SJ blog
backend
A

信頼度ランク

S 公式ソース確認済み
A 成功実績多数・失敗例少数
B 賛否両論
C 動作未確認・セキュリティリスク高
Z 個人所感

Docker Composeでローカル開発環境を完璧に管理する

Docker Composeを使ったローカル開発環境の構築パターンを解説。ホットリロード・ヘルスチェック・シークレット管理・マルチサービス構成など実践的なTipsを紹介します。

一言結論

Docker Composeでローカル開発環境を定義すれば「自分の環境では動く」問題を根絶できるが、ヘルスチェックとvolumes設定を正しく行わないと起動順序の競合やコードの変更が反映されないという別の罠にはまる。

なぜ Docker Compose を使うのか

チームの「自分の環境では動く」を排除する
データベース・キャッシュ・メッセージキューなどの依存関係を一発で起動
本番環境に近い構成をローカルで再現

基本的な docker-compose.yml

# docker-compose.yml
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - .:/app                     # ホストのコードをマウント(ホットリロード)
      - /app/node_modules          # node_modules はコンテナ側を使う
    environment:
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy  # DB が ready になってから起動
      redis:
        condition: service_started

  db:
    image: postgres:16
    environment:
      POSTGRES_USER: postgres
      POSTGRES_PASSWORD: password
      POSTGRES_DB: myapp
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data  # データ永続化
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 5s
      timeout: 5s
      retries: 5

  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"

volumes:
  postgres_data:

Dockerfile.dev — 開発専用設定

FROM node:22-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install

# ソースはボリュームでマウントするのでコピー不要
EXPOSE 3000
CMD ["npm", "run", "dev"]

よく使うコマンド

# 起動(バックグラウンド)
docker compose up -d

# ログをリアルタイムで確認
docker compose logs -f app

# 特定サービスのシェルに入る
docker compose exec app sh

# 停止(ボリューム含む完全削除)
docker compose down -v

# 設定を変えてビルドし直す
docker compose up --build

# 特定サービスだけ再起動
docker compose restart app

シークレット管理

パスワードなどを環境変数に直書きしない。

# .env.local(gitignore に追加)
POSTGRES_PASSWORD=supersecret
JWT_SECRET=myjwtsecret
# docker-compose.yml
services:
  app:
    env_file:
      - .env.local
.gitignore に追加:
.env.local
.env.production

ヘルスチェックと起動順序の制御

services:
  worker:
    depends_on:
      db:
        condition: service_healthy    # DB が healthy になるまで待つ
      redis:
        condition: service_started    # redis は started でOK
      migration:
        condition: service_completed_successfully  # マイグレーション完了後に起動

  migration:
    build: .
    command: npm run migrate
    depends_on:
      db:
        condition: service_healthy
    restart: "no"  # 一度実行したら終了

プロファイルで環境を切り替える

services:
  app:
    build: .
    profiles: ["app", "full"]

  mailhog:           # 開発時のみメール確認用
    image: mailhog/mailhog
    profiles: ["dev"]
    ports:
      - "8025:8025"

  prometheus:        # 監視スタックは必要な時だけ
    image: prom/prometheus
    profiles: ["monitoring"]
# dev プロファイルのみ起動
docker compose --profile dev up

# 全サービス起動
docker compose --profile full --profile monitoring up

まとめ

ホットリロード    → volumes でソースをマウント
DB の起動待ち    → healthcheck + depends_on condition
シークレット      → .env ファイル(gitignore 必須)
環境の切り替え   → profiles を活用

docker compose up -d 一発でチームの誰でも同じ環境が立ち上がる状態を目指すことが、開発生産性に直結します。


参考: Docker Compose 公式ドキュメント