Running Databases in Docker
Docker is perfect for running databases in development β you get isolated, reproducible database instances without installing anything on your host machine. For production, consider managed database services, but Docker works well for smaller deployments too.
PostgreSQL
# docker-compose.yml
services:
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- postgres-data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin -d myapp"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres-data:
# Connect to PostgreSQL
docker compose exec postgres psql -U admin myapp
# Backup
docker compose exec postgres pg_dump -U admin myapp > backup.sql
# Restore
docker compose exec -T postgres psql -U admin myapp < backup.sql
MongoDB
services:
mongo:
image: mongo:7
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
MONGO_INITDB_DATABASE: myapp
volumes:
- mongo-data:/data/db
- ./mongo-init.js:/docker-entrypoint-initdb.d/init.js
ports:
- "27017:27017"
mongo-express:
image: mongo-express
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: admin
ME_CONFIG_MONGODB_ADMINPASSWORD: secret
ME_CONFIG_MONGODB_URL: mongodb://admin:secret@mongo:27017/
ports:
- "8081:8081"
depends_on:
- mongo
volumes:
mongo-data:
Redis
services:
redis:
image: redis:7-alpine
command: redis-server --appendonly yes --requirepass secret
volumes:
- redis-data:/data
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "-a", "secret", "ping"]
interval: 10s
timeout: 5s
retries: 5
# Redis GUI
redis-commander:
image: rediscommander/redis-commander
environment:
REDIS_HOSTS: local:redis:6379:0:secret
ports:
- "8082:8081"
depends_on:
- redis
volumes:
redis-data:
MySQL
services:
mysql:
image: mysql:8
environment:
MYSQL_ROOT_PASSWORD: rootsecret
MYSQL_DATABASE: myapp
MYSQL_USER: admin
MYSQL_PASSWORD: secret
volumes:
- mysql-data:/var/lib/mysql
- ./init.sql:/docker-entrypoint-initdb.d/init.sql
ports:
- "3306:3306"
command: --default-authentication-plugin=mysql_native_password
volumes:
mysql-data:
Full Stack with Database
# Complete development stack
services:
api:
build: .
ports:
- "4000:4000"
environment:
DATABASE_URL: postgres://admin:secret@postgres:5432/myapp
REDIS_URL: redis://redis:6379
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_started
postgres:
image: postgres:16-alpine
environment:
POSTGRES_USER: admin
POSTGRES_PASSWORD: secret
POSTGRES_DB: myapp
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin"]
interval: 10s
retries: 5
redis:
image: redis:7-alpine
volumes:
- redis-data:/data
# Database admin UI
adminer:
image: adminer
ports:
- "8080:8080"
depends_on:
- postgres
volumes:
pgdata:
redis-data:
Tips for Database Containers
- πΎ Always use named volumes for data persistence
- π Never use default passwords in production
- π Use init scripts for schema setup (
/docker-entrypoint-initdb.d/) - π₯ Configure health checks so dependent services wait for the DB
- π¦ Back up volumes regularly with
pg_dumpor volume exports