84

A very simple Python program. Suppose the current directory is /PYTHON. I want to pass file.txt as an argument to the Python script boot.py. Here is my Dockerfile:

FROM python
COPY boot.py ./
COPY file.txt ./
RUN pip install numpy
CMD ["python", "boot.py", "file.txt"]

Then I build the Docker container with:

docker build -t boot/latest .

Then run the container

docker run -t boot:latest python boot.py file.txt

I got the correct results.

But if I copy another file, file1.txt, to the current directory (from a different directory (not /PYTHON)), then I run the container again:

docker run -t boot:latest python boot.py file1.txt

I got the following error:

FileNotFoundError: [Errno 2] No such file or directory: 'file1.txt'

so the error is due to fact that file1.txt is not in the container, but if I share this container with a friend and the friend wants to pass a very different file as argument, how do I write the Dockerfile so anybody with my container can pass very different files as argument without errors?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mpp
  • 959
  • 1
  • 6
  • 4
  • You need to change your Dockerfile according the file you are passing... if is working with file.txt and not working with file1.txt , look inside the Dockerfile, is there file1.txt there? – OscarAkaElvis Dec 12 '16 at 00:14
  • The file1.txt is not in Dockerfile because I don't know what files will be passed as argument in advance. – mpp Dec 12 '16 at 00:20
  • Filed https://github.com/docker/cli/issues/3046 to simplify passing files to 'docker run' – rouble Apr 09 '21 at 21:47

4 Answers4

108

It won't work that way. Like you said, file1.txt is not in the container.

The workaround is to use Docker volumes to inject files from your host machine to the container when running it.

Something like this:

docker run -v /local/path/to/file1.txt:/container/path/to/file1.txt -t boot:latest python boot.py /container/path/to/file1.txt

Then /local/path/to/file1.txt would be the path on your host machine which will override /container/path/to/file1.txt on the container.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Hakro
  • 2,625
  • 1
  • 12
  • 23
  • 2
    Make sure that the local path is an absolute path; you cannot specify a relative path like `./myfile.txt1`. – alanc10n Jun 02 '22 at 17:36
21

You may also make your script read from STDIN and then pass data to docker using cat. Have a look at how to get docker container to read from stdin?

The trick is to keep STDIN open even if not attached with --interactive or -i (alias) option for Docker.

Something like:

cat /path/to/file | docker run -i --rm boot python boot.py

Or:

docker run -i --rm boot python booty.py < /path/to/file

EOF is the end of the input.

Nick Roz
  • 3,918
  • 2
  • 36
  • 57
6

If I understand the question correctly, you are acknowledging that the file isn't in the container, and you are asking how to best share you container with the world, allowing people to add their own content into it.

You have a couple of options, either use Docker volumes, which allows your friends (and other interested parties) to mount local volumes inside your Docker containers. That is, you can overlay a folder on your local filesystem onto a folder inside the container (this is generally quite nifty when you are developing locally as well).

Or, again, depending on the purpose of your container, somebody could extend your image. For example, a Dockerfile like

FROM yourdockerimage:latest
COPY file1.txt ./
CMD ["python", "boot.py", "file1.txt"]

Choose whichever option suits your project the best.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
JustDanyul
  • 13,813
  • 7
  • 53
  • 71
0

You could change your Dockerfile to:

FROM python
COPY boot.py ./
COPY file.txt ./
RUN pip install numpy
ENTRYPOINT ["python", "boot.py"]

And then run it to read from STDIN:

docker run -i boot:latest -<file1.txt
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gdzcorp
  • 73
  • 6