2

I am running one application which run python script and read the data and write to file. I am using docker to that.

Dockerfile:

FROM python:3
WORKDIR /usr/src/app
COPY . .
CMD ["test.py"]
ENTRYPOINT ["python3"]

Python code:

#!/usr/bin/env python3
import argparse
import sys

def get_arguments():
    parser = argparse.ArgumentParser()
    parser.add_argument('-t', '--input_file', required=True)
    parser.add_argument('-o', '--output_file', required=True)
    return parser

def main(argv):
    parser = get_arguments()
    args = parser.parse_args()

    with open(args.output_file, 'w') as o:
         o.write("hello world" + "\n")

if __name__ == "__main__":
    main(sys.argv[1:])

I am generating image using this command:

docker build -t user/hello:1.0.0 .

% docker images

REPOSITORY                  TAG       IMAGE ID       CREATED          SIZE
user/hello                  1.0.0     055851132d95   12 minutes ago   885MB

But i can't see anything when i run

%docker ps

CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES

Looks like container to exited state.

I ran the container using following command.

docker run -it user/hello:1.0.0 test.py -t data/test_input.txt -o data/test_out.txt

But when i enter into the container checking the test_out.txt using

docker exec -it user/hello:1.0.0 /bin/sh

Error: No such container: user/hello:1.0.0

how can i check my test_out.txt?

Manish
  • 3,341
  • 15
  • 52
  • 87
  • 1
    It might be easier to run this script directly on the host. You could in principle bind-mount a directory to hold the input and output data, but since a container has an isolated filesystem, it will be much harder than just using the host's Python. – David Maze Mar 28 '21 at 01:08
  • 1
    Does the setup in [Docker input file and save in output](https://stackoverflow.com/questions/63400807/docker-input-file-and-save-in-output) work for you? You should not need `docker exec` in this case (and can't use it on a stopped/completed container). – David Maze Mar 28 '21 at 01:14

3 Answers3

2

NOTE: In chat, OP clarified that they want to use docker run in a WDL to run the Python script in Docker and extract the file onto the host. As David Maze pointed out, this answer provides a great solution to this by using a bind mount.


My apologies for adding yet another answer to this question but I thought I could clarify a few things. As you mentioned in a comment, your container stops right after executing your .py script. This is why you don't see anything after running docker ps.

One way to solve this is to reverse the order of your commands to keep your container running. First run docker run ... /bin/sh and then run the docker exec ... test.py ... command. The only alternative I can think of besides keeping your container running is to use a bind mount to write to the output file in order to get your file on the host machine. While you could also use docker cp, this command also requires that the container is still running as far as I can tell from the docs.

As other answers have noted, when you run your Docker image, it creates a container with a unique container ID. Unless you manually specify the container name, it will be different than the image name. You can specify a container name with --name CONTAINER_NAME.

I'd recommend doing the following:

  1. Replace the ENTRYPOINT with CMD in your Dockerfile so you can optionally overwrite the start command to keep the container running. Details about CMD and ENTRYPOINT and their differences here.
FROM python:3
WORKDIR /usr/src/app
COPY . .
CMD ["python3"]
  1. Run a shell first to keep your container running. After running this command to open a shell, you can either execute your python script here or go to step 3.
docker run -it --name CONTAINER_NAME user/hello:1.0.0 /bin/sh
  1. Execute a command in your container with by specifying its name when using docker exec.
docker exec -it CONTAINER_NAME python3 test.py -t data/test_input.txt -o data/test_out.txt

I swapped the order of the commands you executed so you can have a long-running shell to inspect the output file and use exec to execute your script. Of course, this doesn't have the nice CLI feel your original command does but will help you check the output file.

cam
  • 4,409
  • 2
  • 24
  • 34
  • Thanks! i did that but i got message Error response from daemon: Container 3e9a90c85e3ed1eda07ddf952e7147e37d71e6e075e52ab549ef2634b32e11b3 is not running. Everytime container gets stopped then what can i do? – Manish Mar 28 '21 at 00:56
  • Hi! Sorry, did you try running the `docker run ... /bin/sh` command I posted? I forgot to mention you may need to replace the `ENTRYPOINT python3` in your Dockerfile with `CMD python3` since that command can be replaced by your `run` arguments. Either way, I'd suggest keeping your container running with a shell open and then run the `docker exec` command to run your python script. – cam Mar 28 '21 at 00:59
  • you mean i should remove Entrypoint and just keep CMD ["python3", "test.py"]? – Manish Mar 28 '21 at 01:03
  • In order to keep your container running, you need to have it "do" something, i.e. run `/bin/sh` shell. The way your Dockerfile is written, it will only execute the python script or append any `run` arguments to `python3` since you used `ENTRYPOINT`. I'd recommend temporarily removing the `ENTRYPOINT` and `CMD` from the Dockerfile so you can run your python script in a shell with `/bin/sh` or with `docker exec`. – cam Mar 28 '21 at 01:06
  • should i use only CMD ["python3", "test.py"]? I am bit confused so asking again. – Manish Mar 28 '21 at 01:09
  • Sorry, I'm not being too clear. I'd recommend removing it entirely and running the commands I posted in my answer. – cam Mar 28 '21 at 01:11
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/230459/discussion-between-manish-and-tentative). – Manish Mar 28 '21 at 01:16
1

docker exec takes the name of a running container, but you passed it user/hello:1.0.0, the name of an image. Pass it the name of a container instead and it will work.

  • I tried using image name docker exec -t confident_cray sh and getting following error. Error response from daemon: Container c4209f54d9d441f4292510e35c3bf91b21d61dff23bc78c471464431aac63a11 is not running. As i noticed container gets exited immediately and in that case i will never be able to usign exec command. – Manish Mar 28 '21 at 00:11
  • `docker exec` operates on **running** containers. Do you just want the file out of your stopped one? If so, just `docker cp` it instead. – Joseph Sible-Reinstate Monica Mar 28 '21 at 00:12
0

Have you tried changing your entrypoint and putting also the path to your .py script? This could be one of the problems.

Also check the command you are passing as input to docker exec, it takes the container name as input not the image name.

However given that this could be the problem, I suggest you to use another Docker image as baseline for your container. If u want to access/manage your files inside the container maybe try using images such as ubuntu or centos (or any you feel more familiar to), then if u need to optimize/port to production you can always change the image and set it to something u think it’s more suitable, but for testing one that has an easy access to the CLI is preferable (in my opinion).