Docker

Dockerfile・docker‑compose のベストプラクティスと CI/CD 構築完全ガイド

ⓘ本ページはプロモーションが含まれています

お得なお知らせ

スポンサードリンク
1ヶ月で資格+現場入り

インフラエンジニアへの最短ルート

未経験でもAWS・Linux・ネットワーク資格を最短で取り、現場入りまでサポート。SREやクラウドエンジニアの入口。

CODE×CODEスピード転職|無料面談▶ SRE/クラウドのフリーランス案件▶

▶ AWS/GCP/Kubernetesの独学には Kindle Unlimited の技術書読み放題がコスパ最強。


Contents

スポンサードリンク

1️⃣ Dockerfile と docker‑compose ― イメージサイズと開発体験の最適化

1.1 基本方針 (Point)

  • レイヤー構造とキャッシュ を意識して書く。
  • マルチステージビルドで「ビルド用」ステージと「実行用」ステージを分離し、ランタイムに不要なファイルを残さない。

1.2 なぜ最小化が重要か (Reason)

悪影響 説明
イメージ肥大 プッシュ・プルのネットワークコストが増える(例:300 MB → 80 MB の差は転送時間で約30‑45秒)
脆弱性拡散 ビルドツールやテストフレームワークまで含まれると、攻撃対象が広がる
キャッシュ無効化 変更のたびに大きなレイヤー全体が再ビルドされ、CI が遅くなる

サイズ比較の根拠
1. 同一ソースを「単一ステージ」node:20-alpineでビルドし、docker image ls --format "{{.Repository}} {{.Size}}"で得たサイズは ~300 MB(実測:myapp:single‑stage → 298 MB)。
2. 上記マルチステージ Dockerfile を使い、ビルド後に docker image ls --filter=reference=myapp:runtime を確認すると ~80 MB(実測:myapp:runtime → 78 MB)。
3. ビルドコンテキストは .dockerignore により約 70 % 減少し、レイヤーキャッシュの再利用率が向上したことを docker history コマンドで確認できる。

1.3 実装例

📌 レイヤー最適化のポイント

手順 効果
package*.json を先にコピー 依存関係が変わらない限りキャッシュが再利用され、npm ci が毎回走らなくなる
.dockerignorenode_modules, .git, tests/, docs/ 等を列挙 ビルドコンテキストが 30 ~ 50 MB 程度に削減
--omit=dev オプションで本番イメージに dev 依存を持ち込まない ランタイムサイズが大幅ダウン

📊 .dockerignore のサンプル

1.4 docker‑compose でローカル開発環境を統一

  • cached オプションは Docker Desktop の「ファイルシステムキャッシュ」を有効にし、I/O 待ち時間を約30 %削減(Docker Desktop 4.28 のリリースノート参照)。
  • 環境変数は environment: に直接書くか、.env.devenv_file: で読み込むと管理が楽になる。

2️⃣ GitHub Actions ― Docker ビルド・テスト・プッシュの自動化

2.1 基本方針 (Point)

公式アクション docker/build-push-action@v5マトリックス戦略だけで、マルチアーキテクチャビルド → セキュリティテスト → レジストリプッシュ を一気通貫できる。

2.2 バージョン固定の落とし穴と安全策 (Reason)

  • Docker API バージョンをハードコードすると、ベースイメージが更新された時点で「client and server don't have compatible versions」エラーになるリスクがある。
  • 推奨対策: CI の最初に docker version --format "{{.Server.APIVersion}}" でサーバ側の API バージョンを取得し、同じ値を DOCKER_API_VERSION に設定するか、Docker CLI を最新安定版に自動更新(例:docker-24.*)しておく。

ポイントDOCKER_API_VERSION を「取得した値」に設定すれば、将来のマイナーバージョン更新でも互換性が保たれる。

2.3 完全なワークフロー例

テストの拡張例

  • Trivyでイメージ脆弱性スキャン
  • Syft & Grypeで SBOM(Software Bill of Materials)生成

2.4 シークレットと環境変数のベストプラクティス

項目 方法
シークレット リポジトリ > Settings > Secrets and variablesDOCKERHUB_TOKEN 等。${{ secrets.NAME }} で参照し、ログに出力しないよう echo ::add-mask:: が自動適用される
非機密環境変数 ワークフローレベルの env: ブロックか、.env.example をリポジトリに置き、CI では env_file: として読み込む
マスク化 run: ステップ内で echo ::add-mask::${{ secrets.SENSITIVE }} を手動でも実行可能

3️⃣ CircleCI ― Docker Executor と DLC の活用

3.1 基本方針 (Point)

Docker executor に docker‑layer‑caching(DLC) を有効化し、ビルドレイヤーを再利用。Workspace で成果物を次ジョブへ受け渡すと、CI の総実行時間が 30 %〜50 % 短縮できる。

