SyntaxStudy
Sign Up
Docker Persisting Database Data with Volumes
Docker Beginner 1 min read

Persisting Database Data with Volumes

Databases are the canonical use case for Docker volumes. Without a volume, every docker rm on a database container destroys all data permanently. Mounting a named volume at the database's data directory persists the data independently of the container lifecycle. Database containers are initialised on first start from a clean volume — subsequent starts reuse existing data. This means environment variables like POSTGRES_PASSWORD are only effective on the first run. If you need to re-initialise, delete the volume explicitly with docker volume rm before starting a new container. For backup, the safest approach is to use the database's own dump tool (pg_dump, mysqldump) rather than copying raw data files. Run the dump tool inside the running container with docker exec and redirect output to a file on the host. This produces a portable, consistent backup regardless of the database engine's internal format.
Example
# PostgreSQL with persistent data
docker volume create pgdata

docker run -d \
  --name postgres \
  --restart unless-stopped \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD=strongpassword \
  -e POSTGRES_DB=appdb \
  -v pgdata:/var/lib/postgresql/data \
  -p 5432:5432 \
  postgres:16-alpine

# Stop, remove, and recreate — data persists via the volume
docker stop postgres && docker rm postgres
docker run -d --name postgres \
  -v pgdata:/var/lib/postgresql/data \
  -e POSTGRES_USER=appuser \
  -e POSTGRES_PASSWORD=strongpassword \
  postgres:16-alpine

# Backup with pg_dump
docker exec postgres pg_dump -U appuser appdb \
  > backup-$(date +%Y%m%d).sql

# Restore
docker exec -i postgres psql -U appuser appdb < backup.sql

# MySQL equivalent
docker run -d \
  --name mysql \
  -e MYSQL_ROOT_PASSWORD=secret \
  -e MYSQL_DATABASE=appdb \
  -v mysqldata:/var/lib/mysql \
  mysql:8.0