jpskill.com
🛠️ 開発・MCP コミュニティ

containerizing-applications

Containerizes applications with Docker, docker-compose, and Helm charts. Use when creating Dockerfiles, docker-compose configurations, or Helm charts for Kubernetes. Includes Docker Hardened Images (95% fewer CVEs), multi-stage builds, and 15+ battle-tested gotchas.

⚡ おすすめ: コマンド1行でインストール(60秒)

下記のコマンドをコピーしてターミナル(Mac/Linux)または PowerShell(Windows)に貼り付けてください。 ダウンロード → 解凍 → 配置まで全自動。

🍎 Mac / 🐧 Linux
mkdir -p ~/.claude/skills && cd ~/.claude/skills && curl -L -o containerizing-applications.zip https://jpskill.com/download/17292.zip && unzip -o containerizing-applications.zip && rm containerizing-applications.zip
🪟 Windows (PowerShell)
$d = "$env:USERPROFILE\.claude\skills"; ni -Force -ItemType Directory $d | Out-Null; iwr https://jpskill.com/download/17292.zip -OutFile "$d\containerizing-applications.zip"; Expand-Archive "$d\containerizing-applications.zip" -DestinationPath $d -Force; ri "$d\containerizing-applications.zip"

完了後、Claude Code を再起動 → 普通に「動画プロンプト作って」のように話しかけるだけで自動発動します。

💾 手動でダウンロードしたい(コマンドが難しい人向け)
  1. 1. 下の青いボタンを押して containerizing-applications.zip をダウンロード
  2. 2. ZIPファイルをダブルクリックで解凍 → containerizing-applications フォルダができる
  3. 3. そのフォルダを C:\Users\あなたの名前\.claude\skills\(Win)または ~/.claude/skills/(Mac)へ移動
  4. 4. Claude Code を再起動

⚠️ ダウンロード・利用は自己責任でお願いします。当サイトは内容・動作・安全性について責任を負いません。

🎯 このSkillでできること

下記の説明文を読むと、このSkillがあなたに何をしてくれるかが分かります。Claudeにこの分野の依頼をすると、自動で発動します。

📦 インストール方法 (3ステップ)

  1. 1. 上の「ダウンロード」ボタンを押して .skill ファイルを取得
  2. 2. ファイル名の拡張子を .skill から .zip に変えて展開(macは自動展開可)
  3. 3. 展開してできたフォルダを、ホームフォルダの .claude/skills/ に置く
    • · macOS / Linux: ~/.claude/skills/
    • · Windows: %USERPROFILE%\.claude\skills\

Claude Code を再起動すれば完了。「このSkillを使って…」と話しかけなくても、関連する依頼で自動的に呼び出されます。

詳しい使い方ガイドを見る →
最終更新
2026-05-18
取得日時
2026-05-18
同梱ファイル
3

📖 Skill本文(日本語訳)

※ 原文(英語/中国語)を Gemini で日本語化したものです。Claude 自身は原文を読みます。誤訳がある場合は原文をご確認ください。

アプリケーションのコンテナ化

クイックスタート

  1. まず影響分析を実行します(環境変数、ネットワークトポロジ、認証/CORS)。
  2. 以下のパターンを使用して Dockerfile を生成します。
  3. 適切なネットワーク構成で docker-compose.yml を作成します。
  4. Kubernetes 用に Helm チャートとしてパッケージ化します。

Dockerfile のパターン

FastAPI/Python (uv を使用したマルチステージ)

# syntax=docker/dockerfile:1
FROM python:3.13-slim AS builder
WORKDIR /app
RUN pip install uv
COPY pyproject.toml .
RUN uv pip install --system --no-cache -r pyproject.toml

FROM python:3.13-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY . .
RUN useradd -u 1000 appuser && chown -R appuser /app
USER appuser
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Next.js (スタンドアロン)

# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_SSO_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_SSO_URL=$NEXT_PUBLIC_SSO_URL
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

docker-compose のパターン

services:
  web:
    build:
      context: ./web
      args:
        # BROWSER: baked into JS bundle
        - NEXT_PUBLIC_API_URL=http://localhost:8000
    environment:
      # SERVER: read at runtime inside container
      - SERVER_API_URL=http://api:8000
    ports:
      - "3000:3000"
    depends_on:
      api:
        condition: service_healthy

  api:
    build: ./api
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - CORS_ORIGINS=http://localhost:3000,http://web:3000
    ports:
      - "8000:8000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Helm チャートの構造

helm/myapp/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   └── ingress.yaml

Chart.yaml

apiVersion: v2
name: myapp
version: 1.0.0
appVersion: "1.0.0"

values.yaml のパターン

api:
  replicaCount: 1
  image:
    repository: myapp/api
    tag: latest
    pullPolicy: IfNotPresent
  service:
    type: ClusterIP
    port: 8000
  resources:
    limits:
      cpu: 500m
      memory: 512Mi

Helm コマンド

helm create mychart              # 新しいチャートを作成
helm template . --debug          # テンプレートをレンダリング
helm install myapp ./chart       # インストール
helm upgrade myapp ./chart       # アップグレード
helm install myapp ./chart \
  --set api.image.tag=v2.0.0     # 値をオーバーライド

実戦で検証済みの落とし穴 (15+)

1. ブラウザ vs サーバーの URL

問題: ブラウザはホスト上で実行され、サーバーはコンテナ内で実行されます。

build:
  args:
    - NEXT_PUBLIC_API_URL=http://localhost:8000   # ブラウザ
environment:
  - SERVER_API_URL=http://api:8000                # サーバー

2. ヘルスチェックの IPv6 の問題

問題: wget http://localhost:3000 が IPv6 で失敗します。

healthcheck:
  test: ["CMD", "wget", "--spider", "http://127.0.0.1:3000/"]  # localhost ではない!

3. MCP サーバー 421 Misdirected Request

問題: FastMCP は Docker サービス名を拒否します。

transport_security = TransportSecuritySettings(
    allowed_hosts=["127.0.0.1:*", "localhost:*", "mcp-server:*", "0.0.0.0:*"]
)

4. SQLModel テーブルが作成されない

問題: create_all() の前にモデルがインポートされていません。

# create_all() の前にインポートする必要があります
from .models import User, Task, Project  # noqa: F401
SQLModel.metadata.create_all(engine)

5. データベースの移行順序

問題: Drizzle の db:push はスキーマにないテーブルを削除します。 解決策: postgres を起動 → Drizzle を実行 → その後 API を起動

6. uv ネットワークタイムアウト

RUN UV_HTTP_TIMEOUT=120 uv pip install --system --no-cache -r pyproject.toml

7. 構文ディレクティブの欠落

# syntax=docker/dockerfile:1    # 常に最初の行
FROM python:3.13-slim

8. コンテナ内の localhost

サーバー側には Docker サービス名 (api, web, sso) を使用し、localhost は使用しないでください。

9. 認証オリジン

ビルドする前に、信頼できるオリジンに Docker サービス名を追加します。

10. サービスの起動順序

depends_oncondition: service_healthy と共に使用します。

11. ヘルスチェックのタイミング

起動に時間がかかるアプリには、start_period (例: 40 秒) を使用します。

12. pgAdmin のメール検証

.local ドメインではなく、admin@example.com のような有効なメールを使用します。

13. 依存関係の Playwright

テストツールは devDependencies に保持します (300MB 以上の肥大化)。

14. MCP ヘルスチェック 406

ASGI ミドルウェアを介して個別の /health エンドポイントを追加します。

15. Helm のカンマ解析

カンマを含む値には、--set の代わりに values ファイルを使用します。

本番環境のセキュリティ

Docker Hardened Images (推奨)

コミュニティイメージよりも CVE が 95% 少ない です。Apache 2.0 の下で無料です。

# 以前: 不明な CVE を持つコミュニティイメージ
FROM python:3.12-slim

