0

I'm new to Docker and trying to understand how to use bind mounts with Python scripts. I'm using a Mac running Catalina (10.15.7). I have a Python script that I normally start with a local config.ini file containing settings that control the script. I'd like to run the Python script in a Docker container but have it access the config file from my local machine.

My local directory contains the Dockerfile, requirements.txt file , config.ini file, and a subdirectory (src) with my python files. The Dockerfile used to build the image is as follows:

FROM python:3.7

WORKDIR /app

COPY requirements.txt .

RUN pip install -r requirements.txt

COPY src/ .

CMD ["python", "./main.py" ]

After I build the image, I run it with the following command:

docker container run -v $(pwd):/app image_name

which results in the error can't open file './main.py'

Suggestions?

  • 1
    Docker bind mounts will overwrite the contents of the destination directory on the container. See [this answer](https://stackoverflow.com/a/47673246/4676641) for more info. So it seems like the command `python /app/main.py` will fail when the container starts up. Why do you need to mount `$(pwd)` to `/app`? Do you have additional config you need that's not already in the container? – cam Jan 04 '21 at 01:22
  • That's what I suspected was happening. – Daniel Simon Jan 04 '21 at 01:26
  • Yes, I was thinking it'd be useful to run the script with different parameters without needing to rebuild the image. – Daniel Simon Jan 04 '21 at 01:27
  • One possible solution would be to mount the specific file(s) you want. This might be tedious though. Something like this: `docker container run -v $(pwd)/config.ini:/app/config.ini image_name` – cam Jan 04 '21 at 01:53
  • 1
    Thanks. Yes, that did work. I suppose I could also direct the script to look in a folder other than /app for the config.ini file and create a mount there instead. I've replaced the CMD function with ENTRYPOINT in the Dockerfile so I can pass an extra argument telling the container where to look for this file. Haven't quite got it all working yet though. – Daniel Simon Jan 04 '21 at 02:17

1 Answers1

0

Your problem is that Docker bind mounts will overwrite the contents of the destination directory on the container. See this answer for more info. It seems like the command python /app/main.py will fail when the container starts up.

Below, I'll just summarize and expand on what I commented.


Mount Specific File(s)

One possibly quick fix may be to mount a specific file to /app for your program to read.

docker run -v $(pwd)/config.ini:/app/config.ini image_name

Run With Environment Variables

You mentioned creating another mount point to read/mount config from that also may work.

Another option to set things at runtime besides using program arguments from your ENTRYPOINT command is using environment variables. More info in the docs

docker run -e "CONFIG_PATH=/app/config/config.ini" image_name

Set Environment Variables in Dockerfile

Of course, you could hard-code some environment variable into your image with ENV:

FROM python:3.7

ENV CONFIG_PATH=/app/config/config.ini

Or set it as a build-arg:

ARG CONFIG_PATH
ENV CONFIG_PATH=${CONFIG_PATH}

And build like so:

docker build --build-arg CONFIG_PATH=/app/config/config.ini .

You may have considered these already or have a better solution, please let me know if I can clarify any of these suggestions. Thanks!

cam
  • 4,409
  • 2
  • 24
  • 34