Dockerガイド 
この包括的なガイドでは、Traeで構築されたアプリケーションのDocker使用法、コンテナ化ベストプラクティス、デプロイメント戦略について説明します。
概要 
Dockerは、コンテナ化を通じて一貫性があり、ポータブルで、スケーラブルなアプリケーションデプロイメントを可能にします。このガイドでは以下について説明します:
- Dockerの基礎
- Dockerfileベストプラクティス
- マルチステージビルド
- Docker Compose
- コンテナオーケストレーション
- セキュリティ考慮事項
- パフォーマンス最適化
Dockerの基礎 
核心概念 
イメージとコンテナ 
- イメージ: コンテナを作成するための読み取り専用テンプレート
- コンテナ: イメージの実行中インスタンス
- レイヤー: Dockerfileの各命令がレイヤーを作成
- レジストリ: イメージの保存と配布システム
Dockerアーキテクチャ 
┌─────────────────┐    ┌─────────────────┐    ┌─────────────────┐
│   Docker CLI    │    │  Docker Daemon  │    │   Docker Hub    │
│                 │───▶│                 │───▶│                 │
│  docker build   │    │   Image Mgmt    │    │   Image Store   │
│  docker run     │    │   Container     │    │   Public/Private│
│  docker push    │    │   Management    │    │   Repositories  │
└─────────────────┘    └─────────────────┘    └─────────────────┘基本コマンド 
bash
# イメージ管理
docker build -t myapp:latest .
docker images
docker rmi image_id
docker pull nginx:alpine
docker push myregistry/myapp:latest
# コンテナ管理
docker run -d -p 3000:3000 --name myapp myapp:latest
docker ps
docker ps -a
docker stop container_id
docker rm container_id
docker logs container_id
docker exec -it container_id /bin/bash
# System management
docker system prune
docker volume ls
docker network lsDockerfile Best Practices 
Basic Dockerfile Structure 
dockerfile
# 公式ベースイメージを使用
FROM node:18-alpine AS base
# 作業ディレクトリを設定
WORKDIR /app
# パッケージファイルをコピー
COPY package*.json ./
# 依存関係をインストール
RUN npm ci --only=production && npm cache clean --force
# アプリケーションコードをコピー
COPY . .
# 非rootユーザーを作成
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001
# 所有権を変更
RUN chown -R nextjs:nodejs /app
USER nextjs
# ポートを公開
EXPOSE 3000
# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
# アプリケーションを開始
CMD ["npm", "start"]Multi-Stage Builds 
dockerfile
# Node.jsアプリケーション用マルチステージビルド
# ステージ1: 依存関係のビルド
FROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
# ステージ2: アプリケーションのビルド
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# ステージ3: 本番イメージ
FROM node:18-alpine AS production
WORKDIR /app
# 適切なシグナル処理のためdumb-initをインストール
RUN apk add --no-cache dumb-init
# 非rootユーザーを作成
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001
# ビルドされたアプリケーションをコピー
COPY --from=builder --chown=nextjs:nodejs /app/dist ./dist
COPY --from=dependencies --chown=nextjs:nodejs /app/node_modules ./node_modules
COPY --chown=nextjs:nodejs package*.json ./
# 非rootユーザーに切り替え
USER nextjs
# ポートを公開
EXPOSE 3000
# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:3000/health || exit 1
# 適切なシグナル処理のためdumb-initを使用
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "dist/server.js"]Language-Specific Examples 
Python Application 
dockerfile
FROM python:3.11-slim AS base
# 環境変数を設定
ENV PYTHONDONTWRITEBYTECODE=1 \
    PYTHONUNBUFFERED=1 \
    PYTHONHASHSEED=random \
    PIP_NO_CACHE_DIR=1 \
    PIP_DISABLE_PIP_VERSION_CHECK=1
