Search code examples
djangopostgresqldockerdocker-composedocker-volume

Docker not persisting postgres volume [django]


There are many questions that have been asked on here about similar issues that I went through such as this, this, this and this that are very similar but none of the solutions there solve my problem. Please don't close this question.

Problem:

I am running django with nginx and postgres on docker. Secret information is stored in an .env file. My postgres data is not persisting with docker-compose up/start and docker-compose down/stop/restart.

This is my docker-compose file:

version: '3.7'

services:
  web:
    build: ./app
    command: gunicorn umngane_project.wsgi:application --bind 0.0.0.0:8000
    volumes:
      - ./app/:/usr/src/app/
    expose:
      - 8000
    environment:
      - SECRET_KEY=${SECRET}
      - SQL_ENGINE=django.db.backends.postgresql
      - SQL_DATABASE=postgres
      - SQL_USER=${POSTGRESQLUSER}
      - SQL_PASSWORD=${POSTGRESQLPASSWORD}
      - SQL_HOST=db
      - SQL_PORT=5432
      - SU_NAME=${SU_NAME}
      - SU_EMAIL=${SU_EMAIL}
      - SU_PASSWORD=${SU_PASSWORD}
    depends_on:
      - db
  db:
    image: postgres:11.2-alpine
    volumes:
      - postgres_data:/var/lib/postgresql/data/
  nginx:
    build: ./nginx
    volumes:
      - static_volume:/usr/src/app/assets
    ports:
      - 1337:80
    depends_on:
      - web

volumes:
  postgres_data:
    external: true # I tried running without this and the result is the same
  static_volume:

My entrypoint scipt is this:

python manage.py flush --no-input
python manage.py makemigrations
python manage.py migrate
python manage.py createsuperuser --user "${SU_NAME}" --email "${SU_EMAIL}" --password "${SU_PASSWORD}"
python manage.py collectstatic --no-input

exec "$@"

where createsuperuser is a custom module that creates a superuser in the application.

This setup is not persisting the information in postgres_data.

Additional information:

Before doing anything, I check to see that there is no volume named postgres_data using docker volume ls and get just that.

At which point I run docker-compose up -d/docker-compose up -d --build and everything works out fine with no errors.

I run docker inspect postgres_data and it shows "CreatedAt": "X1"

I am able to login as the superuser. I proceed to create admin users, logout as the superuser and then login as any of the admin users with no problem. I run docker exec -it postgres_data psql -U <postgres_user> to make sure the admin users are in the database and find just that.

At which point I proceed to run docker-compose down/docker-compose stop with no problem. I run docker volume ls and it shows that postgres_data is still there.

I run docker inspect postgres_data and it shows "CreatedAt": "X2"

To test that everything works as expected I run docker-compose up -d/docker-compose up -d --build/docker-compose start/docker-compose restart.

I run docker inspect postgres_data and it shows "CreatedAt": "X3"

At which point I proceed to try and login as an admin user and am not able to. I run docker exec -it postgres_data psql -U <postgres_user> again but this time only see the superuser, no admin users.

(Explanation: I am here using the forward slash to show all the different things I tried on different attempts. I tried every combination of commands shown here.)


Solution

  • The issue is you run "flush" in your entrypoint script which clears the database. The entrypoint will run whenever you boot or recreate the container.