Docker

本番運用

Docker

セキュリティ・ヘルスチェック・リソース管理

セキュリティ

非rootユーザー・読み取り専用・Secrets

Dockerfile.secure dockerfile
FROM node:20-alpine

# セキュリティアップデートを適用
RUN apk update && apk upgrade && rm -rf /var/cache/apk/*

WORKDIR /app

# アプリ専用ユーザーを作成(rootを避ける)
RUN addgroup -S appgroup && adduser -S appuser -G appgroup

COPY --chown=appuser:appgroup package*.json ./
RUN npm ci --only=production
COPY --chown=appuser:appgroup . .

# 非rootユーザーに切り替え
USER appuser

# 読み取り専用ファイルシステム(runで --read-only オプションと組み合わせ)
# docker run --read-only --tmpfs /tmp myapp

EXPOSE 3000
CMD ["node", "server.js"]

Docker Secrets (Compose)

docker-compose.secrets.yml yaml
services:
  app:
    image: myapp:latest
    secrets:
      - db_password
      - api_key
    environment:
      # ファイルパスで参照(環境変数に直接入れない)
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    file: ./secrets/db_password.txt  # ローカル開発用
  api_key:
    external: true                   # Docker Swarm で管理

ヘルスチェックとリソース制限

健全性監視とCPU・メモリ制限

docker-compose.limits.yml yaml
services:
  app:
    image: myapp:latest

    # ヘルスチェック
    healthcheck:
      test: ["CMD", "wget", "-qO-", "http://localhost:3000/health"]
      interval: 30s    # チェック間隔
      timeout: 10s     # タイムアウト
      retries: 3       # 失敗許容回数
      start_period: 40s # 起動待機時間

    # リソース制限
    deploy:
      resources:
        limits:
          cpus: '0.5'     # 最大 0.5 コア
          memory: 512M    # 最大 512MB
        reservations:
          cpus: '0.25'    # 予約: 0.25 コア
          memory: 256M    # 予約: 256MB

    # 再起動ポリシー
    restart: unless-stopped
    # on-failure:3  → 失敗時のみ最大3回
    # always        → 常に再起動
    # no            → 再起動しない