1

I have a docker-compose file to build a web server with django and a postgres database. It basically looks like that :

version: '3'

services:
  server:
    build:
      context: .
      dockerfile: ./docker/server/Dockerfile
    image: backend
    volumes:
      - ./api:/app
    ports:
      - 8000:8000
    depends_on:
      - postgres
      - redis
    environment:
      - PYTHONUNBUFFERED=1

  postgres:
    image: kartoza/postgis:11.0-2.5
    volumes:
      - pg_data:/var/lib/postgresql/data:rw
    environment:
      POSTGRES_DB: "gis,backend"
      POSTGRES_PORT: "5432"
      POSTGRES_USER: "user"
      POSTGRES_PASS: "pass"
      POSTGRES_MULTIPLE_EXTENSIONS: "postgis,postgis_topology"
    ports:
      - 5432:5432

  redis:
    image: "redis:alpine"

volumes:
  pg_data:

I'm using a volume to make my data persistent I managed to run my containers and add data to the database. A volume has successfully been created : docker volume ls

DRIVER              VOLUME NAME
local               server_pg_data

But this volume is empty as the output of docker system df -v shows:

Local Volumes space usage:

VOLUME NAME                                                        LINKS               SIZE
server_pg_data                                                     1                   0B

Also, if I want or need to build the containers once again using docker-compose down and docker-compose up, data has been purged from my database. Yet, I thought that volumes were used to make data persistent on disk…

I must be missing something in the way I'm using docker and volumes but I don't get what:

  • why does my volume appears empty while there is some data in my postgres container ?
  • why does my volume does not persist after doing docker-compose down ?

This thread (How to persist data in a dockerized postgres database using volumes) looked similar but the solution does not seem to apply.

1 Answer 1

5

The kartoza/postgis image isn't configured the same way as the standard postgres image. Its documentation notes (under "Cluster Initializations"):

By default, DATADIR will point to /var/lib/postgresql/{major-version}. You can instead mount the parent location like this: -v data-volume:/var/lib/postgresql

If you look at the Dockerfile in GitHub, you will also see that parent directory named as a VOLUME, which has some interesting semantics here.

With the setting you show, the actual data will be stored in /var/lib/postgresql/11.0; you're mounting the named volume on a different directory, /var/lib/postgresql/data, which is why it stays empty. Changing the volume mount to just /var/lib/postgresql should address this:

volumes:
  - pg_data:/var/lib/postgresql:rw # not .../data
Sign up to request clarification or add additional context in comments.

2 Comments

in the documentation, that part quoted is followed by: -v data-volume:/opt/postgres/data \ -e DATADIR:/opt/postgres/data \ -> that is confusing, maybe DATADIR env isn't actually being checked for where to store data?
Thanks, just mounting /var/lib/postgresql on a persistent volume did the job, my dockerised postgresql+postgis is persistent now.

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.