1

My first question is: What is a docker volume? Is it an instance of the code? So if I write to a file, the file is written to that volume's version of the file?

Here is my data structure:

static   
---scripts  
---styles  
---templates 

matrices  
--- sampleMatrix.txt    <- this is the file I'm trying desperately to write to     
app.py  
dockerfile  
docker-compose.yml

App.py code:

try:
    matrixFile= open(fileName, "w+")
    matrixFile.write("text: \n")               <- should print test:
    print("wrote to: ",fileName, file=sys.stderr)
    matrixFile.close()

    matrixFile= open(fileName, "w+")
    print("About to read: ",fileName, file=sys.stderr)
    print(matrixFile.read(), file=sys.stderr)   <- prints a newline and nothing else
    print("Read from: ",fileName, file=sys.stderr)
    matrixFile.close()   
except:
    print("cant open file", file=sys.stderr)  <- never prints

With this, I know that flask is FINDING the file but seems not to be writing anything to it. Also no changes to the file locally

dockerfile:

FROM python:3.6.1-alpine
ADD . .
RUN pip install -r requirements.txt
RUN pip install requests
VOLUME [ "/matrices/" ]
CMD ["python","app.py"]

docker-compose.yml

version: '2'

services:
  <containerName>:
    build: . 
    ports: 
      - 82:80
    container_name: <containerName>
    volumes:
      - ~<userName>/Desktop/<folderName>/matrices/:/matrices/

I thought possibly the path of the volume could be wrong but I can't tell how to check. If this was theoretically working correctly, would I see changes to the local file immediately?

davidism
  • 121,510
  • 29
  • 395
  • 339
perryr
  • 89
  • 1
  • 5

1 Answers1

2

A Docker volume is essentially a "directory" you can mount to a container that is only managed and accessed through Docker. You are using a bind mount, that is some directory on your local filesystem managed by the host OS and made accessible to your Docker container. If mounted properly, you will be able to read/write this volume both in your Docker container and on your local filesystem. This picture from the docs helps visualize this:

enter image description here

In your Dockerfile, you've copied your code into your image. When you start your Docker container with a volume, that is mounted to the container and is accessible by your python code in the image. This isn't the only way to run it, for example you could also bind mount your Python code and run the container that way.

If you gave the wrong path in services.<containerName>.volumes, then Docker will try to create matrices if it doesn't exist. It looks like your path isn't right if it starts with ~username.

I'd suggest you double check the volume's path in the docker-compose.

Unix

ls ~<userName>/Desktop/<folderName>/matrices/

# if this fails, it will say so with something like:
# ls: cannot access '<YOUR_PATH>': No such file or directory

Windows Powershell (just in case)

Test-Path ~<userName>/Desktop/<folderName>/matrices/
# this will output False if the path is bad

Once you've verified the path is correct, you should be see whatever the Python code writes to appear in that directory on the host OS.

For more about Docker volumes, see these docs. For more about bind mounts, see these docs.

cam
  • 4,409
  • 2
  • 24
  • 34
  • This is great! At least I feel like I know the issue is the path. I also just confirmed that when I write something in the file locally, running my program overwrites the file locally to be empty. Is the path on the left relative to where the docker command is initiated? – perryr Jan 15 '21 at 23:23
  • 1
    Hope it helps! I'm still trying to verify this is the case, but that the volume paths can be relative to the `docker-compose.yml` file, not necessarily where the command is run. Absolute paths should always work and you can use environment variables to set the path as well. – cam Jan 15 '21 at 23:54
  • How would I make the paths relative to the docker-compose.yml? Also does the right side (I am assuming is the docker side) have any special path I should take. I have seen others do var/lib/docker/ but I can't seem the find a way to view the directory of the docker container – perryr Jan 16 '21 at 00:00
  • 1
    Hmm, well if you're trying to mount a folder in the same directory as the docker-compose file: `./matrices:/matrices`. I suggest at least try an absolute path to the folder you want to mount since that's most reliable: `/Users/username/some/path:/matrices`. But the path on the right side must be absolute (from filesystem's root `/`). This question might help too: https://stackoverflow.com/a/46910980/4676641 – cam Jan 16 '21 at 00:08
  • Thank you for all your help. It seems like: `- ~/Desktop//matrices/:/matrices/` and `- ./matrices:/matrices` are achieving the same thing. They both create a link locally, which removes anything I have already written in the file. But unfortunately, when I write to it with python, nothing shows up. Seems like the local version isn't connected to the volume version, or python is somehow writing to the wrong one. – perryr Jan 16 '21 at 00:49
  • Do you know what `filename` is at runtime in your python program and are you sure it's a path in the container's `/matrices` directory? `matrixFile= open(fileName, "w+")` – cam Jan 16 '21 at 01:03
  • I'm pretty sure for 2 reasons. First is that I print out everything in the `/matrices/` folder using Glob.glob and it gives the name of the file, second is that `open()` is never failing in the try-catch. It reads empty when it starts with info, and it's not writing anything when I write to it. Even when I read right after it doesn't read anything. – perryr Jan 16 '21 at 01:13
  • Sorry for the late reply. What's the output when you run the container and run `docker inspect CONTAINER_NAME`? I wonder if it's not mounting properly for some reason. – cam Jan 23 '21 at 01:14