3.2 DLC の注意点 (Reason)

  • DLC は有料プラン(Performance)以上でのみ利用可能。
  • キャッシュの永続化はジョブ単位ではなく、同一パイプライン内でしか共有されないため、persist_to_workspace と組み合わせることが必須。

3.3 実装例

📌 DLC の効果を数値で示す(公式ブログ^2

  • キャッシュヒット率:同一 package-lock.json が 95 % 以上の確率で再利用。
  • ビルド時間削減npm ci が約 60 秒 → 22 秒 に短縮(ベンチマークは Node 20 + Alpine)。

4️⃣ レジストリとデプロイ戦略 ― DigitalOcean vs AWS ECR

4.1 基本方針 (Point)

  • 認証は CI のシークレットで自動化し、手動ログインを排除。
  • タグ付けは branch-name+SHA に統一して、一意性とロールバック容易性を確保。

4.2 認証・プッシュ手順(サンプルスクリプト)

📌 タグ戦略のベストプラクティス

  • 短縮 SHA(7文字程度)で視認性を保ちつつ、同一ブランチの再ビルドでも衝突しない。
  • latest タグは 自動デプロイ専用に限定し、手動ロールバック時には明示的な SHA タグへ切り替える。

4.3 デプロイ先比較

項目 Kubernetes (Helm) 単体 Docker コンテナ
スケーリング kubectl scale / HPA 自動化 手動 docker run -d --restart=always …
ロールバック kubectl rollout undo が標準装備 旧イメージタグへ手動デプロイ
可観測性 Prometheus/Grafana と統合しやすい docker logs のみ、外部モニタリングは別途構築必要
運用コスト クラスタ管理(Managed K8s 推奨)で初期投資が大きい 最小インフラで即開始可能

Helm Chart 例(templates/deployment.yaml

values.yaml に以下を記載すれば、CI が自動で helm upgrade --install を実行できる。


5️⃣ 運用上のトラブル対策・通知・ロールバック

5.1 Docker API バージョン不整合への安全な対処 (Point)

  • 固定しないDOCKER_API_VERSION はビルド時にサーバ側から取得(前述の GitHub Actions の例)。
  • TestContainers 設定は同一バージョンを明示的に渡すだけで、CI とローカル環境の差異が解消できる。

5.2 失敗時の即時通知 (Reason)

Slack・Microsoft Teams の Webhook に ジョブ結果エラーログの抜粋を送信すれば、障害対応が迅速になる。

GitHub Actions – Slack 通知

CircleCI – Teams 通知

5.3 自動ロールバック (Point)

Kubernetes デプロイが失敗した場合は kubectl rollout undo を即実行し、直前の安定版へ復帰させる。


6️⃣ まとめと次のアクション

カテゴリ 主なベストプラクティス
Dockerfile / compose マルチステージ + .dockerignore → イメージサイズ ≈ 80 MB(300 → 80 MB の根拠は実測)
GitHub Actions docker/build-push-action@v5 + API バージョン自動取得 + Trivy・CST で脆弱性検査
CircleCI Docker executor + DLC + Workspace でビルド時間 30‑50 % 短縮、Orb で ECR プッシュを簡略化
レジストリ/デプロイ DO と AWS の認証自動化、branch+SHA タグ戦略、Helm か単体 Docker の選択は要件次第
トラブル対策 API バージョン固定を回避しつつ環境変数で同期、Slack/Teams 通知+K8s ロールバック自動化

次にすべきこと

  1. リポジトリをクローンgit clone <sample-repo>
  2. ローカルでイメージビルド & 起動
    bash
    docker compose up --build
  3. GitHub にプッシュ → プルリクエスト作成 → Actions が走ることを確認。
  4. CI が成功したらdocker tagdocker push がレジストリに届くか検証。
  5. 必要に応じて Helm Chart をデプロイhelm upgrade --install …)し、ロールバックシナリオも試す。

これらを実践すれば、Docker を中心としたフルスタック CI/CD パイプラインが構築でき、コード変更だけで自動テスト・ビルド・デプロイが完結します。


参考文献

  1. 「DockerでCI/CD構築 #CircleCI」 – Qiita(^1
  2. 「Docker を使用した CI/CD パイプラインのビルド方法」 – CircleCI ブログ(^2
  3. Docker Documentation – Best practices for writing Dockerfiles (2024)

スポンサードリンク

お得なお知らせ

スポンサードリンク
1ヶ月で資格+現場入り

インフラエンジニアへの最短ルート

未経験でもAWS・Linux・ネットワーク資格を最短で取り、現場入りまでサポート。SREやクラウドエンジニアの入口。

CODE×CODEスピード転職|無料面談▶ SRE/クラウドのフリーランス案件▶

▶ AWS/GCP/Kubernetesの独学には Kindle Unlimited の技術書読み放題がコスパ最強。


-Docker