docker-development について
docker-developmentは、Docker開発とCIの実践ガイドです。イメージ構築、セキュリティ、キャッシュ、Compose、テストのトラブルシューティングを扱い、短い例とテーマ別資料でコンテナ開発の課題に対応します。
主な機能
- 01Node.jsとGoのマルチステージビルド例
- 02イメージとコンテナのセキュリティ指針
- 03ビルドキャッシュとDocker Bakeの解説
- 04Composeのライフサイクルと設定の要点
- 05CIテストのパターンと問題解決
- 06テーマ別リファレンスの一覧
活用シーン
- 01Node.jsやGoサービスのマルチステージイメージ設計
- 02コンテナ設定の秘密情報や権限リスクの確認
- 03依存関係レイヤーの順序によるビルドキャッシュ改善
- 04Composeのサービス動作やCIテストのトラブル対応
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ netresearch/ docker-development-skill --skill docker-developmentインストール後、Claude Code で/docker-developmentを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
checkpoints.yamlreferences/bake-ci-cache.mdbind-mount-ownership.mdbuild-secret-leaks.mdci-testing.mdcompose-runtime-lifecycle.mddatabase-container-readiness.mddind-testing-patterns.mdengine-and-image-upgrades.mdgpg-verification.mdimage-ca-trust.mdmulti-stage-caching.mdphp-fpm-worker-starvation.mdregistry-catalogue-and-pin-rot.md詳細
Docker 開発
基本原則
- 最小限 — Alpine/distroless、マルチステージ
- セキュア — 非 root の
USER、レイヤーにシークレットを含めない、バージョンを固定 - テスト可能 — エントリーポイントのバイパス、DNS のモック
- キャッシュ効率 — 依存関係を先に処理し、同じレイヤー内でクリーンアップ
クイックリファレンス
マルチステージビルド(Node.js)
FROM node:24-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
FROM node:24-alpine
RUN addgroup -g 1001 app && adduser -u 1001 -G app -D app
USER app
COPY --from=builder /app .
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
CMD wget -qO- http://localhost:3000/health || exit 1
CMD ["node", "server.js"]
マルチステージビルド(Go — scratch/distroless)
FROM golang:1.26-alpine AS builder
WORKDIR /app
COPY go.* ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 go build -o /app/server .
FROM gcr.io/distroless/static:nonroot
COPY --from=builder /app/server /server
CMD ["/server"]
レイヤーの最適化
RUN apt-get update && \
apt-get install -y --no-install-recommends curl && \
rm -rf /var/lib/apt/lists/*
ビルドキャッシュ:依存関係のファイルを先にコピー
COPY package*.json ./
RUN npm ci
COPY . .
マニフェストをソースより先にコピーすると、インストールレイヤーのキャッシュが保持されます。
BuildKit シークレット
RUN --mount=type=secret,id=ssh_key,dst=/root/.ssh/id_rsa git clone [email protected]:org/repo.git
ARG は docker history と SLSA provenance に漏えいします — references/build-secret-leaks.md
Docker Bake(マルチプラットフォーム)
target "app" {
platforms = ["linux/amd64", "linux/arm64"]
}
CI ビルドは Bake と netresearch/.github/.github/workflows/build-container-bake.yml@main を経由します。イメージは 1 つでも複数でも構いません。再利用可能なワークフローがターゲットごとに GHA キャッシュを追加するため、HCL ではキャッシュを宣言しません。定期的な再ビルドでは cache: false を渡します — references/bake-ci-cache.md
セキュリティ上のアンチパターン
| アンチパターン | 修正方法 |
|---|---|
FROM image:latest | バージョンを固定します:image:1.2.3-alpine |
USER ディレクティブがない | adduser + USER appuser |
chmod 777 | 特定の権限を指定します:chmod 550 |
compose の privileged: true | 削除するか、特定の cap_add を使用します |
volumes: [/:/host] | 必要なパスのみをマウントします |
ports: ["0.0.0.0:3000:3000"] | 127.0.0.1:3000:3000 にバインドします |
ENV DB_PASSWORD=secret | --mount=type=secret または compose のシークレットを使用します |
CI テストでの注意点
- エントリーポイントをバイパスする:
docker run --rm --entrypoint php myimage -v - 上流 DNS をモックする:
docker run --rm --add-host backend:127.0.0.1 nginx-image nginx -t - Compose の検証:
docker compose configの前にcp .env.example .envを実行します - シークレットスキャン:
.env.example、README、ドキュメントを除外します - root 所有のアーティファクト:ディレクトリをバインドマウントします(
EACCES)—references/bind-mount-ownership.md
.dockerignore
除外対象:.git、node_modules/vendor、.env*、*.pem、*.key
Compose の基本事項
- 起動順序:
depends_on.condition: service_healthy+healthcheckのstart_period networks.internal: trueでデータベースを隔離しますprofiles: [debug]:--profile debugを指定した場合のみ起動します。downと--remove-orphansは無効なプロファイルのコンテナーを対象にしないため、停止対象のまま有効化をやめたサービスは動作し続けます —docker compose --profile '*' down、またはdocker compose down <service>(references/compose-runtime-lifecycle.md)- ログドライバーはデフォルトでブロッキング動作です:リモートエンドポイント(
awslogsなど)が停止すると、アプリの書き込みも停止します。mode: non-blocking+max-buffer-sizeを指定すると、代わりにログ行を破棄します。これで保護されるのは実行中のコンテナーのみです(references/compose-runtime-lifecycle.md) - イメージ参照の共有:ファイルごとに、トップレベルの拡張フィールドとアンカーで一度だけ定義します —
x-app-image: &app-image registry/app:${APP_IMAGE_VERSION:-85}。サービスではimage: *app-imageを使用します。このフィールドはservices:より上に置く必要があります — エイリアスが有効なのは、ドキュメント内でアンカーの後にある場合のみです。:-のデフォルト値は、未設定の変数と空の変数の両方に適用されます(タグを省略すると、何も通知されないまま:latestに解決されます)。アンカーはファイル内でのみ有効です。オーバーレイファイルごとに、それぞれアンカーを定義する必要があります。両方の方法で確認します:APP_IMAGE_VERSION= docker compose configと、オーバーライドを指定した場合
参考資料
references/bake-ci-cache.md-- 共通の Bake 再利用可能ワークフロー、Compose ファイルと同じ場所にある-f docker-bake.hcl、ターゲットごとの GHA キャッシュスコープ、キャッシュを使わずに定期的に再ビルドしながらキャッシュには書き込む方法、bake-action のディレクトリにあるヘルパーステップreferences/ci-testing.md-- Docker イメージの CI テストパターン、-c文字列での busybox のshと bash の違い、docker compose runをtimeoutで囲むと PID 1 がシグナルを無視した場合にコンテナが実行中のままになることreferences/dind-testing-patterns.md-- Docker-in-Docker のテストパターンreferences/bind-mount-ownership.md-- bind mount の成果物が root 所有になる問題、親パスにある tmpfs がその下のボリュームを隠す問題references/gpg-verification.md-- gpgv のパターン、古い keybox ロックreferences/registry-catalogue-and-pin-rot.md-- カタログのプローブ、ピンの陳腐化references/build-secret-leaks.md-- provenance 内のARGreferences/php-fpm-worker-starvation.md-- keepalive が php-fpm を占有する問題references/engine-and-image-upgrades.md--MinAPIVersionによってソケット読み取りサイドカーが遮断される問題、プローブコンテナによるアップグレードチェック、ベースイメージのUSERの変更、PHP 8.5 で OPcache がコアに組み込まれたことreferences/database-container-readiness.md-- シード済み DB イメージがready for connectionsを2回ログに出すこと、ログではなくシードデータを検証することreferences/compose-runtime-lifecycle.md-- 無効なプロファイルのコンテナがdownとup --remove-orphansの後も残ること、ブロッキングとノンブロッキングのログ配信、およびノンブロッキングでは防げないことreferences/image-ca-trust.md-- CA が侵害された後に、公開イメージのca-certificatesのバージョンとルート証明書のサブジェクトを確認すること、バンドル内の CA 名をgrepしても必ず0が返ること
コメント
Markdown 対応