# 以降: Docker Hardened Image
FROM docker.io/docker/python:3.12-dhi

DHI の 5 つの柱: | 柱 | 得られるもの | |--------|--------------| | 最小限の攻撃対象領域 | CVE の 98% 削減 | | 100% 完全な SBOM | SPDX/CycloneDX 形式 | | SLSA ビルドレベル 3 | 検証済みの出所 | | OpenVEX | 機械可読な脆弱性ステータス | | Cosign 署名 | 暗号化された検証

(原文はここで切り詰められています)

📜 原文 SKILL.md(Claudeが読む英語/中国語)を展開

Containerizing Applications

Quick Start

  1. Run impact analysis first (env vars, network topology, auth/CORS)
  2. Generate Dockerfiles using patterns below
  3. Create docker-compose.yml with proper networking
  4. Package as Helm chart for Kubernetes

Dockerfile Patterns

FastAPI/Python (Multi-stage with uv)

# syntax=docker/dockerfile:1
FROM python:3.13-slim AS builder
WORKDIR /app
RUN pip install uv
COPY pyproject.toml .
RUN uv pip install --system --no-cache -r pyproject.toml

FROM python:3.13-slim
WORKDIR /app
COPY --from=builder /usr/local/lib/python3.13/site-packages /usr/local/lib/python3.13/site-packages
COPY . .
RUN useradd -u 1000 appuser && chown -R appuser /app
USER appuser
EXPOSE 8000
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000"]

Next.js (Standalone)

# syntax=docker/dockerfile:1
FROM node:20-alpine AS deps
WORKDIR /app
COPY package*.json ./
RUN npm ci

FROM node:20-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
ARG NEXT_PUBLIC_API_URL
ARG NEXT_PUBLIC_SSO_URL
ENV NEXT_PUBLIC_API_URL=$NEXT_PUBLIC_API_URL
ENV NEXT_PUBLIC_SSO_URL=$NEXT_PUBLIC_SSO_URL
RUN npm run build

FROM node:20-alpine AS runner
WORKDIR /app
ENV NODE_ENV=production
RUN addgroup -g 1001 -S nodejs && adduser -S nextjs -u 1001
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
COPY --from=builder /app/public ./public
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]

docker-compose Pattern

services:
  web:
    build:
      context: ./web
      args:
        # BROWSER: baked into JS bundle
        - NEXT_PUBLIC_API_URL=http://localhost:8000
    environment:
      # SERVER: read at runtime inside container
      - SERVER_API_URL=http://api:8000
    ports:
      - "3000:3000"
    depends_on:
      api:
        condition: service_healthy

  api:
    build: ./api
    environment:
      - DATABASE_URL=${DATABASE_URL}
      - CORS_ORIGINS=http://localhost:3000,http://web:3000
    ports:
      - "8000:8000"
    healthcheck:
      test: ["CMD", "curl", "-f", "http://127.0.0.1:8000/health"]
      interval: 30s
      timeout: 10s
      retries: 3
      start_period: 40s

Helm Chart Structure

helm/myapp/
├── Chart.yaml
├── values.yaml
├── templates/
│   ├── _helpers.tpl
│   ├── deployment.yaml
│   ├── service.yaml
│   ├── configmap.yaml
│   ├── secret.yaml
│   └── ingress.yaml

Chart.yaml

apiVersion: v2
name: myapp
version: 1.0.0
appVersion: "1.0.0"

values.yaml Pattern

api:
  replicaCount: 1
  image:
    repository: myapp/api
    tag: latest
    pullPolicy: IfNotPresent
  service:
    type: ClusterIP
    port: 8000
  resources:
    limits:
      cpu: 500m
      memory: 512Mi

Helm Commands

helm create mychart              # Create new chart
helm template . --debug          # Render templates
helm install myapp ./chart       # Install
helm upgrade myapp ./chart       # Upgrade
helm install myapp ./chart \
  --set api.image.tag=v2.0.0     # Override values

Battle-Tested Gotchas (15+)

1. Browser vs Server URLs

