Docker compose reusing volumes

2019-04-26 20:23发布

问题:

I'm trying to create a new Docker image that no longer uses volumes from a running container that does use images. The volumes were created using docker-compose file, not Dockerfile. The problem is, when I launch a new container via new docker-compose.yml file it still has the volumes mapped. I still need to keep these volumes and the original containers/images that use them. Also, if possible I would like to continue to use the same docker image, just add a new version, or :latest. Here's the steps I used:

New version of an existing image:

docker commit <image id> existingImage:new-version

Create a new image from current running container:

docker commit <Image ID> newimage

Create new docker-compose.yml with no volumes defined and run docker-compose with a different project name

docker-compose -p <new project name> 

Running without docker-compose, just use docker run:

 docker run -d -p 8093:80 <img>:<version>

Any time I run any combination of these the volumes are still mapped from the original image. So my question is, how to I create a container from an image that once had mapped volumes but I no longer want to use the volumes?

Edit: Additional things I've tried:

  • Stop container, remove container, restart docker, run docker compose again. No luck.

Edit 2: Decided to start over on the image. Using a base image, launched a container with an updated docker compose file that uses the now unrelated image. Run docker-compose -f up -d -> STILL has these same volumes mapped even though the image does not (and never has) any volumes mapped, and the current docker-compose.yml file does not map files. It looks like docker-compose caches what volumes are mapped for projects.

After searching for caching options in docker-compose, I came across this article: How to get docker-compose to always re-create containers from fresh images? which seems to solve the problem of caching images but not containers caching volumes

回答1:

According to another SO post what I am trying to do is not possible. For future reference, one cannot attach volumes to an image, and then later decide to remove them. A new image must be created without the volumes instead. Reference: How to remove configure volumes in docker images



回答2:

To remove volumes along with the containers used by docker-compose, use docker-compose down -v.

To start containers with docker-compose, leave your existing volumes intact, but not use those volumes, you should change your project name. You can use docker-compose -p new_project_name up -d for that.


Edit: here's an example showing how docker-compose does not reuse named volumes between different projects, but it does reuse and persist the volume unless you do a down -v:

$ docker-compose -p proj1 -f docker-compose.vol-named.yml up -d
Creating network "proj1_default" with the default driver
Creating volume "proj1_data" with default driver
Creating proj1_test_1 ...
Creating proj1_test_1 ... done

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
71f2eb516f71        busybox             "tail -f /dev/null"      5 seconds ago       Up 2 seconds                                 proj1_test_1

$ docker exec -it 71f /bin/sh
/ # ls /data
/ # echo "Hello proj1" >/data/data.txt
/ # exit

Volume is now populated, lets stop and start a new container to show it persist:

$ docker-compose -p proj1 -f docker-compose.vol-named.yml down
Stopping proj1_test_1 ... done
Removing proj1_test_1 ... done
Removing network proj1_default

$ docker-compose -p proj1 -f docker-compose.vol-named.yml up -d
Creating network "proj1_default" with the default driver
Creating proj1_test_1 ...
Creating proj1_test_1 ... done

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
311900fd3d27        busybox             "tail -f /dev/null"      5 seconds ago       Up 3 seconds                                 proj1_test_1

$ docker exec -it 311 /bin/sh
/ # cat /data/data.txt
Hello proj1
/ # exit

There's the expected persistent volume, lets run a different project at the same time to show the volume would be independent:

$ docker-compose -p proj2 -f docker-compose.vol-named.yml up -d
Creating network "proj2_default" with the default driver
Creating volume "proj2_data" with default driver
Creating proj2_test_1 ...
Creating proj2_test_1 ... done

$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
d39e6fc51436        busybox             "tail -f /dev/null"      4 seconds ago       Up 2 seconds                                 proj2_test_1
311900fd3d27        busybox             "tail -f /dev/null"      33 seconds ago      Up 32 seconds                                proj1_test_1

$ docker exec -it d39 /bin/sh
/ # ls -al /data
total 8
drwxr-xr-x    2 root     root          4096 Nov  6 19:56 .
drwxr-xr-x    1 root     root          4096 Nov  6 19:56 ..
/ # exit

The volume is completely empty in the new project. Let's cleanup.

$ docker-compose -p proj2 -f docker-compose.vol-named.yml down -v
Stopping proj2_test_1 ...
Stopping proj2_test_1 ... done
Removing proj2_test_1 ... done
Removing network proj2_default
Removing volume proj2_data

$ docker volume ls
DRIVER              VOLUME NAME
local               proj1_data

Note the volume is there in proj1 from before.

$ docker-compose -p proj1 -f docker-compose.vol-named.yml down -v
Stopping proj1_test_1 ... done
Removing proj1_test_1 ... done
Removing network proj1_default
Removing volume proj1_data

$ docker volume ls
DRIVER              VOLUME NAME

But doing a down -v deletes the volume.