1

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. Commented Feb 7, 2022 at 21:38
  • @David Maze, yes, that was exactly the issue, thanks! I even manually checked the path before, by using docker exec -it postgres /bin/bash, but I didn't copy-pasted the exact path -- that was my error. Then I would have spotted/solved the error. Now everything works and the data are persisted after docker-compose down and docker-compose up again. Commented Feb 8, 2022 at 10:01

2 Answers 2

2

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)

Sign up to request clarification or add additional context in comments.

1 Comment

Hans Kilian, thanks for the advice. The actual issue for the double volume was a typo, noticed by @David Maze in his comment under my question. Nevertheless, I also used your suggestion, so thanks again.
0

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

3 Comments

alexanderdavide, thank you for the clear example and additional link to the documentation. I wanted to have everything managed by a single docker-compose file, so the tip about creating external volumes is useful, but not for me, in this case. The actual reason for two volumes being created was found by @David Maze (see his comment under my question). I am going to mark @Hans Kilman 's answer as "the solution", because he was first, and he provided the exact line I needed (although also with the aforementioned typo). I would have upvoted you answer as well, but I don't have enough reputation
@MikolajBuchwald No problem! I hope my answer still added to your understanding.
Yes, it did, thank you!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.