Docker Composeを使ったモダンな開発環境構築ガイド
Docker Composeを活用して、フロントエンド(React)、バックエンド(Express)、データベース(PostgreSQL)を連携させた、効率的で再現性の高い開発環境を構築する手順を解説します。
docker DockerDocker Compose開発環境ReactNode.js
Docker開発環境構築
Docker Composeを使った効率的な開発環境の構築方法
基本構成
プロジェクト構造
project/
├── docker-compose.yml # 基本設定
├── docker-compose.dev.yml # 開発環境用
├── docker-compose.prod.yml # 本番環境用
├── frontend/
│ ├── Dockerfile
│ ├── nginx.conf # プロダクション用
│ └── src/
├── backend/
│ ├── Dockerfile
│ └── src/
└── database/
└── init.sql # 初期化スクリプト
Docker Compose設定
基本設定(docker-compose.yml)
version: '3.8'
services:
# PostgreSQLデータベース
database:
image: postgres:15
container_name: collepoke_db
environment:
POSTGRES_DB: collepoke
POSTGRES_USER: user
POSTGRES_PASSWORD: password
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./database/init.sql:/docker-entrypoint-initdb.d/init.sql
healthcheck:
test: ["CMD-SHELL", "pg_isready -U user -d collepoke"]
interval: 30s
timeout: 10s
retries: 3
# バックエンドAPI
backend:
build:
context: ./backend
dockerfile: Dockerfile
container_name: collepoke_backend
environment:
DB_HOST: database
DB_PORT: 5432
DB_NAME: collepoke
DB_USER: user
DB_PASSWORD: password
NODE_ENV: production
ports:
- "3001:3001"
depends_on:
database:
condition: service_healthy
volumes:
- ./backend:/app
- /app/node_modules
# フロントエンド
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
container_name: collepoke_frontend
environment:
VITE_API_URL: http://backend:3001
ports:
- "3002:80"
depends_on:
- backend
volumes:
postgres_data:
開発環境用設定(docker-compose.dev.yml)
version: '3.8'
services:
backend:
environment:
NODE_ENV: development
volumes:
- ./backend:/app
- /app/node_modules
command: npm run dev
frontend:
build:
context: ./frontend
target: development # マルチステージビルドの開発段階
environment:
VITE_API_URL: http://localhost:3001 # 開発時はlocalhost
ports:
- "5173:5173" # Vite開発サーバー
volumes:
- ./frontend:/app
- /app/node_modules
command: npm run dev
本番環境用設定(docker-compose.prod.yml)
version: '3.8'
services:
backend:
environment:
NODE_ENV: production
restart: always
frontend:
build:
context: ./frontend
target: production # マルチステージビルドの本番段階
restart: always
database:
restart: always
volumes:
- postgres_data:/var/lib/postgresql/data
# 本番では初期化スクリプトは除外
Dockerfile設定
フロントエンド(React + Vite)
# マルチステージビルド
FROM node:18-alpine AS base
WORKDIR /app
COPY package*.json ./
RUN npm ci
# 開発段階
FROM base AS development
COPY . .
EXPOSE 5173
CMD ["npm", "run", "dev", "--", "--host", "0.0.0.0"]
# ビルド段階
FROM base AS build
COPY . .
RUN npm run build
# 本番段階
FROM nginx:alpine AS production
COPY --from=build /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
バックエンド(Express.js)
FROM node:18-alpine
WORKDIR /app
# 依存関係のインストール
COPY package*.json ./
RUN npm ci
# ソースコードのコピー
COPY . .
# TypeScriptのビルド
RUN npm run build
# アプリケーションの起動
EXPOSE 3001
CMD ["npm", "start"]
運用コマンド
開発環境
# 開発環境の起動
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up
# バックグラウンド実行
docker-compose -f docker-compose.yml -f docker-compose.dev.yml up -d
# ログの確認
docker-compose logs -f [service-name]
# 特定サービスの再起動
docker-compose restart backend
# 全コンテナの停止
docker-compose down
データベースのリセット
# ボリュームも含めて完全削除
docker-compose down -v
# 再構築
docker-compose up --build
本番環境
# 本番環境での起動
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up -d
# イメージの再ビルド
docker-compose -f docker-compose.yml -f docker-compose.prod.yml up --build -d
nginx設定
SPA + API用設定
server {
listen 80;
root /usr/share/nginx/html;
index index.html;
# SPA用設定(React Router対応)
location / {
try_files $uri $uri/ /index.html;
}
# API用リバースプロキシ
location /api/ {
proxy_pass http://backend:3001;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;
}
# 静的ファイルのキャッシュ設定
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg|woff|woff2|ttf|eot)$ {
expires 1y;
add_header Cache-Control "public, immutable";
}
# gzip圧縮
gzip on;
gzip_vary on;
gzip_min_length 1000;
gzip_types
text/plain
text/css
text/xml
text/javascript
application/xml+rss
application/javascript
application/json;
}
環境変数管理
.env ファイル設定
# データベース設定
POSTGRES_DB=collepoke
POSTGRES_USER=user
POSTGRES_PASSWORD=your_secure_password
DB_HOST=database
DB_PORT=5432
# バックエンド設定
NODE_ENV=development
PORT=3001
JWT_SECRET=your_jwt_secret
# フロントエンド設定
VITE_API_URL=http://localhost:3001
VITE_APP_NAME=CollePoke
docker-compose.ymlでの環境変数読み込み
services:
database:
environment:
POSTGRES_DB: ${POSTGRES_DB}
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
backend:
environment:
DB_HOST: ${DB_HOST}
DB_USER: ${POSTGRES_USER}
DB_PASSWORD: ${POSTGRES_PASSWORD}
DB_NAME: ${POSTGRES_DB}
NODE_ENV: ${NODE_ENV}
JWT_SECRET: ${JWT_SECRET}
frontend:
environment:
VITE_API_URL: ${VITE_API_URL}
ボリューム管理
データの永続化
volumes:
# PostgreSQLデータの永続化
postgres_data:
driver: local
# node_modulesの効率的な管理
frontend_node_modules:
backend_node_modules:
services:
frontend:
volumes:
- ./frontend:/app
- frontend_node_modules:/app/node_modules # ホストと分離
backend:
volumes:
- ./backend:/app
- backend_node_modules:/app/node_modules
開発時のホットリロード対応
services:
frontend:
volumes:
- ./frontend:/app
- /app/node_modules
environment:
- CHOKIDAR_USEPOLLING=true # ファイル変更検知の改善
ports:
- "5173:5173"
command: npm run dev -- --host 0.0.0.0
ヘルスチェック設定
データベースのヘルスチェック
database:
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER} -d ${POSTGRES_DB}"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
バックエンドのヘルスチェック
backend:
healthcheck:
test: ["CMD", "curl", "-f", "http://localhost:3001/api/health"]
interval: 30s
timeout: 10s
retries: 3
start_period: 60s
セキュリティ設定
非rootユーザーでの実行
# Dockerfile
FROM node:18-alpine
# 非rootユーザーの作成
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN chown -R nextjs:nodejs /app
USER nextjs
EXPOSE 3001
CMD ["npm", "start"]
ネットワーク分離
networks:
frontend-network:
backend-network:
database-network:
services:
frontend:
networks:
- frontend-network
backend:
networks:
- frontend-network
- backend-network
- database-network
database:
networks:
- database-network
パフォーマンス最適化
イメージサイズの最適化
# マルチステージビルドの活用
FROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine AS runtime
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package*.json ./
EXPOSE 3001
CMD ["npm", "start"]
.dockerignore の設定
node_modules
npm-debug.log
.git
.gitignore
README.md
.env
.nyc_output
coverage
.vscode
.idea
*.swp
*.swo
*~
.DS_Store
Thumbs.db
モニタリングとログ
ログ設定
services:
backend:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
frontend:
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"
ログの確認コマンド
# 全サービスのログを表示
docker-compose logs -f
# 特定サービスのログのみ
docker-compose logs -f backend
# 最新のログのみ表示
docker-compose logs --tail=100 backend
# タイムスタンプ付きでログ表示
docker-compose logs -f -t backend
トラブルシューティング
よくある問題と解決方法
コンテナが起動しない
# ログの確認
docker-compose logs [service-name]
# コンテナの状態確認
docker-compose ps
# 個別コンテナでのデバッグ
docker-compose exec backend sh
ポート競合エラー
# 使用中のポートを確認
netstat -an | grep 3001
lsof -i :3001
# ポート番号を変更
# docker-compose.yml
ports:
- "3002:3001" # ホスト側のポートを変更
ボリュームマウントの問題
# ボリュームの確認
docker volume ls
# ボリュームの詳細情報
docker volume inspect project_postgres_data
# ボリュームの削除
docker volume rm project_postgres_data