Docker-compose and volume persistence

Hello,

I’m just starting out with docker and seem to have misunderstood something fundamental about building images. I want to use docker-compose to add a volume to an image. If I give it a CMD to list the volume in my Dockerfile I see that the volume - defined in my docker-compose.yml - has been mounted and the contents are there.

My issue is that I am using docker-compose up to trigger the build and the image just exits when the build is complete. If I then run the image via docker exec I no longer see the volume.

my Dockerfile:

FROM centos:latest
CMD ["/bin/bash"]

My docker-compose.yml:

version: '2'
services:
   muse:
       build: .
       volumes:
           - ../muse/muse_root/:/usr/local/bin/muse_root
       command: ls /usr/local/bin

When I run docker-compose up -d I see this:

Starting docker_muse_1
Attaching to docker_muse_1
muse_1  | muse_root
docker_muse_1 exited with code 0

So I see that muse_root is mounted under /usr/local/bin. (I was expecting the image to keep on running in the background because of the -d but it exits and I don’t know why).

Having built the image I see it listed:

docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker_muse         latest              cb1a6859f6e4        14 seconds ago      196.5 MB

When I log into the image though the volume is no longer mounted:

docker run -it docker_muse /bin/bash
[root@5150e5587dd5 /]# ls -l /usr/local/bin/
total 0

From what I’ve been reading I need to use the docker-compose.yml file to define the volume I want to mount. How do I get docker-compose up to bring up the image and keep it running with the volume in place?

Images don’t have volumes. You can attach a volume to a specific running container from an image, but it’s not persistent with the image. So, when you eventually run

docker run -it docker_muse /bin/bash
[root@5150e5587dd5 /]# ls -l /usr/local/bin/
total 0

since you didn’t give a -v option to docker run, no volumes are attached to the container.

If you want the contents of that directory to be in the image every time you run it, COPY it into the image in your Dockerfile. (Yes, that means you need to docker build or docker-compose build every time the content changes, but this is pretty quick.)

docker run -d (and its docker-compose equivalent) means that Docker will return to you immediately, instead of waiting for the command to complete. Whenever the command completes, the container exits. ls commands usually don’t take especially long to run, so you’ll probably get a shell prompt back immediately whether or not you use -d.

1 Like

Ah thanks very much. That’s given me some context :slight_smile: