Agent Skills by ALSEL
Anthropic ClaudeDevOps・インフラ⭐ リポ 0品質スコア 50/100

docker

アプリケーションと依存関係をまとめて隔離されたポータブルなコンテナにパッケージングするDockerコンテナ化スキルです。開発・テスト・本番環境を問わず一貫した動作を保証し、環境差異によるトラブルを防ぎます。

description の原文を見る

Docker containerization for packaging applications with dependencies into isolated, portable units ensuring consistency across development, testing, and production environments.

SKILL.md 本文

Docker コンテナ化スキル

サマリー

Docker はアプリケーションとその依存関係を独立したポータブルなユニットにパッケージ化するためのコンテナ化を提供します。コンテナは開発、テスト、本番環境全体で一貫性を確保し、「自分のマシンでは動作する」という問題を排除します。

使用すべき時期

  • ローカル開発: チームメンバー間で一貫した開発環境
  • CI/CDパイプライン: 再現可能なビルドおよびテスト環境
  • マイクロサービス: 独立したスケーリングを持つ隔離されたサービス
  • 本番デプロイメント: クラウドプロバイダー全体でのポータブルアプリケーション
  • データベース/サービステスト: 統合テスト用の一時的なデータベース
  • レガシーアプリケーション分離: 互換性のない依存関係を並行実行

クイックスタート

1. Dockerfile の作成

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
EXPOSE 3000
CMD ["node", "server.js"]

2. イメージのビルド

docker build -t myapp:1.0 .

3. コンテナの実行

docker run -p 3000:3000 myapp:1.0

コア概念

イメージ vs コンテナ

  • イメージ: アプリケーションコード、ランタイム、依存関係を含む読み取り専用テンプレート
  • コンテナ: 書き込み可能なレイヤーを持つイメージの実行インスタンス
  • レジストリ: イメージの保存場所(Docker Hub、GitHub Container Registry)

レイヤーとキャッシング

各 Dockerfile の命令はレイヤーを作成します。Docker は変更されていないレイヤーをキャッシュしてビルドを高速化します。

# 良い例: 依存関係はコードより変更頻度が低い
FROM python:3.11-slim
COPY requirements.txt .
RUN pip install -r requirements.txt  # requirements.txt が変更されない限りキャッシュ
COPY . .                              # コード変更時のみ再ビルド

# 悪い例: コード変更のたびにキャッシュが無効化される
FROM python:3.11-slim
COPY . .                              # 頻繁に変更
RUN pip install -r requirements.txt  # ビルドのたびに再インストール

ボリューム

コンテナ再起動後も存続する永続データストレージ。

# 名前付きボリューム (Docker で管理)
docker run -v mydata:/app/data myapp

# バインドマウント (ホストディレクトリ)
docker run -v $(pwd)/data:/app/data myapp

# 匿名ボリューム (一時的)
docker run -v /app/data myapp

ネットワーク

コンテナは Docker ネットワークを通じて通信します。

# ネットワークの作成
docker network create mynetwork

# ネットワーク上でコンテナを実行
docker run --network mynetwork --name db postgres
docker run --network mynetwork --name app myapp
# アプリはホスト名 "db" を使用して db に接続可能

Dockerfile 基礎

重要な命令

# ベースイメージ
FROM node:18-alpine

# メタデータ
LABEL maintainer="dev@example.com"
LABEL version="1.0"

# ワーキングディレクトリの設定
WORKDIR /app

# ファイルのコピー
COPY package*.json ./
COPY src/ ./src/

# コマンドの実行 (レイヤーを作成)
RUN npm ci --only=production

# 環境変数の設定
ENV NODE_ENV=production
ENV PORT=3000

# ポートの公開 (ドキュメンテーションのみ)
EXPOSE 3000

# デフォルトコマンド
CMD ["node", "src/server.js"]

# 代替手段: ENTRYPOINT (docker run の引数で上書きされない)
ENTRYPOINT ["node"]
CMD ["src/server.js"]  # ENTRYPOINT のデフォルト引数

キャッシュ効率のための命令順序

# 1. ベースイメージ (ほぼ変更なし)
FROM python:3.11-slim