Problem: Browser runs on host, server runs in container

build:
  args:
    - NEXT_PUBLIC_API_URL=http://localhost:8000   # Browser
environment:
  - SERVER_API_URL=http://api:8000                # Server

2. Healthcheck IPv6 Issue

Problem: wget http://localhost:3000 fails with IPv6

healthcheck:
  test: ["CMD", "wget", "--spider", "http://127.0.0.1:3000/"]  # NOT localhost!

3. MCP Server 421 Misdirected Request

Problem: FastMCP rejects Docker service names

transport_security = TransportSecuritySettings(
    allowed_hosts=["127.0.0.1:*", "localhost:*", "mcp-server:*", "0.0.0.0:*"]
)

4. SQLModel Tables Not Created

Problem: Models not imported before create_all()

# MUST import before create_all()
from .models import User, Task, Project  # noqa: F401
SQLModel.metadata.create_all(engine)

5. Database Migration Order

Problem: Drizzle db:push drops tables not in schema Solution: Start postgres → Run Drizzle → Then start API

6. uv Network Timeout

RUN UV_HTTP_TIMEOUT=120 uv pip install --system --no-cache -r pyproject.toml

7. Missing Syntax Directive

# syntax=docker/dockerfile:1    # ALWAYS first line
FROM python:3.13-slim

8. localhost in Container

Use Docker service names (api, web, sso) for server-side, NOT localhost

9. Auth Origins

Add Docker service names to trustedOrigins BEFORE building

10. Service Startup Order

Use depends_on with condition: service_healthy

11. Health Check Timing

Use start_period (e.g., 40s) for apps that take time to start

12. pgAdmin Email Validation

Use valid email like admin@example.com, not .local domains

13. Playwright in Dependencies

Keep test tools in devDependencies (300MB+ bloat)

14. MCP Health Check 406

Add separate /health endpoint via ASGI middleware

15. Helm Comma Parsing

Use values file instead of --set for comma-containing values

Production Security

Docker Hardened Images (Recommended)

95% fewer CVEs than community images. Free under Apache 2.0.

# BEFORE: Community image with unknown CVEs
FROM python:3.12-slim

# AFTER: Docker Hardened Image
FROM docker.io/docker/python:3.12-dhi

Five Pillars of DHI: | Pillar | What You Get | |--------|--------------| | Minimal Attack Surface | 98% CVE reduction | | 100% Complete SBOM | SPDX/CycloneDX format | | SLSA Build Level 3 | Verified provenance | | OpenVEX | Machine-readable vuln status | | Cosign Signatures | Cryptographic verification |

Verify signatures:

cosign verify docker.io/docker/python:3.12-dhi

Read SBOM:

docker sbom docker.io/docker/python:3.12-dhi

Trivy Scanning (CI/CD)

- name: Scan for vulnerabilities
  run: trivy image --severity HIGH,CRITICAL --exit-code 1 ${{ env.IMAGE }}

Distroless Images (Alternative)

# Python - use gcr.io/distroless/python3-debian12
FROM gcr.io/distroless/python3-debian12
# No shell, no package manager, runs as nonroot by default

Multi-Arch Builds

- uses: docker/build-push-action@v5
  with:
    platforms: linux/amd64,linux/arm64  # Build for both
    cache-from: type=gha
    cache-to: type=gha,mode=max

BuildKit Secrets

# Mount secrets during build (never stored in layers)
RUN --mount=type=secret,id=npm_token \
    NPM_TOKEN=$(cat /run/secrets/npm_token) npm install

See references/production-security.md for full patterns.

Verification

Run: python scripts/verify.py

Related Skills

  • operating-k8s-local - Local Kubernetes with Minikube
  • deploying-cloud-k8s - Cloud Kubernetes deployment
  • scaffolding-fastapi-dapr - FastAPI patterns

References

同梱ファイル

※ ZIPに含まれるファイル一覧。`SKILL.md` 本体に加え、参考資料・サンプル・スクリプトが入っている場合があります。