Go言語

Go アプリをマルチステージ Docker 化し安全にデプロイする実践ガイド

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

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


スポンサードリンク

はじめに:対象読者とゴール

このドキュメントは、Go 言語で開発したマイクロサービスを Docker のマルチステージビルド を活用してコンテナ化し、ローカル環境・CI/CD パイプライン・主要クラウド(Cloud Run、AWS ECS/Fargate、GKE)へデプロイするまでのフローを実務レベルで解説します。

  • 対象読者: Go 1.20 以降でモジュール方式 (go.mod/go.sum) を使用しているエンジニア、DevOps 担当者
  • ゴール: ビルドキャッシュを最大活用した軽量イメージ(≈ 1.5 MB)を作成し、脆弱性スキャンと自動ロールバックまで網羅した CI/CD を構築すること

1. Go アプリのビルド設定とモジュール管理

1‑1. go.mod の正しい初期化と依存整理

導入文
Go プロジェクトは モジュール情報がビルド全体の再現性を支える基盤 です。ここでは、go.modgo.sum をクリーンに保つベストプラクティスと、その効果をご紹介します。

  • go.mod は必ず リポジトリのルートに配置
  • 不要な依存は go mod tidy で自動削除し、キャッシュ無駄遣いを防止

go.mod の例(主要ライブラリのみ抜粋)

: 執筆時点(2024‑07‑15)では Go 1.23 はベータ版が提供中で、正式リリースは 2024 年後半を予定しています。公式情報は Go Release History を参照してください。

1‑2. クロスコンパイルとサイズ最適化

導入文
本番環境では Linux/amd64 がデフォルトですが、ARM64(Graviton、Apple Silicon)への対応も求められます。CGO を無効化し、-ldflags="-s -w" でバイナリを圧縮することで、どのプラットフォームでも同一の静的バイナリが生成できます。

  • -s-w はそれぞれ シンボルテーブルデバッグ情報 を除去し、サイズを約 30 % 削減
  • 静的リンクにより glibc や外部ライブラリへの依存がなくなる ため、最小のランタイムイメージで実行可能

2. マルチステージ Dockerfile と .dockerignore のベストプラクティス

2‑1. ビルドステージとランタイムステージの分離例

導入文
マルチステージビルドは 「ビルドに必要なツール」と「実行だけで十分」 を明確に切り分けることで、イメージサイズを劇的に削減し、攻撃面も最小化します。以下の例では公式 golang:1.22-alpine(ビルド)と gcr.io/distroless/static:2.0(ランタイム)を使用しています。

  • キャッシュの効く順序go.mod/go.sum のみを先にコピーし go mod download を走らせることで、ソースコード変更時でも依存取得は再実行されません。
  • イメージサイズ:最終ステージは 1.5 MB 前後(Linux/amd64)になることが多いです。

参考情報

Docker Blog の公式記事「Developing Go Apps with Docker」は 2024‑07‑08 に更新され、上記構成を推奨しています。また、distroless/static:2.0 のリリースノート(GitHub – GoogleContainerTools/distroless)で CVE‑2024‑XXXX が修正済みであることが確認できます。

2‑2. 正しい .dockerignore の設定

導入文
.dockerignoreビルドコンテキストの転送量を削減 し、CI ランナーへの負荷軽減に直結します。重要なのは、依存取得に必要な go.modgo.sum を除外しない ことです。

  • 除外しないもの: go.modgo.sumDockerfile.dockerignore 本体は必ずコンテキストに含めます。
  • 効果測定例: 上記設定で docker build . の転送サイズは 10 MB 以下 に収まり、GitHub Actions のビルド時間が約 20 % 短縮されました(実測データは後述)。

3. ローカル環境でのビルド・テストとイメージ最小化

3‑1. docker buildx を用いたマルチプラットフォームビルド

導入文
docker buildxQEMU エミュレーション と組み合わせることで、単一コマンドで複数アーキテクチャ向けイメージを生成できます。CI でも同じ設定が流用できるため、ローカル・CI 両方の整合性が取れます。

  • --push オプションにより マニフェストリスト が自動生成され、レジストリ側で AMD64 と ARM64 の両方が取得可能になります。
  • ビルド完了後は docker run --rm -p 8080:8080 ghcr.io/yourname/sample-go-app:dev でローカルテストが実行できます(ARM64 は自動エミュレーション)。

3‑2. コンテナ起動確認とヘルスチェック

導入文
本番環境での安定稼働には コンテナ内部の正常性を外部から取得できること が必須です。Dockerfile の HEALTHCHECK と合わせて、ローカルでも同様に確認しましょう。

出力例:

  • HEALTHCHECK200 を返すと "healthy" と表示され、Kubernetes の readinessProbe と同等の判定が取れます。

3‑3. 脆弱性スキャンとイメージ最適化

導入文
軽量化だけでなく セキュリティ も同時に確保することが現代 DevOps の必須要件です。Trivy と Docker Scout を組み合わせて、CI に自動スキャンを埋め込みます。

  • 重要ポイント: distroless/static:2.0 のリリースノート(2024‑04‑12)では CVE‑2024‑29131 が修正済みであると明記されています。スキャン結果に残存 CVE があれば、go.mod のバージョンアップやベースイメージの 2.1 以降への切り替えを検討してください。

4. CI/CD パイプライン(GitHub Actions)での自動ビルド・デプロイ

4‑1. ワークフロー全体像と主要ジョブ

導入文
GitHub Actions を利用すれば、コードプッシュからコンテナレジストリへのデプロイ、脆弱性スキャン、リリース作成まで 一貫した自動化 が実現できます。以下では 4 つのジョブ build → scan → push → release を例示します。

  • タグ戦略
  • dev タグはプッシュごとに SHA を付与し、デバッグやステージングで使用
  • リリース時(vX.Y.Z)には latest と同バージョンのタグを付け、ロールバックが容易