# 2. システム依存関係 (ほぼ変更なし)
RUN apt-get update && apt-get install -y \
    gcc \
    && rm -rf /var/lib/apt/lists/*

# 3. アプリケーション依存関係 (たまに変更)
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 4. アプリケーションコード (頻繁に変更)
COPY . .

# 5. ランタイム設定
ENV PYTHONUNBUFFERED=1
EXPOSE 8000
CMD ["python", "manage.py", "runserver", "0.0.0.0:8000"]

.dockerignore

ビルドコンテキストからファイルを除外 (ビルド高速化、イメージサイズ削減)。

# .dockerignore
node_modules/
npm-debug.log
.git/
.gitignore
*.md
.env
.vscode/
__pycache__/
*.pyc
.pytest_cache/
coverage/
dist/
build/

マルチステージビルド

ビルドステージとランタイムステージを分離してイメージサイズを最適化します。

Node.js TypeScript の例

# ビルドステージ
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

# 本番ステージ
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
EXPOSE 3000
CMD ["node", "dist/server.js"]

メリット:

  • ビルド依存関係 (TypeScript、webpack) は最終イメージから除外
  • 最終イメージ: ビルドツール付きで約500MB ではなく約50MB
  • デプロイメント高速化と攻撃面縮小

Python の例

# ビルドステージ
FROM python:3.11 AS builder
WORKDIR /app
COPY requirements.txt .
RUN pip install --user --no-cache-dir -r requirements.txt

# ランタイムステージ
FROM python:3.11-slim
WORKDIR /app
COPY --from=builder /root/.local /root/.local
COPY . .
ENV PATH=/root/.local/bin:$PATH
CMD ["python", "app.py"]

Go の例 (最小イメージ)

# ビルドステージ
FROM golang:1.21-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o server

# ランタイムステージ (scratch = 空のベースイメージ)
FROM scratch
COPY --from=builder /app/server /server
EXPOSE 8080
ENTRYPOINT ["/server"]

結果: コンパイル済みバイナリのみを含む約10MB の最終イメージ。


Docker Compose

YAML で マルチコンテナアプリケーションを定義します。

基本構造

version: '3.8'

services:
  app:
    build: .
    ports:
      - "3000:3000"
    environment:
      - DATABASE_URL=postgres://db:5432/myapp
    depends_on:
      - db
    volumes:
      - ./src:/app/src  # 開発時ホットリロード

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - db_data:/var/lib/postgresql/data
    ports:
      - "5432:5432"

volumes:
  db_data:

コマンド

# すべてのサービスを起動
docker-compose up

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

# イメージを再ビルド
docker-compose up --build

# サービスを停止
docker-compose down

# サービスを停止してボリュームを削除
docker-compose down -v

# ログを表示
docker-compose logs -f app

# ワンタイムコマンドを実行
docker-compose run app npm test

フルスタック例

version: '3.8'

services:
  # フロントエンド
  web:
    build:
      context: ./frontend
      dockerfile: Dockerfile.dev
    ports:
      - "3000:3000"
    volumes:
      - ./frontend/src:/app/src
    environment:
      - REACT_APP_API_URL=http://localhost:8000

  # バックエンド API
  api:
    build: ./backend
    ports:
      - "8000:8000"
    environment:
      - DATABASE_URL=postgresql://postgres:secret@db:5432/myapp
      - REDIS_URL=redis://redis:6379
    depends_on:
      db:
        condition: service_healthy
      redis:
        condition: service_started
    volumes:
      - ./backend:/app
    command: uvicorn main:app --host 0.0.0.0 --reload

  # データベース
  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: secret
      POSTGRES_DB: myapp
    volumes:
      - db_data:/var/lib/postgresql/data
      - ./init.sql:/docker-entrypoint-initdb.d/init.sql
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U postgres"]
      interval: 10s
      timeout: 5s
      retries: 5

  # キャッシュ
  redis:
    image: redis:7-alpine
    ports:
      - "6379:6379"
    volumes:
      - redis_data:/data

  # ワーカー (バックグラウンドジョブ)
  worker:
    build: ./backend
    command: celery -A tasks worker --loglevel=info
    environment:
      - REDIS_URL=redis://redis:6379
    depends_on:
      - redis
      - db

volumes:
  db_data:
  redis_data:

networks:
  default:
    name: myapp_network

開発ワークフロー

ボリュームを使用したホットリロード

Node.js

services:
  app:
    build: .
    volumes:
      - ./src:/app/src        # ソースコード同期
      - /app/node_modules     # コンテナの node_modules 上書き防止
    command: npm run dev
# Dockerfile.dev
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install  # 開発依存関係を含める
COPY . .
EXPOSE 3000
CMD ["npm", "run", "dev"]

Python (Django/FastAPI)

services:
  web:
    build: .
    volumes:
      - .:/app
    command: python manage.py runserver 0.0.0.0:8000
    # または FastAPI の場合:
    # command: uvicorn main:app --host 0.0.0.0 --reload

VS Code Dev Containers

.devcontainer/devcontainer.json:

{
  "name": "Python Dev Container",
  "dockerComposeFile": "../docker-compose.yml",
  "service": "app",
  "workspaceFolder": "/app",
  "customizations": {
    "vscode": {
      "extensions": [
        "ms-python.python",
        "ms-python.vscode-pylance"
      ],
      "settings": {
        "python.defaultInterpreterPath": "/usr/local/bin/python"
      }
    }
  },
  "postCreateCommand": "pip install -r requirements-dev.txt",
  "remoteUser": "vscode"
}

ローカルデータベースコンテナ

# PostgreSQL
docker run -d \
  --name dev-postgres \
  -e POSTGRES_PASSWORD=localdev \
  -e POSTGRES_DB=myapp_dev \
  -p 5432:5432 \
  -v pgdata:/var/lib/postgresql/data \
  postgres:15-alpine

# MySQL
docker run -d \
  --name dev-mysql \
  -e MYSQL_ROOT_PASSWORD=localdev \
  -e MYSQL_DATABASE=myapp_dev \
  -p 3306:3306 \
  -v mysqldata:/var/lib/mysql \
  mysql:8

# MongoDB
docker run -d \
  --name dev-mongo \
  -p 27017:27017 \
  -v mongodata:/data/db \
  mongo:7

# Redis
docker run -d \
  --name dev-redis \
  -p 6379:6379 \
  redis:7-alpine

本番パターン

ヘルスチェック

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .

# ヘルスチェックエンドポイント
HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \
  CMD node healthcheck.js

EXPOSE 3000
CMD ["node", "server.js"]
// healthcheck.js
const http = require('http');

const options = {
  host: 'localhost',
  port: 3000,
  path: '/health',
  timeout: 2000
};

const request = http.request(options, (res) => {
  if (res.statusCode === 200) {
    process.exit(0);
  } else {
    process.exit(1);
  }
});

request.on('error', () => process.exit(1));
request.end();

セキュリティベストプラクティス

FROM python:3.11-slim

# 1. 非root ユーザーを使用
RUN groupadd -r appuser && useradd -r -g appuser appuser

# 2. 依存関係を root として インストール
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# 3. アプリケーションファイルをコピー
COPY --chown=appuser:appuser . .

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

# 5. 不要な権限を削除
EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "app:app"]

追加のセキュリティ対策:

  • 最小限のベースイメージ (alpine、distroless) を使用
  • イメージの脆弱性をスキャン: docker scan myapp:latest
  • イメージにシークレットを含めない (環境変数またはシークレット管理ツールを使用)
  • ベースイメージを更新に保つ
  • 可能な限りルートファイルシステムを読み取り専用に

シークレット管理

# Docker Swarm シークレット (本番)
echo "db_password_here" | docker secret create db_password -
version: '3.8'
services:
  app:
    image: myapp
    secrets:
      - db_password
    environment:
      - DB_PASSWORD_FILE=/run/secrets/db_password

secrets:
  db_password:
    external: true

代替案: 環境ファイル

# docker-compose.yml
services:
  app:
    env_file:
      - .env.production  # このファイルはコミットしない
# .env.production (gitignore)
DATABASE_URL=postgresql://user:pass@db:5432/prod
SECRET_KEY=your-secret-key

リソースリミット

services:
  app:
    image: myapp
    deploy:
      resources:
        limits:
          cpus: '1.0'
          memory: 512M
        reservations:
          cpus: '0.5'
          memory: 256M
      restart_policy:
        condition: on-failure
        delay: 5s
        max_attempts: 3
# コマンドラインリソースリミット
docker run -d \
  --memory="512m" \
  --cpus="1.0" \
  --restart=unless-stopped \
  myapp

フレームワーク固有の例

Python: Django

FROM python:3.11-slim

ENV PYTHONUNBUFFERED=1
ENV PYTHONDONTWRITEBYTECODE=1

WORKDIR /app

# システム依存関係のインストール
RUN apt-get update && apt-get install -y \
    postgresql-client \
    && rm -rf /var/lib/apt/lists/*

# Python 依存関係のインストール
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションをコピー
COPY . .

# 静的ファイルを収集
RUN python manage.py collectstatic --noinput

# 非root ユーザーを作成
RUN useradd -m -u 1000 django && chown -R django:django /app
USER django

EXPOSE 8000
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "--workers", "4", "myproject.wsgi:application"]

docker-compose.yml:

version: '3.8'

services:
  web:
    build: .
    command: python manage.py runserver 0.0.0.0:8000
    volumes:
      - .:/app
    ports:
      - "8000:8000"
    environment:
      - DEBUG=1
      - DATABASE_URL=postgres://postgres:postgres@db:5432/django_dev
    depends_on:
      - db

  db:
    image: postgres:15-alpine
    environment:
      POSTGRES_PASSWORD: postgres
      POSTGRES_DB: django_dev
    volumes:
      - postgres_data:/var/lib/postgresql/data

volumes:
  postgres_data:

Python: FastAPI

FROM python:3.11-slim

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .

EXPOSE 8000

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]

Node.js: Next.js

# Next.js 用のマルチステージビルド
FROM node:18-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:18-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build

FROM node:18-alpine AS runner
WORKDIR /app

ENV NODE_ENV=production

RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001

COPY --from=builder /app/public ./public
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static

USER nextjs

EXPOSE 3000

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

next.config.js (スタンドアロン出力に必須):

module.exports = {
  output: 'standalone',
}

Node.js: Express

FROM node:18-alpine

WORKDIR /app

# 依存関係をインストール
COPY package*.json ./
RUN npm ci --only=production

# アプリケーションをコピー
COPY . .

# 非root ユーザーを作成
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser

EXPOSE 3000

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

TypeScript ビルド

# ビルドステージ
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json tsconfig.json ./
RUN npm ci
COPY src/ ./src/
RUN npm run build

# 本番ステージ
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist

EXPOSE 3000
CMD ["node", "dist/index.js"]

コンテナオーケストレーション基礎

Docker Swarm (組み込み)

# Swarm を初期化
docker swarm init

# スタックをデプロイ
docker stack deploy -c docker-compose.yml myapp

# サービスをスケール
docker service scale myapp_web=5

# サービスを更新 (ダウンタイムなし)
docker service update --image myapp:2.0 myapp_web

# スタックを削除
docker stack rm myapp

Kubernetes との比較

機能Docker ComposeDocker SwarmKubernetes
複雑さ
ユースケースローカル開発小規模クラスタ本番規模
セットアップ単一ファイル組み込み別途インストール
スケーリング手動自動自動 + 高度
HAなしありあり
エコシステム限定的Docker膨大

それぞれの使い分け:

  • Docker Compose: ローカル開発、シンプルなデプロイ
  • Docker Swarm: 小規模本番クラスタ、K8s より単純
  • Kubernetes: 大規模本番、マルチクラウド、高度なオーケストレーション

CI/CD 統合

GitHub Actions

# .github/workflows/docker.yml
name: Build and Push Docker Image

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

env:
  REGISTRY: ghcr.io
  IMAGE_NAME: ${{ github.repository }}

jobs:
  build:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      packages: write

    steps:
      - uses: actions/checkout@v3

      - 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=semver,pattern={{version}}
            type=sha

      - name: Build and push
        uses: docker/build-push-action@v4
        with:
          context: .
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}
          cache-from: type=gha
          cache-to: type=gha,mode=max

      - name: Run tests
        run: |
          docker run --rm ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} npm test

GitLab CI

# .gitlab-ci.yml
stages:
  - build
  - test
  - deploy

variables:
  DOCKER_DRIVER: overlay2
  IMAGE_TAG: $CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA

build:
  stage: build
  image: docker:latest
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
    - docker build -t $IMAGE_TAG .
    - docker push $IMAGE_TAG

test:
  stage: test
  script:
    - docker run --rm $IMAGE_TAG npm test

deploy:
  stage: deploy
  script:
    - docker pull $IMAGE_TAG
    - docker tag $IMAGE_TAG $CI_REGISTRY_IMAGE:latest
    - docker push $CI_REGISTRY_IMAGE:latest
  only:
    - main

コンテナのデバッグ

ログを表示

# ログをストリーム表示
docker logs -f container_name

# 最後の 100 行
docker logs --tail 100 container_name

# タイムスタンプ以降のログ
docker logs --since 2024-01-01T10:00:00 container_name

# タイムスタンプ付きで表示
docker logs -t container_name

# Docker Compose のログ
docker-compose logs -f service_name

実行中のコンテナでコマンドを実行

# インタラクティブシェル
docker exec -it container_name /bin/sh
# または
docker exec -it container_name /bin/bash

# 単一コマンドを実行
docker exec container_name ls -la /app

# 別のユーザーとして実行
docker exec -u root container_name apt-get update

コンテナを検査

# コンテナの完全な詳細
docker inspect container_name

# 特定フィールド (IP アドレス)
docker inspect -f '{{.NetworkSettings.IPAddress}}' container_name

# 環境変数
docker inspect -f '{{.Config.Env}}' container_name

# マウントされたボリューム
docker inspect -f '{{.Mounts}}' container_name

リソース使用状況

# リアルタイム統計
docker stats

# 単一コンテナ
docker stats container_name

# ストリーミングなし (1 回のスナップショット)
docker stats --no-stream

ネットワークのデバッグ

# ネットワークをリスト表示
docker network ls

# ネットワークを検査
docker network inspect bridge

# コンテナ間の接続テスト
docker exec container1 ping container2

# DNS 解決をチェック
docker exec container_name nslookup other_container

ビルド問題のデバッグ

# キャッシュなしでビルド
docker build --no-cache -t myapp .

# ビルド進行状況を表示
docker build --progress=plain -t myapp .

# 特定ステージをビルド
docker build --target builder -t myapp-builder .

# 中間レイヤーを検査
docker history myapp:latest

ローカル Docker パターン (mcp-browser、mcp-memory)

mcp-browser 開発 compose

  • docker-compose.yml はポート範囲 8875-8895mcp-server を実行し、オプションの chrome プロファイルに対応
  • コードマウントは読み取り専用 (./src:/app/src:ro) で永続ログと一時ボリュームあり
  • 環境デフォルト: MCP_DEBUG=trueMCP_LOG_LEVEL=DEBUGMCP_HOST=0.0.0.0MCP_PORT=8875
  • オプションプロファイル: chrome (ブラウザ) と tools (開発ツールコンテナ)

mcp-browser Dockerfile.dev

  • ARG PYTHON_VERSION=3.11watchdog + Playwright Chromium をインストール
  • パッケージをエディタブルモードでインストールし、python -m src.dev_runner を実行
  • 非root ユーザーと /health ヘルスチェック

mcp-memory 本番 Dockerfile

  • /opt/venv に venv を持つマルチステージビルドと python:3.11-slim
  • ランタイムはヘルスチェック用に curl をインストール、PYTHONPATH=/app を設定
  • 非root ユーザーと CMD ["python", "run_api_server.py"]/health チェック

トラブルシューティング

よくある問題

「ポートが既に使用されている」

# ポートを使用中のプロセスを見つける
lsof -i :3000
# または
netstat -tulpn | grep 3000

# プロセスを強制終了
kill -9 <PID>

# または別のホストポートを使用
docker run -p 3001:3000 myapp

「Docker デーモンに接続できない」

# Docker が実行中か確認
docker info

# Docker Desktop を再起動 (Mac/Windows)
# または
sudo systemctl restart docker  # Linux

# 権限を確認 (Linux)
sudo usermod -aG docker $USER
# ログアウトして再度ログイン

「デバイスに空きがない」

# 未使用のコンテナ、イメージ、ボリュームを削除
docker system prune -a --volumes

# ダングリングイメージのみ削除
docker image prune

# 停止中のコンテナを削除
docker container prune

# 未使用のボリュームを削除
docker volume prune

# ディスク使用状況をチェック
docker system df

「ビルドコンテキストが大きすぎる」

# .dockerignore を作成
cat > .dockerignore << EOF
node_modules/
.git/
*.log
dist/
coverage/
EOF

# 特定のコンテキストでビルド
docker build -f Dockerfile -t myapp ./src

コンテナが直ちに終了

# ログをチェック
docker logs container_name

# インタラクティブシェルで実行してデバッグ
docker run -it myapp /bin/sh

# entrypoint をオーバーライド
docker run -it --entrypoint /bin/sh myapp

# 終了コードをチェック
docker inspect -f '{{.State.ExitCode}}' container_name

コンテナ内で権限が拒否

# root として実行してデバッグ
docker exec -u root -it container_name /bin/sh

# 所有権を修正
docker exec -u root container_name chown -R appuser:appuser /app

# または Dockerfile で正しい権限でリビルド

パフォーマンス問題

ビルドが遅い

# BuildKit を使用 (高速化、キャッシング改善)
DOCKER_BUILDKIT=1 docker build -t myapp .

# マルチステージビルドでレイヤー削減
# 命令を変更頻度順に並べる
# 不要なファイルを .dockerignore で除外

メモリ使用率が高い

# メモリリミットを設定
docker run -m 512m myapp

# メモリをモニタリング
docker stats container_name

# アプリケーションのメモリリーク確認

ボリュームマウントが遅い (Mac/Windows)

# delegated 一貫性を使用 (Mac)
volumes:
  - ./src:/app/src:delegated

# または バインドマウントの代わりに名前付きボリュームを使用
volumes:
  - node_modules:/app/node_modules

ベストプラクティス

レイヤー最適化

  1. 変更頻度順に並べる: 最も頻度の低いものを最初に
  2. RUN コマンドを結合: レイヤー数を削減
  3. 同じレイヤーでクリーンアップ: 一時ファイルをすぐに削除
# 良い例
RUN apt-get update && apt-get install -y \
    package1 \
    package2 \
    && rm -rf /var/lib/apt/lists/*

# 悪い例 (3 つのレイヤーを作成、apt キャッシュがレイヤー 2 に残る)
RUN apt-get update
RUN apt-get install -y package1 package2
RUN rm -rf /var/lib/apt/lists/*

イメージサイズの削減

  1. Alpine イメージを使用: フル Linux の 5MB vs 100MB 以上
  2. マルチステージビルド: ビルドツールを最終イメージから除外
  3. 不要なファイルを削除: ドキュメント、例、テスト
  4. .dockerignore を使用: 開発ファイルを除外
# 前: 800MB
FROM node:18
COPY . .
RUN npm install
CMD ["node", "server.js"]

# 後: 120MB
FROM node:18-alpine
COPY package*.json ./
RUN npm ci --only=production
COPY server.js .
CMD ["node", "server.js"]

セキュリティチェックリスト

  • 信頼されたソースの公式ベースイメージを使用
  • イメージバージョンを正確に指定 (latest ではなく)
  • 非root ユーザーとして実行
  • イメージの脆弱性をスキャン
  • ベースイメージを更新に保つ
  • イメージにシークレットを埋め込まない
  • 可能な限りルートファイルシステムを読み取り専用に
  • 攻撃面を最小化 (alpine、distroless)
  • Docker Content Trust を有効化 (イメージ署名)

開発 vs 本番

開発:

FROM node:18
WORKDIR /app
COPY package*.json ./
RUN npm install  # 開発依存関係を含める
COPY . .
CMD ["npm", "run", "dev"]

本番:

FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY --from=builder /app/dist ./dist
USER node
CMD ["node", "dist/server.js"]

ログのベストプラクティス

# stdout/stderr にログを出力 (Docker が取得)
CMD ["node", "server.js"]  # 良い例

# ファイルにログを出力しない (コンテナ停止時に失われる)
CMD ["node", "server.js", ">", "app.log"]  # 悪い例
// アプリケーションログ
console.log('Info message');   // stdout
console.error('Error message'); // stderr

// 構造化ログを使用
console.log(JSON.stringify({
  level: 'info',
  timestamp: new Date().toISOString(),
  message: 'Request processed',
  requestId: '123'
}));

環境設定

# ビルド時変数に ARG を使用
ARG NODE_ENV=production
ENV NODE_ENV=$NODE_ENV

# ランタイム変数に ENV を使用
ENV PORT=3000
ENV LOG_LEVEL=info

# ランタイムでオーバーライド
# docker run -e PORT=8080 -e LOG_LEVEL=debug myapp

ヘルスチェック

HEALTHCHECK --interval=30s --timeout=3s --start-period=40s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1
# docker-compose.yml
services:
  app:
    image: myapp
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3000/health"]
      interval: 30s
      timeout: 3s
      retries: 3
      start_period: 40s

グレースフルシャットダウン

// Node.js 例
process.on('SIGTERM', () => {
  console.log('SIGTERM received, closing server...');
  server.close(() => {
    console.log('Server closed');
    process.exit(0);
  });
});
# exec フォーム使用でシグナル処理
CMD ["node", "server.js"]  # 良い例
CMD node server.js          # 悪い例 (/bin/sh でラップ、シグナル転送なし)

クイックリファレンス

必須コマンド

# イメージ
docker build -t name:tag .
docker pull image:tag
docker push image:tag
docker images
docker rmi image:tag

# コンテナ
docker run -d --name container image
docker ps                    # 実行中のコンテナ
docker ps -a                 # すべてのコンテナ
docker stop container
docker start container
docker restart container
docker rm container
docker logs -f container
docker exec -it container /bin/sh

# クリーンアップ
docker system prune -a       # 未使用リソースをすべて削除
docker container prune       # 停止中のコンテナを削除
docker image prune          # ダングリングイメージを削除
docker volume prune         # 未使用ボリュームを削除

# Compose
docker-compose up -d
docker-compose down
docker-compose logs -f
docker-compose exec service /bin/sh
docker-compose build

よく使うフラグ

# docker run フラグ
-d              # デタッチ (バックグラウンド)
-it             # インタラクティブで TTY
-p 8080:80      # ポートマッピング (ホスト:コンテナ)
--name myapp    # コンテナ名
-e VAR=value    # 環境変数
-v /host:/container  # ボリュームマウント
--network name  # ネットワークに接続
--rm            # 終了時にコンテナを削除
-m 512m         # メモリリミット
--cpus 1.0      # CPU リミット

Dockerfile 命令

FROM image:tag           # ベースイメージ
WORKDIR /path            # ワーキングディレクトリを設定
COPY src dst             # ファイルをコピー
ADD src dst              # コピー (URL/tar サポート)
RUN command              # コマンドを実行
ENV KEY=value            # 環境変数
EXPOSE port              # ポートをドキュメント化
CMD ["executable"]       # デフォルトコマンド
ENTRYPOINT ["exec"]      # コマンドプレフィックス
VOLUME /path             # マウントポイントを作成
USER username            # ユーザーを設定
ARG name=default         # ビルド引数
LABEL key=value          # メタデータ
HEALTHCHECK CMD command  # ヘルスチェック

まとめ

Docker コンテナ化は以下を提供します:

  • 一貫性: 開発から本番までの同一環境
  • 分離: アプリケーション間で依存関係が競合しない
  • ポータビリティ: Docker が実行できるあらゆる場所で動作 (クラウド、ローカル、CI)
  • 効率: VM 比で軽量、高速起動
  • スケーラビリティ: オーケストレーションでの簡単な水平スケーリング

主要ワークフロー:

  1. 開発: ホットリロードボリュームを使用した docker-compose
  2. CI/CD: イメージビルド、テスト、レジストリへのプッシュ
  3. 本番: イメージをプル、リソースリミットとヘルスチェック付きで実行

次のステップ:

  • イメージサイズ最適化のためのマルチステージビルドをマスター
  • ヘルスチェックとグレースフルシャットダウンを実装
  • ローカル開発用に docker-compose を設定
  • CI/CD パイプラインに Docker を統合
  • 本番規模用のオーケストレーション (Swarm または Kubernetes) を検討

ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ

詳細情報

作者
bobmatnyc
リポジトリ
bobmatnyc/claude-mpm-skills
ライセンス
MIT
最終更新
不明

Source: https://github.com/bobmatnyc/claude-mpm-skills / ライセンス: MIT

関連スキル

汎用DevOps・インフラ⭐ リポ 502

superpowers-streamer-cli

SuperPowers デスクトップストリーマーの npm パッケージをインストール、ログイン、実行、トラブルシューティングできます。ユーザーが npm から `superpowers-ai` をセットアップしたい場合、メールまたは電話でサインインもしくはアカウント作成を行いたい場合、ストリーマーを起動したい場合、表示されたコントロールリンクを開きたい場合、後で停止したい場合、またはソースコードへのアクセスなしに npm やランタイムの一般的な問題から復旧したい場合に使用します。

by rohanarun
汎用DevOps・インフラ⭐ リポ 493

catc-client-ops

Catalyst Centerのクライアント操作・監視機能 - 有線・無線クライアントのリスト表示・フィルタリング、MACアドレスによる詳細なクライアント検索、クライアント数分析、時間軸での分析、SSIDおよび周波数帯によるフィルタリング、無線トラブルシューティング機能を提供します。MACアドレスやIPアドレスでのクライアント検索、サイト別やSSID別のクライアント数集計、無線周波数帯の分布分析、Wi-Fi信号の問題調査が必要な場合に活用できます。

by automateyournetwork
汎用DevOps・インフラ⭐ リポ 39,967

ci-cd-and-automation

CI/CDパイプラインの設定を自動化します。ビルドおよびデプロイメントパイプラインの構築または変更時に使用できます。品質ゲートの自動化、CI内のテストランナー設定、またはデプロイメント戦略の確立が必要な場合に活用します。

by addyosmani
汎用DevOps・インフラ⭐ リポ 39,967

shipping-and-launch

本番環境へのリリース準備を行います。本番環境へのデプロイ準備が必要な場合、リリース前チェックリストが必要な場合、監視機能の設定を行う場合、段階的なロールアウトを計画する場合、またはロールバック戦略が必要な場合に使用します。

by addyosmani
OpenAIDevOps・インフラ⭐ リポ 38,974

linear-release-setup

Linear Releaseに向けたCI/CD設定を生成します。リリース追跡の設定、LinearのCIパイプライン構築、またはLinearリリースとのデプロイメント連携を実施する際に利用できます。GitHub Actions、GitLab CI、CircleCIなど複数のプラットフォームに対応しています。

by novuhq
Anthropic ClaudeDevOps・インフラ⭐ リポ 2,159

tracking-application-response-times

API エンドポイント、データベースクエリ、サービスコール全体にわたるアプリケーションのレスポンスタイムを追跡・最適化できます。パフォーマンス監視やボトルネック特定の際に活用してください。「レスポンスタイムを追跡する」「API パフォーマンスを監視する」「遅延を分析する」といった表現で呼び出せます。

by jeremylongshore
本サイトは GitHub 上で公開されているオープンソースの SKILL.md ファイルをクロール・インデックス化したものです。 各スキルの著作権は原作者に帰属します。掲載に問題がある場合は info@alsel.co.jp または /takedown フォームよりご連絡ください。
原作者: bobmatnyc · bobmatnyc/claude-mpm-skills · ライセンス: MIT