I have a few docker containers that I start and stop with docker-compose up / down. Inside the docker-compose.yml I have defined a volume for each container. To what I understood, these should appear as a named volume under var/lib/docker/volumes but all I am seeing is a bunchof cryptic directories that also increase in count everytime I restart containers.
Everytime I restart my containers, the database is empty again when I thought I am using volumes to avoid it beeing like this. I want to persist the data.
Am I doing something wrong I am missing?
version: "3"
services:
nftapi:
env_file:
- .env
build:
context: .
ports:
- '5000:5000'
depends_on:
- postgres
networks:
- postgres
postgres:
container_name: postgres
image: postgres:latest
ports:
- "5432:5432"
volumes:
- /data/postgres:/data/postgres
env_file:
- docker.env
networks:
- postgres
pgadmin:
links:
- postgres:postgres
container_name: pgadmin
image: dpage/pgadmin4
ports:
- "8080:80"
volumes:
- /data/pgadmin:/root/.pgadmin
env_file:
- docker.env
networks:
- postgres
networks:
postgres:
driver: bridge
Screen of volume dirs
2
Answers
You are not making use of named volumes. When the left side of your volume configuration refers to an existing host path, this is a "bind mount", not a named volume. When you start your compose stack, this configuration:
Means that the host path
/data/postgres
is mounted on/data/postgres
in the container.A named volume configuration would look like this:
You can read more about volumes in the documentation. The docker-compose syntax is in the syntax reference.
The other volumes you see in the output of e.g.
docker volumes
probably correspond to anonymous volumes configured in the images you’re using. For example, the pgadmin image has a volume mounted at/var/lib/pgadmin
:The Docker Hub
postgres
image keeps its data in/var/lib/postgresql/data
(see "Where to store data" in the extended description). You need to change the bind mount so that’s the second directory named there.This is why you’re not seeing data persisted in the host directory; it’s getting mounted on the wrong path.
Meanwhile, the image’s
Dockerfile
contains aVOLUME
declaration for that directory. That causes Docker to create an anonymous volume for that directory if nothing else is mounted there. Thedocker-compose down
documentation notes:So that’s why you’re also not seeing database data preserved across restarts either; fixing the mount path will address this.
(In an earlier question you were asking where the extra volumes came from, and it’s the anonymous volumes created by the Dockerfile
VOLUME
. @larsks’s answer has a good discussion on the different between named volumes and bind mounts; the anonymous volumes they refer to at the end of their answer are the sameVOLUME
mechanic.)