TechLead
Lesson 15 of 18
5 min read
Docker & DevOps

Docker with Databases

Run PostgreSQL, MongoDB, Redis, and MySQL in Docker containers with data persistence and backups

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_dump or volume exports

Continue Learning