0
votes

I am trying to create a persistent volume storage for a postgres docker container. Because I will have some other services within this docker environment, I am using docker-compose to start the container.

The contents of my docker-compose.yml file are:

version: "3.8"

services:
  db:
    image: postgres:12.3
    volumes:
      - ./postgres-data:/var/lib/posgresql/data
    environment:
      - POSTGRES_NAME=postgres
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=postgres

volumes:
  postgres-data:

I run the command:

docker-compose up

Now, based on the documentation, and this example, I expect to have one persistent volume created, with its name including postgres-data (e.g., postgres-volume_postgres-data).

Instead, two volumes are created:

docker volume ls

Output:

DRIVER    VOLUME NAME
local     a53a5b161f0fefca840e2f0cd2a97ad019864dea23c7f23f07c94e6be7ace601
local     postgres-volume_postgres-data

Inspecting the volumes:

docker volume inspect a53a5b161f0fefca840e2f0cd2a97ad019864dea23c7f23f07c94e6be7ace601

Output:

[
    {
        "CreatedAt": "2022-02-07T19:12:04Z",
        "Driver": "local",
        "Labels": null,
        "Mountpoint": "/var/lib/docker/volumes/a53a5b161f0fefca840e2f0cd2a97ad019864dea23c7f23f07c94e6be7ace601/_data",
        "Name": "a53a5b161f0fefca840e2f0cd2a97ad019864dea23c7f23f07c94e6be7ace601",
        "Options": null,
        "Scope": "local"
    }
]

Inspecting the second volume:

docker volume inspect postgres-volume_postgres-data

Output:

[
    {
        "CreatedAt": "2022-02-07T19:12:02Z",
        "Driver": "local",
        "Labels": {
            "com.docker.compose.project": "postgres-volume",
            "com.docker.compose.version": "1.29.2",
            "com.docker.compose.volume": "postgres-data"
        },
        "Mountpoint": "/var/lib/docker/volumes/postgres-volume_postgres-data/_data",
        "Name": "postgres-volume_postgres-data",
        "Options": null,
        "Scope": "local"
    }
]

Of these two volumes only the a53a5b161f0fefca840e2f0cd2a97ad019864dea23c7f23f07c94e6be7ace601 is active and all the data seem to be stored within this volume.

The effect is that when I use docker-compose down, all data saved to the database when the container was running are lost, i.e., the data are not persisted, and they are not available after running the docker-compose up again.

What I am doing wrong?

(I am using macOS Big Sur, v.11.4.)

Docker & docker-compose versions:

➜  ~ docker --version
Docker version 20.10.7, build f0df350

➜  ~ docker-compose version
docker-compose version 1.29.2, build 5becea4c
docker-py version: 5.0.0
CPython version: 3.9.0
OpenSSL version: OpenSSL 1.1.1h  22 Sep 2020
2
The container path /var/lib/postgresql/data needs a t in it. That could cause the anonymous volume you're seeing.David Maze

2 Answers

0
votes

What you're doing is called a 'bind mount' where a directory on the host is mapped to a directory in the container.

The syntax is slightly different if you want to create a volume. Do this instead

- postgres-data:/var/lib/posgresql/data

(i.e. no path information before the volume name)

0
votes

Currently, you are mounting a host path. Its contents are lost when removing containers. What you want to have is a named volume. After the initial creation of a named volume, you can reuse it across services and it will be persisted on following invocations.

In docker-compose, the following would create the named volume myapp and use it in the service called 'frontend'. The docs and compose reference explain this well.

version: "3.9"
services:
  frontend:
    image: node:lts
    volumes:
      - myapp:/home/node/app
volumes:
  myapp:

Actually, you also can create volumes externally with docker volume create myapp and then reference them inside docker-compose setups adding external: true.

volumes:
  myapp:
    external: true