I am running Django with PostgreSQL in a docker-compose setup for development. Each time I restart the application container, the database is empty, even though I do neither restart the DBMS container nor do I drop the DBMS's data volume. It seems that Django is dropping all tables upon restart. Why?
My setup closely follows the description here. That is, my compose file looks as follows (simplified):
version: '3.8'
services:
db:
image: postgres
environment:
- POSTGRES_DB=db_dev
- POSTGRES_USER=dev
- POSTGRES_PASSWORD=postgres
volumes:
- type: volume
source: app-data
target: /var/lib/postgresql/data
app:
build: .
command: python manage.py runserver 0.0.0.0:8888
container_name: app
environment:
- DATABASE_URL
- PYTHONDONTWRITEBYTECODE=1
- PYTHONUNBUFFERED=1
volumes:
# Mount the local source code folder for quick iterations.
# See: https://www.docker.com/blog/containerized-python-development-part-3/
- type: bind
source: .
target: /code
ports:
- target: 8888
published: 8888
depends_on:
- db
env_file:
- ./dev.env
volumes:
app-data:
external: true
The Django application is started by means of an entrypoint.sh
:
#! /bin/sh
if [ "$DATABASE" = "postgresql" ]
then
echo "Waiting for postgres..."
while ! nc -z $SQL_HOST $SQL_PORT; do
sleep 0.1
done
echo "PostgreSQL started"
fi
doMigrate=${DB_MIGRATE:-false}
if [ "$doMigrate" = true ] ;
then
python manage.py flush --no-input
python manage.py migrate
fi
exec "$@"
In the development setup, I set DB_MIGRATE=true
and DEBUG=1
.
The Django
flush
command removes all data from the database, as explained in the documentation.Hence, to solve my problem above, I only need to remove the line
from my
entrypoint.sh
script.Explanation: I thought - incorrectly - that
flush
would commit any pending transactions that might still be open from other applications that might potentially use the DB. This is not the case. Instead,flush
simply removes all data.