Local Development with Docker Compose: MySQL, Redis, and MinIO

Build a local development environment with MySQL, Redis, and MinIO using Docker Compose, covering docker-compose.yml syntax, data persistence, and health checks.

Introduction

Manually installing and configuring middleware like MySQL, Redis, and object storage for local development often leads to environment inconsistencies and version management issues. Docker Compose lets you spin up a reproducible development environment instantly with a single docker compose up command.

This article explains how to build a practical development environment with MySQL, Redis, and MinIO (S3-compatible object storage) using Docker Compose.

Basic docker-compose.yml Structure

A Docker Compose configuration file consists of three main sections:

services: # Container definitions
  web:
    image: nginx
    ports:
      - "8080:80"

volumes: # Volumes for data persistence
  db-data:

networks: # Custom networks
  backend:

Service Configuration

MySQL

services:
  mysql:
    image: mysql:8.0
    container_name: dev-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpass}
      MYSQL_DATABASE: ${MYSQL_DATABASE:-devdb}
      MYSQL_USER: ${MYSQL_USER:-devuser}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-devpass}
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --default-time-zone=+09:00

Setting default-time-zone=+09:00 enables JST-based datetime management.

Redis

redis:
  image: redis:7-alpine
  container_name: dev-redis
  ports:
    - "6379:6379"
  volumes:
    - redis-data:/data
  healthcheck:
    test: ["CMD", "redis-cli", "ping"]
    interval: 10s
    timeout: 5s
    retries: 5
  command: redis-server --appendonly yes

--appendonly yes enables AOF (Append Only File) persistence for data durability.

MinIO (S3-Compatible Storage)

minio:
  image: minio/minio:latest
  container_name: dev-minio
  environment:
    MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
    MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
  ports:
    - "9000:9000" # API
    - "9001:9001" # Console
  volumes:
    - minio-data:/data
  healthcheck:
    test: ["CMD", "mc", "ready", "local"]
    interval: 10s
    timeout: 5s
    retries: 5
  command: server /data --console-address ":9001"

MinIO provides an AWS S3-compatible API, making it ideal for local development of applications that use S3 in production.

Complete docker-compose.yml

services:
  mysql:
    image: mysql:8.0
    container_name: dev-mysql
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD:-rootpass}
      MYSQL_DATABASE: ${MYSQL_DATABASE:-devdb}
      MYSQL_USER: ${MYSQL_USER:-devuser}
      MYSQL_PASSWORD: ${MYSQL_PASSWORD:-devpass}
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    healthcheck:
      test: ["CMD", "mysqladmin", "ping", "-h", "localhost"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s
    command: >
      --character-set-server=utf8mb4
      --collation-server=utf8mb4_unicode_ci
      --default-time-zone=+09:00

  redis:
    image: redis:7-alpine
    container_name: dev-redis
    ports:
      - "6379:6379"
    volumes:
      - redis-data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    command: redis-server --appendonly yes

  minio:
    image: minio/minio:latest
    container_name: dev-minio
    environment:
      MINIO_ROOT_USER: ${MINIO_ROOT_USER:-minioadmin}
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-minioadmin}
    ports:
      - "9000:9000"
      - "9001:9001"
    volumes:
      - minio-data:/data
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 10s
      timeout: 5s
      retries: 5
    command: server /data --console-address ":9001"

volumes:
  mysql-data:
  redis-data:
  minio-data:

Common Commands

CommandDescription
docker compose up -dStart in background
docker compose downStop and remove containers
docker compose down -vStop and remove volumes too
docker compose logs -f mysqlFollow MySQL logs
docker compose exec mysql mysql -u devuser -p devdbConnect to MySQL
docker compose exec redis redis-cliConnect to Redis CLI
docker compose psCheck container status
docker compose restart redisRestart specific service

Data Persistence

Named Volumes vs Bind Mounts

TypeUse CaseExample
Named VolumeDB data persistencemysql-data:/var/lib/mysql
Bind MountSource code sync./src:/app/src

Named Volumes persist after docker compose down, but are deleted with the -v flag.

Health Checks and depends_on

Combine healthcheck with depends_on to control service startup order:

services:
  app:
    build: .
    depends_on:
      mysql:
        condition: service_healthy
      redis:
        condition: service_healthy

condition: service_healthy waits for the dependency’s health check to pass before starting the app.

Environment Variable Management

A .env file placed alongside docker-compose.yml is automatically loaded:

# .env
MYSQL_ROOT_PASSWORD=my_secure_password
MYSQL_DATABASE=myapp
MYSQL_USER=appuser
MYSQL_PASSWORD=app_secure_password
MINIO_ROOT_USER=minio_admin
MINIO_ROOT_PASSWORD=minio_secure_password

Add .env to .gitignore and include a .env.example (without values) in version control.

Tips

Selective Service Startup with Profiles

Not all services are always needed. Profiles enable selective startup:

services:
  minio:
    profiles: ["storage"]
    image: minio/minio:latest
    # ...
docker compose up -d                    # mysql, redis only
docker compose --profile storage up -d  # include minio

Volume Cleanup

Unused volumes accumulate and consume disk space:

docker volume ls                  # List volumes
docker volume prune               # Remove unused volumes
docker system df                  # Docker disk usage

References