# システム依存関係をインストール
RUN apt-get update && apt-get install -y \
    build-essential \
    curl \
    && rm -rf /var/lib/apt/lists/*
# 非rootユーザーを作成
RUN groupadd -r appuser && useradd -r -g appuser appuser
# 作業ディレクトリを設定
WORKDIR /app
# Python依存関係をインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
# アプリケーションコードをコピー
COPY --chown=appuser:appuser . .
# 非rootユーザーに切り替え
USER appuser
# ポートを公開
EXPOSE 8000
# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:8000/health || exit 1
# アプリケーションを開始
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]Go Application 
dockerfile
# ビルドステージ
FROM golang:1.21-alpine AS builder
WORKDIR /app
# go modファイルをコピー
COPY go.mod go.sum ./
RUN go mod download
# ソースコードをコピー
COPY . .
# アプリケーションをビルド
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o main .
# 本番ステージ
FROM alpine:latest AS production
# HTTPS用のca-certificatesをインストール
RUN apk --no-cache add ca-certificates
# 非rootユーザーを作成
RUN adduser -D -s /bin/sh appuser
WORKDIR /root/
# ビルダーステージからバイナリをコピー
COPY --from=builder /app/main .
# 所有権を変更
RUN chown appuser:appuser main
# 非rootユーザーに切り替え
USER appuser
# ポートを公開
EXPOSE 8080
# ヘルスチェック
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1
# アプリケーションを開始
CMD ["./main"]Docker Compose 
Basic Docker Compose Setup 
yaml
# docker-compose.yml
version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
      target: production
    ports:
      - "3000:3000"
    environment:
      - NODE_ENV=production
      - DATABASE_URL=postgresql://postgres:password@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - app_logs:/app/logs
    networks:
      - app_network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    volumes:
      - postgres_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - app_network
    restart: unless-stopped
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5
  redis:
    image: redis:7-alpine
    command: redis-server --appendonly yes
    volumes:
      - redis_data:/data
    networks:
      - app_network
    restart: unless-stopped
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 3s
      retries: 3
  nginx:
    image: nginx:alpine
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
      - ./ssl:/etc/nginx/ssl
    depends_on:
      - app
    networks:
      - app_network
    restart: unless-stopped
volumes:
  postgres_data:
  redis_data:
  app_logs:
networks:
  app_network:
    driver: bridgeDevelopment Docker Compose 
yaml
# docker-compose.dev.yml
version: '3.8'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
      - "9229:9229"  # Node.jsデバッガー
    environment:
      - NODE_ENV=development
      - DEBUG=app:*
    volumes:
      - .:/app
      - /app/node_modules
    command: npm run dev
    depends_on:
      - db
      - redis
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp_dev
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD=password
    ports:
      - "5432:5432"
    volumes:
      - postgres_dev_data:/var/lib/postgresql/data
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
  mailhog:
    image: mailhog/mailhog
    ports:
      - "1025:1025"
      - "8025:8025"
volumes:
  postgres_dev_data:Production Docker Compose 
yaml
# docker-compose.prod.yml
version: '3.8'
services:
  app:
    image: myregistry/myapp:${APP_VERSION:-latest}
    deploy:
      replicas: 3
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    environment:
      - NODE_ENV=production
    secrets:
      - db_password
      - jwt_secret
    networks:
      - app_network
      - traefik_network
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.app.rule=Host(`myapp.com`)"
      - "traefik.http.routers.app.tls.certresolver=letsencrypt"
  db:
    image: postgres:15-alpine
    environment:
      - POSTGRES_DB=myapp
      - POSTGRES_USER=postgres
      - POSTGRES_PASSWORD_FILE=/run/secrets/db_password
    volumes:
      - postgres_data:/var/lib/postgresql/data
    secrets:
      - db_password
    networks:
      - app_network
    deploy:
      placement:
        constraints:
          - node.role == manager
secrets:
  db_password:
    external: true
  jwt_secret:
    external: true
volumes:
  postgres_data:
    external: true
networks:
  app_network:
    driver: overlay
    attachable: true
  traefik_network:
    external: trueContainer Orchestration 
Docker Swarm 
bash
# Swarmを初期化
docker swarm init
# ワーカーノードを参加
docker swarm join --token SWMTKN-1-... manager-ip:2377
# スタックをデプロイ
docker stack deploy -c docker-compose.prod.yml myapp
# サービスをスケール
docker service scale myapp_app=5
# サービスを更新
docker service update --image myregistry/myapp:v2.0.0 myapp_app
# サービスを監視
docker service ls
docker service ps myapp_appKubernetes Deployment 
yaml
# k8s/deployment.yml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myregistry/myapp:latest
        ports:
        - containerPort: 3000
        env:
        - name: NODE_ENV
          value: "production"
        - name: DATABASE_URL
          valueFrom:
            secretKeyRef:
              name: myapp-secrets
              key: database-url
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancerSecurity Best Practices 
Dockerfile Security 
dockerfile
# セキュリティ重視のDockerfile
FROM node:18-alpine AS base
# パッケージを更新してセキュリティアップデートをインストール
RUN apk update && apk upgrade && apk add --no-cache dumb-init
# 非rootユーザーを作成
RUN addgroup -g 1001 -S nodejs && \
    adduser -S nextjs -u 1001 -G nodejs
# 作業ディレクトリを設定
WORKDIR /app
# パッケージファイルをコピー
COPY package*.json ./
# 依存関係をインストール
RUN npm ci --only=production && \
    npm cache clean --force && \
    rm -rf /tmp/*
# アプリケーションコードをコピー
COPY --chown=nextjs:nodejs . .
# 不要なファイルを削除
RUN rm -rf .git .gitignore README.md docs/ tests/
# 適切な権限を設定
RUN chmod -R 755 /app && \
    chmod -R 644 /app/package*.json
# 非rootユーザーに切り替え
USER nextjs
# ポートを公開(非特権)
EXPOSE 3000
# 適切なシグナル処理のためにdumb-initを使用
ENTRYPOINT ["dumb-init", "--"]
CMD ["node", "server.js"]Security Scanning 
bash
# Scan images for vulnerabilities
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image myapp:latest
# Scan Dockerfile
docker run --rm -i hadolint/hadolint < Dockerfile
# Use Docker Bench Security
docker run -it --net host --pid host --userns host --cap-add audit_control \
  -e DOCKER_CONTENT_TRUST=$DOCKER_CONTENT_TRUST \
  -v /var/lib:/var/lib \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v /usr/lib/systemd:/usr/lib/systemd \
  -v /etc:/etc --label docker_bench_security \
  docker/docker-bench-securityRuntime Security 
yaml
# docker-compose.yml with security constraints
version: '3.8'
services:
  app:
    image: myapp:latest
    security_opt:
      - no-new-privileges:true
    cap_drop:
      - ALL
    cap_add:
      - NET_BIND_SERVICE
    read_only: true
    tmpfs:
      - /tmp
      - /var/cache
    user: "1001:1001"
    ulimits:
      nproc: 65535
      nofile:
        soft: 65535
        hard: 65535Performance Optimization 
Image Optimization 
dockerfile
# Optimized Dockerfile
FROM node:18-alpine AS dependencies
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
# Distroless image for minimal attack surface
FROM gcr.io/distroless/nodejs18-debian11 AS production
WORKDIR /app
COPY --from=dependencies /app/node_modules ./node_modules
COPY --from=build /app/dist ./dist
COPY package*.json ./
EXPOSE 3000
CMD ["dist/server.js"]Build Optimization 
bash
# Use BuildKit for faster builds
export DOCKER_BUILDKIT=1
docker build --target production -t myapp:latest .
# Use build cache
docker build --cache-from myapp:latest -t myapp:latest .
# Multi-platform builds
docker buildx build --platform linux/amd64,linux/arm64 -t myapp:latest .Resource Management 
yaml
# docker-compose.yml with resource limits
version: '3.8'
services:
  app:
    image: myapp:latest
    deploy:
      resources:
        limits:
          cpus: '0.5'
          memory: 512M
        reservations:
          cpus: '0.25'
          memory: 256M
    mem_limit: 512m
    mem_reservation: 256m
    cpus: 0.5
    oom_kill_disable: falseMonitoring and Logging 
Container Monitoring 
yaml
# docker-compose.monitoring.yml
version: '3.8'
services:
  prometheus:
    image: prom/prometheus
    ports:
      - "9090:9090"
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - prometheus_data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--web.console.libraries=/etc/prometheus/console_libraries'
      - '--web.console.templates=/etc/prometheus/consoles'
  grafana:
    image: grafana/grafana
    ports:
      - "3001:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - grafana_data:/var/lib/grafana
  cadvisor:
    image: gcr.io/cadvisor/cadvisor
    ports:
      - "8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:rw
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
volumes:
  prometheus_data:
  grafana_data:Centralized Logging 
yaml
# docker-compose.logging.yml
version: '3.8'
services:
  app:
    image: myapp:latest
    logging:
      driver: "fluentd"
      options:
        fluentd-address: localhost:24224
        tag: myapp
  fluentd:
    image: fluent/fluentd:v1.14-debian-1
    ports:
      - "24224:24224"
    volumes:
      - ./fluentd.conf:/fluentd/etc/fluent.conf
      - fluentd_data:/var/log/fluentd
  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:8.5.0
    environment:
      - discovery.type=single-node
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
    volumes:
      - elasticsearch_data:/usr/share/elasticsearch/data
  kibana:
    image: docker.elastic.co/kibana/kibana:8.5.0
    ports:
      - "5601:5601"
    environment:
      - ELASTICSEARCH_HOSTS=http://elasticsearch:9200
volumes:
  fluentd_data:
  elasticsearch_data:CI/CD Integration 
GitHub Actions 
yaml
# .github/workflows/docker.yml
name: Docker Build and Deploy
on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]
env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}
jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write
    steps:
    - name: Checkout repository
      uses: actions/checkout@v3
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    - name: Log in to Container Registry
      uses: docker/login-action@v2
      with:
        registry: ${{ env.REGISTRY }}
        username: ${{ github.actor }}
        password: ${{ secrets.GITHUB_TOKEN }}
    - name: Extract metadata
      id: meta
      uses: docker/metadata-action@v4
      with:
        images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
        tags: |
          type=ref,event=branch
          type=ref,event=pr
          type=sha,prefix={{branch}}-
          type=raw,value=latest,enable={{is_default_branch}}
    - name: Build and push Docker image
      uses: docker/build-push-action@v4
      with:
        context: .
        platforms: linux/amd64,linux/arm64
        push: true
        tags: ${{ steps.meta.outputs.tags }}
        labels: ${{ steps.meta.outputs.labels }}
        cache-from: type=gha
        cache-to: type=gha,mode=max
    - name: Run security scan
      uses: aquasecurity/trivy-action@master
      with:
        image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest
        format: 'sarif'
        output: 'trivy-results.sarif'
    - name: Upload Trivy scan results
      uses: github/codeql-action/upload-sarif@v2
      with:
        sarif_file: 'trivy-results.sarif'GitLab CI/CD 
yaml
# .gitlab-ci.yml
stages:
  - build
  - test
  - security
  - deploy
variables:
  DOCKER_DRIVER: overlay2
  DOCKER_TLS_CERTDIR: "/certs"
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHA
build:
  stage: build
  image: docker:20.10.16
  services:
    - docker:20.10.16-dind
  before_script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
  script:
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG
  only:
    - main
    - develop
security_scan:
  stage: security
  image: aquasec/trivy:latest
  script:
    - trivy image --exit-code 0 --format template --template "@contrib/gitlab.tpl" -o gl-container-scanning-report.json $IMAGE_TAG
  artifacts:
    reports:
      container_scanning: gl-container-scanning-report.json
  only:
    - main
    - develop
deploy_staging:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
  script:
    - curl -X POST "$WEBHOOK_URL" -H "Content-Type: application/json" -d '{"image":"'$IMAGE_TAG'"}'
  only:
    - develop
deploy_production:
  stage: deploy
  image: alpine:latest
  before_script:
    - apk add --no-cache curl
  script:
    - curl -X POST "$PROD_WEBHOOK_URL" -H "Content-Type: application/json" -d '{"image":"'$IMAGE_TAG'"}'
  only:
    - main
  when: manualTroubleshooting 
Common Issues 
Container Won't Start 
bash
# Check container logs
docker logs container_name
# Check container configuration
docker inspect container_name
# Run container interactively
docker run -it --entrypoint /bin/sh image_namePerformance Issues 
bash
# Monitor container resources
docker stats
# Check container processes
docker exec container_name ps aux
# Analyze image layers
docker history image_nameNetwork Issues 
bash
# List networks
docker network ls
# Inspect network
docker network inspect network_name
# Test connectivity
docker exec container_name ping other_containerStorage Issues 
bash
# Check disk usage
docker system df
# Clean up unused resources
docker system prune -a
# Check volume usage
docker volume ls
docker volume inspect volume_nameDebugging Tools 
bash
# Debug container with additional tools
docker run -it --rm \
  --pid container:target_container \
  --net container:target_container \
  --cap-add SYS_PTRACE \
  nicolaka/netshoot
# Profile container performance
docker run -it --rm \
  --pid container:target_container \
  --cap-add SYS_PTRACE \
  brendangregg/perf-toolsBest Practices Summary 
Development 
- Use Multi-stage Builds: Reduce image size and improve security
- Leverage Build Cache: Speed up builds with proper layer ordering
- Use .dockerignore: Exclude unnecessary files from build context
- Pin Base Images: Use specific versions for reproducible builds
- Run as Non-root: Improve security by using non-privileged users
Production 
- Health Checks: Implement proper health checks for containers
- Resource Limits: Set appropriate CPU and memory limits
- Security Scanning: Regularly scan images for vulnerabilities
- Monitoring: Implement comprehensive monitoring and logging
- Backup Strategy: Ensure data persistence and backup procedures
Operations 
- Container Orchestration: Use orchestration tools for production
- Rolling Updates: Implement zero-downtime deployment strategies
- Secret Management: Use proper secret management solutions
- Network Security: Implement network segmentation and policies
- Disaster Recovery: Plan for disaster recovery scenarios