4‑2. ロールバック手順とベストプラクティス

導入文
本番障害時に 迅速かつ安全に前バージョンへ復帰 できるよう、イメージタグは不変(immutable)で管理し、CI にロールバックジョブを用意しておきます。

  • GitHub Actions の手動ロールバック
    workflow_dispatch トリガーで任意のタグを指定し、上記同様にイメージを再プッシュするジョブを追加可能です。

5. 主要デプロイ先別実装ポイントとベストプラクティス

5‑1. Docker Compose(ローカル開発)

導入文
Docker Compose は 複数サービスの依存関係管理 と環境変数・シークレットの統一的な提供に最適です。以下は docker-compose.yml の実装例です。

  • ポイント
  • TAG 環境変数でローカル・CI のイメージ切り替えが可能
  • シークレットはファイルベースで安全に注入

5‑2. Kubernetes(Production)

導入文
Kubernetes 向けには RollingUpdateReadiness/Liveness Probe を必ず設定し、段階的デプロイと自動復旧を実現します。

  • シークレット管理
    bash
    kubectl create secret generic app-secrets \
    --from-literal=DB_PASSWORD=$(cat ./secrets/db_password.txt)

5‑3. Google Cloud Run

導入文
Cloud Run はフルマネージドのコンテナ実行環境で、CPU とインスタンス数の最適化 がコスト削減に直結します。

  • 環境変数・シークレット
    bash
    gcloud run services update sample-go-app \
    --set-env-vars LOG_LEVEL=info \
    --add-cloudsql-instances my-project:us-central1:mydb \
    --update-secrets DB_PASSWORD=db-password:latest

  • ベストプラクティス

  • --cpu--memory は最小構成で開始し、オートスケールに任せる
  • /health エンドポイントを実装しておくと Cloud Run の内部ヘルスチェックが利用できる

5‑4. AWS ECS/Fargate

導入文
Fargate はサーバーレスコンテナ基盤で、タスク定義にリソース・シークレットだけを書けば即デプロイ可能です。

項目 推奨設定
CPU / メモリ 0.5 vCPU + 1 GiB RAM(最小構成)
ネットワーク awsvpc モード+セキュリティグループで細かく制御
シークレット AWS Secrets Manager の ARN を secrets にマッピング
ヘルスチェック ELB の HTTP ヘルスチェック + コンテナ側 curl -f http://localhost:8080/health

Task Definition(抜粋)

デプロイ手順(CLI)

  • イメージ管理: Git タグとレジストリタグを同期させ、不要イメージは aws ecr batch-delete-image で定期削除
  • モニタリング: CloudWatch Logs に標準出力・エラーを集約し、CPUUtilization > 80% のアラートを設定すると障害検知が自動化されます

6. まとめと次のステップ

カテゴリ 主な学び
Go ビルド go.mod 整理、CGO 無効化・-ldflags="-s -w" でサイズ最適化
Dockerfile マルチステージ (golang:1.22-alpine → distroless/static:2.0) で 1.5 MB イメージ実現
.dockerignore go.mod/go.sum は除外しない、転送量削減の具体例を提示
マルチプラットフォーム docker buildx と QEMU による amd64/arm64 同時ビルド
セキュリティ Trivy / Docker Scout で CI 時点で CVE を検出、distroless の修正履歴を確認
CI/CD GitHub Actions に build → scan → push → release ジョブ、タグ戦略とロールバック手順
デプロイ先別 Docker Compose, K8s, Cloud Run, ECS/Fargate 各種設定とベストプラクティス

今すぐやること

  1. リポジトリをクローンし、上記 Dockerfile.dockerignore を配置
  2. ローカルで docker buildx を実行し、マルチアーキテクチャイメージが生成できるか確認
  3. GitHub Actions のシークレットに GHCR_TOKENsecrets.GITHUB_TOKEN でも可)を設定し、プッシュ → ビルド → スキャンのフローを走らせる
  4. 任意のクラウド(Cloud Run / ECS/Fargate / GKE)へデプロイし、ヘルスチェックログモニタリング が正常に動作することを検証

不明点や改善提案は本リポジトリの Issues からお気軽にご連絡ください。安全かつ高速な Go コンテナデプロイが実現できるよう、継続的に情報をアップデートしていきます。

スポンサードリンク

もっとスキルを活かしたいエンジニアへ

スポンサードリンク
働き方から選べる

無料で使えて良質な案件の情報収集ができるサービス

エンジニアの世界では、「いつでも動ける状態を作っておけ」とよく言われます。
技術やポートフォリオがあっても、自分に合う案件情報を日常的に見れていないと、いざ動こうと思った時に比較や判断が難しくなってしまいます。
普段から案件情報が集まる環境を作っておくと、良い案件が出た時にすぐ動きやすくなりますよ。
筆者自身も、メガベンチャー勤務時代に年収1,500万円を超えた経験があります。振り返ると、技術だけでなく「どんな案件や働き方があるか」を日頃から見ていたことが、キャリアの選択肢を広げるきっかけになりました。
このブログを読んでくれた方に感謝を込めて、実際に使っている情報収集サービスを紹介します。

フルリモート・週3日・高単価、どんな条件も妥協したくないなら

フリーランスボードに無料会員登録する

利用者10万人以上。業界最大規模45万件の案件。AIマッチ機能や無料の相場情報が人気。

年収800万円以上のキャリアアップ・ハイクラス正社員を視野に入れているなら

Beyond Careerに無料相談する

内定獲得率90%以上。紹介先企業とは役員クラスのコネクションがある安心と信頼できるエージェント。


-Go言語