Docker 開発環境 コピペで使える Tips 集 — compose・マルチステージビルド・Devcontainer
Docker 開発環境のコピペで使えるTips集です。日々の実務で繰り返し使うパターンをまとめました。compose・マルチステージビルド・Devcontainer の順に紹介します。
docker-compose の定番パターン
DB + アプリ + ボリューム構成
Web アプリ開発で最もよく使う構成です。PostgreSQL とアプリサーバーをひとまとめにしています。
# compose.yaml
services:
db:
image: postgres:16-alpine
environment:
POSTGRES_USER: devuser
POSTGRES_PASSWORD: devpassword
POSTGRES_DB: devdb
volumes:
- postgres_data:/var/lib/postgresql/data
ports:
- "5432:5432"
healthcheck:
test: ["CMD-SHELL", "pg_isready -U devuser -d devdb"]
interval: 10s
timeout: 5s
retries: 5
start_period: 10s
app:
build:
context: .
target: dev
environment:
DATABASE_URL: postgres://devuser:devpassword@db:5432/devdb
volumes:
- .:/app
- node_modules:/app/node_modules
ports:
- "3000:3000"
depends_on:
db:
condition: service_healthy
command: npm run dev
volumes:
postgres_data:
node_modules:
Redis を追加する場合
services:
redis:
image: redis:7-alpine
ports:
- "6379:6379"
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 3s
retries: 5
depends_on でアプリが Redis のヘルスチェック通過後に起動するよう制御できます。
環境変数ファイルの分離
services:
app:
env_file:
- .env
- .env.local
.env はデフォルト値のみ(リポジトリにコミット可)、.env.local を .gitignore に入れて秘密情報を分離する運用が定番です。
マルチステージビルドで本番イメージを軽量化
開発用ツールを含まない軽量な本番イメージを作るパターンです。Node.js アプリを例に示します。
# Dockerfile
# --- base ---
FROM node:22-alpine AS base
WORKDIR /app
COPY package*.json ./
# --- dev ---
FROM base AS dev
RUN npm ci
COPY . .
CMD ["npm", "run", "dev"]
# --- builder ---
FROM base AS builder
RUN npm ci --omit=dev
COPY . .
RUN npm run build
# --- prod ---
FROM node:22-alpine AS prod
WORKDIR /app
ENV NODE_ENV=production
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/node_modules ./node_modules
COPY package*.json ./
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
EXPOSE 3000
CMD ["node", "dist/index.js"]
compose.yaml の target でステージを切り替えます。
services:
app:
build:
context: .
target: dev # 本番は prod に変更
Python(FastAPI)の場合:
FROM python:3.12-slim AS base
WORKDIR /app
COPY requirements*.txt ./
FROM base AS dev
RUN pip install -r requirements-dev.txt
COPY . .
CMD ["uvicorn", "main:app", "--reload", "--host", "0.0.0.0"]
FROM base AS prod
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
RUN adduser --disabled-password --no-create-home appuser
USER appuser
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
ヘルスチェック設定
Dockerfile 内に記述する場合
HEALTHCHECK --interval=30s --timeout=10s --start-period=15s --retries=3 \
CMD curl -f http://localhost:3000/health || exit 1
compose.yaml に記述する場合(上書き可能で柔軟)
services:
app:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
interval: 30s
timeout: 10s
start_period: 15s
retries: 3
start_period はアプリの起動時間に合わせて設定します。起動が遅いサービスはここを長くしないと depends_on: condition: service_healthy で永遠に待ち続けます。
ヘルスチェック状態の確認:
docker inspect --format='{{json .State.Health}}' <container_name> | jq
.dockerignore の書き方
ビルドコンテキストが大きいほどビルドが遅くなります。.dockerignore で不要なものを除外します。
# .dockerignore
# 依存パッケージ(コンテナ内でインストール)
node_modules
.venv
__pycache__
*.pyc
*.pyo
# ビルド成果物
dist
build
.next
out
# VCS
.git
.gitignore
# ローカル設定・秘密情報
.env
.env.*
!.env.example
*.local
# エディタ・OS
.DS_Store
Thumbs.db
.vscode
.idea
# テスト・CI
coverage
.nyc_output
*.test.ts
*.spec.ts
# ドキュメント
*.md
docs
確認コマンド:
# ビルドコンテキストのサイズを確認
docker build --no-cache . 2>&1 | head -5
# .dockerignore が効いているか確認(ファイルリスト出力)
docker build --no-cache -f - . <<'EOF'
FROM busybox
COPY . /ctx
RUN find /ctx | sort
EOF
よく使う docker コマンド集
起動・停止
# 起動(バックグラウンド)
docker compose up -d
# 特定サービスだけ再起動
docker compose restart app
# ログをリアルタイムで見る
docker compose logs -f app
# コンテナに入る
docker compose exec app sh
# 一時的にコマンドを実行(コンテナを新規作成して削除)
docker compose run --rm app npm run migrate
イメージ・コンテナの掃除
# 停止中コンテナをすべて削除
docker container prune -f
# タグなしイメージを削除
docker image prune -f
# 未使用ボリュームを削除(データが消えるので注意)
docker volume prune -f
# 未使用ネットワークを削除
docker network prune -f
# 上記すべてを一括(ビルドキャッシュも含む)
docker system prune -af --volumes
デバッグ
# コンテナのリソース使用量をリアルタイム表示
docker stats
# コンテナの詳細情報(IP・環境変数など)
docker inspect <container_name>
# イメージのレイヤー構成確認
docker history <image_name>
# ビルドキャッシュの確認
docker buildx du
イメージのビルド・タグ付け
# マルチステージのターゲットを指定してビルド
docker build --target prod -t myapp:latest .
# BuildKit を有効にしてビルド(デフォルト有効、キャッシュ効率が上がる)
DOCKER_BUILDKIT=1 docker build -t myapp:latest .
# ビルドキャッシュをレジストリに保存(CI で有効)
docker buildx build \
--cache-from type=registry,ref=ghcr.io/myorg/myapp:cache \
--cache-to type=registry,ref=ghcr.io/myorg/myapp:cache,mode=max \
-t ghcr.io/myorg/myapp:latest .
Devcontainer / Dev Containers の基本設定
VS Code や GitHub Codespaces で使える Dev Containers の設定例です。
ディレクトリ構成
.devcontainer/
├── devcontainer.json
└── compose.yaml # 既存の compose.yaml を参照してもOK
Node.js プロジェクト
// .devcontainer/devcontainer.json
{
"name": "Node.js Dev",
"dockerComposeFile": "../compose.yaml",
"service": "app",
"workspaceFolder": "/app",
"features": {
"ghcr.io/devcontainers/features/git:1": {},
"ghcr.io/devcontainers/features/github-cli:1": {}
},
"customizations": {
"vscode": {
"extensions": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"ms-vscode.vscode-typescript-next"
],
"settings": {
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode"
}
}
},
"postCreateCommand": "npm ci",
"remoteUser": "node"
}
Python プロジェクト
// .devcontainer/devcontainer.json
{
"name": "Python Dev",
"image": "mcr.microsoft.com/devcontainers/python:3.12",
"workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:2": {}
},
"customizations": {
"vscode": {
"extensions": [
"ms-python.python",
"ms-python.vscode-pylance",
"charliermarsh.ruff"
],
"settings": {
"python.defaultInterpreterPath": "/usr/local/bin/python",
"[python]": {
"editor.defaultFormatter": "charliermarsh.ruff"
}
}
}
},
"postCreateCommand": "pip install -r requirements-dev.txt",
"remoteUser": "vscode"
}
compose.yaml と組み合わせる場合
既存の compose.yaml をそのまま参照できます。
{
"name": "Full Stack Dev",
"dockerComposeFile": ["../compose.yaml", "compose.override.yaml"],
"service": "app",
"workspaceFolder": "/app",
"shutdownAction": "stopCompose"
}
# .devcontainer/compose.override.yaml
services:
app:
command: sleep infinity
command: sleep infinity でコンテナを起動したまま VS Code が制御を握る構成です。
まとめ
| カテゴリ | ポイント |
|---|---|
| compose 構成 | healthcheck + depends_on: condition: service_healthy でサービス起動順を制御 |
| マルチステージビルド | target で dev/prod を切り替え。本番イメージに開発ツールを含めない |
| ヘルスチェック | start_period を起動時間に合わせて設定。docker inspect でデバッグ |
| .dockerignore | node_modules / .git / .env は必ず除外。ビルドキャッシュ効率が大幅改善 |
| 掃除コマンド | docker system prune -af --volumes で一括クリア(ボリューム削除は要注意) |
| Devcontainer | postCreateCommand で依存インストールを自動化。compose と組み合わせて DB も起動 |