Why docker-compose down deletes my volume? how to define volume as external?

I use docker in ubuntu 16.04 LTS: Docker version 18.06.1-ce, build e68fc7a

in docker compose down | Docker Docs it stated that
docker-compose down by default doesn’t remove volumes.

mongo:
image: mongo
restart: always
networks:
- mynetwork
environment:
MONGO_INITDB_ROOT_USERNAME: user
MONGO_INITDB_ROOT_PASSWORD: pass
volumes:
- ./mongodata:/db/data

when I run docker-compose down without -v or --volumes, why my data is lost? does docker delete my volume?

it’s already on this thread: Docker Volume missing after docker-compose down without -v flag too, but doesn’t receive any answer yet.

and how to define the volume as external ?

The documentation is absolute unclear, because the “by default” block contradicts with the sentence above and under when it commes to volumes. True is that everything that was created with up gets removed/deleted on down.

services, networks and named volumes declared in a compose.yml are bound to the lifecylce of docker-compose.

You need to create your volume from the cli (docker volume create ....), and declare it in your compose.yml as external.

2 Likes

The documentation is absolute unclear, because the “by default” block contradicts with the sentence above and under when it commes to volumes. True is that everything that was created with up gets removed/deleted on down.

this makes me confused too.

I just about to update the thread. I now understand that I can make the volume external by adding external: true

  ...
  volumes:
    - mongo_data:/db/data
volumes: 
  mongo_data:
    external: true

then I create the volume using docker volume create --name=mongo_data

but when I’m using docker-compose down again, the data seems doesn’t persist. the volume is still there when I list them using docker volume ls but when re-running docker-compose up the data is gone.

but when I just stopping the container docker-compose stop and re-run the service, the data still there.

could it be mongo problem? not docker?
should I add mongo to the title?

1 Like

we use external named volumes in development, qa and prod a lot. Data inside an external volume is not deleted by docker-compose or docker stack rm {stackname}.

We use bind type as source for our named volumes in development and NFS as the source in our qa and prod environments.Both can be done with the included “local” persistance driver.

1 Like

Okay so apparently I misread the mongo documentation: Docker

The -v /my/own/datadir:/data/db part of the command mounts the /my/own/datadir directory from the underlying host system as /data/db inside the container, where MongoDB by default will write its data files.

it’s /data/db not /db/data like I write before. Therefore, external volume indeed work. Thank you!

1 Like

I’m also facing the same issue, can anyone help please?
my docker-compose.yaml file looks like this: CodePile | Easily Share Piles of Code

version: '3.7'
services:
  app:
    container_name: bsf-quiz-app
    image: sapkotasuren/bsf-quiz
    ports:
      - "443:8443"
    depends_on:
      - postgresqldb
  postgresqldb:
    image: postgres:latest
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    environment:
      - POSTGRES_PASSWORD=password
      - POSTGRES_USER=postgres
      - POSTGRES_DB=bsfQuiz
      
volumes:
  pgdata:

Does anyone found the solution or have/had the same issue??
I’ve already tried to create the named volume seprately and adding the external value etc in composer file, it doesn’t work for me.

I had the same problem, a colleague helped me, I don’t know how this is solved

@zenaku Could you please ask your colleague to have a look on this? please.

2 Likes

Based on the documentation here, the down will remove volumes unless those volume are external

By default, the only things removed are:

* Containers for services defined in the Compose file
* Networks defined in the networks section of the Compose file
* The default network, if one is used

Networks and volumes defined as external are never removed.

However, you want to use the stop and start commands instead. The stop command doesn’t erase volumes or networks and you don’t need to specify them as externals in your docker-compose.yml file.

Volumes are deleted only if you use -v or --volumes arguments. I think this was always the case at least since I know Docker I don’t know how many years know.

Anonymous volumes are not deleted either by default but every time you create the containers using docker-compose up the container gets a new anonymous volume keeping the old (but not using) at the same time.

When you change something in the service definition and run docker-compose up -d again, your anonymous volumes will not be recreated unless you also use --renew-anon-volumes like docker-compose up -d --renew-anon-volumes

You want to run docker-compose up from root dir only one time if you want to keep your data. After that, those services are existing for docker. That’s why you have to use docker-compose start <service>. If you want to do a fresh start then do docker-compose up again. But docker-compose start/stop is going to reuse the network and volumes for those same services. That is my understanding after reading the docs.

docker-compose up and docker-compose down should work any time without breaking your application unless the configuration is wrong. You are right of course, you can use start and stop if you wish but sometimes you do want to delete everything and start a clean environment. For example imagine an extreme situation where you have a hundred docker compose projects for small tasks but you don’t need them all the time and don’t want to have one hundred docker networks with one hundred reserved bridges and IP ranges. Or you want to temporary delete project A to run project B using the same domain or port forward.

It is your choice but the point is the compose projects are meant to be deletable.

I’m facing same issue because wrong path…
you must mount to /data/db not /db/data

    ...
    volumes:
        - db:/data/db

volumes:
- db: {}

it sould be work