Contents
1️⃣ 前提条件と環境構築
1‑1. 必要なツールとインストール手順
| ツール | 推奨バージョン* | 主な取得先 / インストール方法 |
|---|---|---|
| Go | 1.22.x 以上(例: go1.22.5) |
https://go.dev/dl の OS に合ったアーカイブを展開し、PATH に追加 |
| Google Cloud SDK | 最新安定版(2026 年 4 月時点で 470.0.0 がリリースされていますが、gcloud version で確認してください) |
curl https://sdk.cloud.google.com | bash → インストール後に gcloud init |
| Docker Desktop (Mac/Windows) または Docker Engine (Linux, WSL2) | Docker Engine 24.x 系(Desktop の場合は同等の最新リリース) | https://www.docker.com/get-started からインストーラを取得。Linux は公式パッケージ (apt, dnf 等) を使用 |
* ※ バージョンはあくまで「2026 年時点で確認できた最新」ではなく、常に「最新安定版」を利用することが推奨です。
各ツールのバージョンは次のコマンドで確認できます。
|
1 2 3 4 |
go version # → go version go1.22.x linux/amd64 gcloud version # → Google Cloud SDK 470.0.0 docker --version # → Docker version 24.x.xx, build xxxxxxx |
ポイント
- バージョンが古い場合はgcloud components update、go install golang.org/dl/go@latest && go download等で更新してください。
- CI/CD 環境でも同一バージョンを使用すると「ローカルと本番の差異」からくるトラブルが減ります。
1‑2. Docker のコンテナモード(Linux コンテナ)設定
| OS | デフォルト状態 | 必要な操作 |
|---|---|---|
| macOS (Docker Desktop) | 「Use Linux containers」 が既定で有効 | Docker Desktop → Settings → General で確認 |
| Windows (Docker Desktop) | 同上 | 「Settings → General → Use the WSL 2 based engine」をオンにし、Linux コンテナが自動選択されます |
| Linux(Ubuntu, Debian, etc.) | Docker Engine が直接 Linux コンテナを実行 | 特別な設定は不要。ただし docker run --platform linux/amd64 … でアーキテクチャを明示すると安全です |
| WSL2 (Windows Subsystem for Linux) | Windows 側の Docker Desktop がエンジンとして機能 | WSL2 のディストリビューション内で docker version が表示されれば OK。Docker Desktop → Settings → Resources → WSL Integration で対象ディストリビューションを有効化 |
留意点
- Windows/macOS では「Windows コンテナ」モードに切り替えると Linux 用イメージが起動できません。必ず「Linux コンテナ」モードになっていることを確認してください。
- Linux ホスト上でdocker info | grep "Operating System"がUbuntu等となっていれば、Linux コンテナは既に使用中です。
2️⃣ GCP プロジェクト作成と認証設定
2‑1. 初期化とプロジェクト構成
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
# ① ログイン gcloud auth login # ② プロジェクト作成(任意の ID と名前) PROJECT_ID="go-cloudrun-demo-$(date +%s)" gcloud projects create $PROJECT_ID --name="Go Cloud Run Demo" # ③ 作業対象プロジェクトを設定 gcloud config set project $PROJECT_ID # ④ デフォルトリージョン(例: us-central1)を保存 gcloud config set run/region us-central1 |
2‑2. CI 用サービスアカウントと最小権限ロールの付与
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# サービスアカウント作成 SA_NAME="ci-runner" gcloud iam service-accounts create $SA_NAME \ --display-name="CI/CD Runner for Cloud Run" SA_EMAIL="${SA_NAME}@${PROJECT_ID}.iam.gserviceaccount.com" # 必要ロールの一括付与(最小権限を意識) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${SA_EMAIL}" \ --role="roles/run.admin" # Cloud Run の作成・更新 gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${SA_EMAIL}" \ --role="roles/artifactregistry.writer" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${SA_EMAIL}" \ --role="roles/secretmanager.secretAccessor" # デプロイ後に外部から呼び出すための invoker 権限(必須) gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${SA_EMAIL}" \ --role="roles/run.invoker" |
ロール表
| ロール | 用途 |
|---|---|
roles/run.admin |
Cloud Run のサービス作成・更新・削除 |
roles/artifactregistry.writer |
Artifact Registry へ Docker イメージを書き込み |
roles/secretmanager.secretAccessor |
Secret Manager からシークレット取得 |
roles/run.invoker |
他のリソースやユーザーが Cloud Run を呼び出す権限(必須) |
ベストプラクティス
- プロジェクト全体に付与するのではなく、対象サービス(例:hello-go) の IAM ポリシーに対してroles/run.invokerを個別に設定すると、権限が過剰になるリスクを低減できます。
3️⃣ シンプルな Go 「Hello World」アプリの実装とローカルテスト
3‑1. ソースコード(main.go)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
package main import ( "fmt" "log" "net/http" "os" ) func handler(w http.ResponseWriter, r *http.Request) { fmt.Fprintln(w, "Hello World from Go on Cloud Run!") } func main() { port := os.Getenv("PORT") if port == "" { port = "8080" // デフォルト } http.HandleFunc("/", handler) log.Printf("Listening on :%s", port) if err := http.ListenAndServe(":"+port, nil); err != nil { log.Fatalf("Server failed: %v", err) } } |
3‑2. ローカルでのビルド・実行手順
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# モジュール初期化(まだなら実施) go mod init example.com/helloworld # ビルドせずに直接実行(開発中は go run が便利) go run main.go & # → 背景で起動した PID が表示されるので、次のリクエストへ # 動作確認 curl http://localhost:8080 # => Hello World from Go on Cloud Run! # 終了(バックグラウンドジョブを停止) kill %1 |
ポイント
-PORT環境変数が未設定でもデフォルトで 8080 を使用するため、ローカルと本番の挙動に差異はありません。
- ログは標準出力へ出すことで Cloud Run の Cloud Logging に自動収集されます。
4️⃣ マルチステージ Dockerfile と Artifact Registry へのプッシュ
4‑1. 推奨 Dockerfile(マルチステージ & Distroless)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
# ---------- Build Stage ---------- FROM golang:1.22-alpine AS builder WORKDIR /src # 依存関係だけ先に取得してキャッシュを有効化 COPY go.mod go.sum ./ RUN go mod download # ソースコード全体をコピー COPY *.go ./ # 静的リンクで最小サイズのバイナリを作成 ENV CGO_ENABLED=0 GOOS=linux GOARCH=amd64 RUN go build -a -ldflags="-s -w" -trimpath -o server . # ---------- Runtime Stage ---------- FROM gcr.io/distroless/static:nonroot AS runtime WORKDIR /app COPY --from=builder /src/server . EXPOSE 8080 CMD ["./server"] |
4‑2. Artifact Registry 用リポジトリ作成
|
1 2 3 4 5 6 |
# Docker フォーマットのプライベートレジストリを us-central1 に作成 gcloud artifacts repositories create go-demo \ --repository-format=docker \ --location=us-central1 \ --description="Docker images for Go Cloud Run demo" |
4‑3. イメージビルド・プッシュ手順
|
1 2 3 4 5 6 7 8 9 10 11 12 |
# イメージタグは <region>-docker.pkg.dev/<PROJECT>/<REPO>/<IMAGE>:<TAG> IMAGE_TAG="us-central1-docker.pkg.dev/${PROJECT_ID}/go-demo/hello-go:${SHORT_SHA:-v1}" # ビルド docker build -t $IMAGE_TAG . # Docker が自動で取得できるように認証情報を設定 gcloud auth configure-docker us-central1-docker.pkg.dev # プッシュ docker push $IMAGE_TAG |
サイズ比較(参考)
-golang:1.22-alpineビルダーイメージ:≈ 350 MB
- 最終distroless/staticランタイム:≈ 15 MB (バイナリのみ)
5️⃣ Cloud Run へのデプロイと認証設定
5‑1. デプロイコマンド(最小構成)
|
1 2 3 4 5 6 7 |
gcloud run deploy hello-go \ --image=$IMAGE_TAG \ --region=us-central1 \ --platform=managed \ --port=8080 \ --allow-unauthenticated # パブリックにしたい場合。プライベートは省略。 |
オプション解説
---platform=managed: 完全マネージド環境(Cloud Run (fully managed))を使用。
---port=8080: コンテナがリッスンするポート。コード側で$PORTを参照しているので省略可能だが、明示すると可読性が上がります。
---allow-unauthenticated: 全員に公開。内部利用のみならこのフラグを外し、後述の IAM invoker 設定でアクセス制御します。
5‑2. デプロイ後の URL 確認とテスト
|
1 2 3 4 5 6 7 8 |
SERVICE_URL=$(gcloud run services describe hello-go \ --region us-central1 \ --format='value(status.url)') echo "Service URL: $SERVICE_URL" curl -s $SERVICE_URL # => Hello World from Go on Cloud Run! |
5‑3. IAM ベースのアクセス制御(最小権限で公開)
|
1 2 3 4 5 6 7 8 9 10 11 |
# 特定ユーザーだけに呼び出し権限を付与 gcloud run services add-iam-policy-binding hello-go \ --member="user:alice@example.com" \ --role="roles/run.invoker" \ --region=us-central1 # すべての社内ユーザーへ公開したい場合は Cloud Identity のグループを指定 gcloud run services add-iam-policy-binding hello-go \ --member="group:dev-team@example.com" \ --role="roles/run.invoker" |
ポイント
-roles/run.invokerが付与されていないと、認証済みユーザーでも 403 エラーが返ります。デプロイ時に--allow-unauthenticatedを外すだけでなく、IAM ポリシーの設定忘れにも注意してください。
6️⃣ GitHub と Cloud Build による CI/CD パイプライン構築
6‑1. リポジトリとビルド定義ファイル
(a) cloudbuild.yaml
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
steps: # ---------- Docker ビルド ---------- - name: 'gcr.io/cloud-builders/docker' args: - build - '-t' - us-central1-docker.pkg.dev/$PROJECT_ID/go-demo/hello-go:$SHORT_SHA - '.' # ---------- イメージプッシュ ---------- - name: 'gcr.io/cloud-builders/docker' args: - push - us-central1-docker.pkg.dev/$PROJECT_ID/go-demo/hello-go:$SHORT_SHA # ---------- Cloud Run デプロイ ---------- - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk' entrypoint: bash args: - '-c' - | gcloud run deploy hello-go \ --image=us-central1-docker.pkg.dev/$PROJECT_ID/go-demo/hello-go:$SHORT_SHA \ --region=us-central1 \ --platform=managed \ --allow-unauthenticated |
(b) Dockerfile は前節 4‑1 と同一のものをリポジトリに配置。
6‑2. Cloud Build 用サービスアカウントにロール付与
|
1 2 3 4 5 6 7 8 9 10 11 |
# デフォルトの Cloud Build SA CB_SA="service-${PROJECT_NUMBER}@gcp-sa-cloudbuild.iam.gserviceaccount.com" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${CB_SA}" \ --role="roles/artifactregistry.writer" gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:${CB_SA}" \ --role="roles/run.admin" |
6‑3. GitHub トリガー作成
|
1 2 3 4 5 6 7 8 |
gcloud beta builds triggers create github \ --name="go-cloudrun-ci" \ --repo-owner=yourorg \ --repo-name=go-cloudrun-demo \ --branch-pattern="^main$" \ --build-config=cloudbuild.yaml \ --description="Push to main → Build & Deploy" |
注意
- GitHub App のインストール時に「Read & Write」権限を付与し、Cloud Build がリポジトリへアクセスできるようにしてください。
6‑4. Secret Manager と Cloud Build の連携
|
1 2 3 4 5 6 7 8 |
# シークレット作成例(DB パスワード) printf "my-secret-pwd" | gcloud secrets create db-password \ --data-file=- --replication-policy="automatic" # ビルド時にシークレットを環境変数として注入 gcloud beta builds triggers update go-cloudrun-ci \ --set-secrets=db-password=projects/$PROJECT_ID/secrets/db-password:latest |
cloudbuild.yaml の Docker ビルドステップで --secret id=db-password,src=/secrets/db-password を付与すれば、Docker ビルド時にシークレットが安全に渡せます。
6‑5. モニタリングと可観測性
| サービス | 主な活用例 |
|---|---|
| Cloud Logging | コンテナの stdout/stderr が自動収集。gcloud logging read "resource.type=cloud_run_revision" で確認 |
| Error Reporting | パニックやスタックトレースをリアルタイム通知 |
| Cloud Monitoring | run.googleapis.com/request_count, cpu/utilization 等のメトリクスをダッシュボード化 |
| Alerting | エラーレートが一定閾値を超えたら Slack / Email へ通知 |
7️⃣ トラブルシューティングよくある質問
| 現象 | 原因例 | 解決策 |
|---|---|---|
Permission denied while trying to access Artifact Registry |
ビルド SA に roles/artifactregistry.writer が無い |
上記 6‑3 のロール付与コマンドを再実行 |
Port not exposed: container listening on 8080 but Cloud Run expects $PORT |
Dockerfile の EXPOSE が 8080 以外、またはコードが $PORT を読まない |
EXPOSE 8080 を残しつつ、Go コードで os.Getenv("PORT") を使用 |
| デプロイ後に 403 エラーが返る | roles/run.invoker がサービスアカウントまたはユーザーに付与されていない |
2‑2 のロール付与を確認、もしくは gcloud run services add-iam-policy-binding で追加 |
| CI ビルドがタイムアウトする | Artifact Registry のリージョンが違うか、ネットワーク制限あり | リージョンが一致しているか (us-central1) を再確認し、VPC Service Controls が有効なら例外設定 |
8️⃣ まとめ
- ツールは常に最新安定版 を使用し、バージョンはコマンドで確認。
- Docker は Linux コンテナモード(macOS/Windows の Desktop、Linux 本体、WSL2)を必ず有効化。
- IAM では
roles/run.invokerを忘れずに付与し、最小権限でアクセス制御。 - マルチステージ Dockerfile と Distroless ランタイムで イメージサイズ ≈15 MB に抑える。
gcloud run deployのフラグを正しく設定すれば、デプロイは 1 行コマンドで完了。- GitHub + Cloud Build の CI/CD パイプラインにより コード → ビルド → デプロイ が自動化され、Secret Manager・Logging・Monitoring による安全性と可観測性も確保できる。
これらの手順を踏めば、ローカル開発から本番環境へのデプロイまでスムーズに進められます。ぜひ実際のプロジェクトで試してみてください!