Flutter Web アプリを Cloud Run にデプロイするまでのトライ記録(GCP + GitHub Actions + Docker)
概要
Flutter Web アプリを Google Cloud Run 上で動かす構成を構築し、GitHub Actions による CI/CD、自動ビルド、Cloud Build 連携、SSL対応などを含めた一連のデプロイ手順とトラブルシュートの記録です。
ゴール
- Flutter Web アプリをビルドし、Docker化して Cloud Run にデプロイ
- GitHub Actions を使って CI/CD を構築
- GCP サービスアカウントによる権限管理を構成
- Cloud Run で HTTPS によるアクセス確認
GCP 初期設定
プロジェクトと環境変数の設定
set PROJECT_ID="xxx"
gcloud config set project %PROJECT_ID%
必要なAPIの有効化
gcloud services enable \
run.googleapis.com \
cloudbuild.googleapis.com \
artifactregistry.googleapis.com
サービスアカウントの作成と鍵発行
gcloud iam service-accounts create github-actions-deployer \
--display-name="GitHub Actions Deployer"
gcloud iam service-accounts keys create key.json \
--iam-account=github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com
IAM ロールの付与
gcloud projects add-iam-policy-binding %PROJECT_ID% \
--member="serviceAccount:github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com" \
--role="roles/run.admin"
gcloud projects add-iam-policy-binding %PROJECT_ID% \
--member="serviceAccount:github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com" \
--role="roles/iam.serviceAccountUser"
gcloud projects add-iam-policy-binding %PROJECT_ID% \
--member="serviceAccount:github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com" \
--role="roles/cloudbuild.builds.editor"
gcloud projects add-iam-policy-binding %PROJECT_ID% \
--member="serviceAccount:github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com" \
--role="roles/storage.admin"
gcloud projects add-iam-policy-binding %PROJECT_ID% \
--member="serviceAccount:github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com" \
--role="roles/artifactregistry.writer"
gcloud projects add-iam-policy-binding %PROJECT_ID% \
--member="serviceAccount:github-actions-deployer@%PROJECT_ID%.iam.gserviceaccount.com" \
--role="roles/viewer"
GitHub Actions 連携と Cloud Build へのデプロイ
Dockerfile の作成(Flutter Web + nginx)
FROM ghcr.io/fluttercommunity/flutter:3.22.1 AS build
WORKDIR /app
COPY . .
RUN flutter pub get
RUN flutter build web
FROM nginx:stable-alpine
COPY default.conf /etc/nginx/conf.d/default.conf
COPY --from=build /app/build/web /usr/share/nginx/html
EXPOSE 8080
CMD ["nginx", "-g", "daemon off;"]
default.conf(nginx)
server {
listen 8080;
server_name localhost;
root /usr/share/nginx/html;
location / {
try_files $uri $uri/ /index.html;
}
}
GitHub Actions 内でのコマンド例
- name: Build and Submit Docker Image
run: |
gcloud builds submit app \
--tag gcr.io/${{ secrets.GCP_PROJECT }}/${{ secrets.SERVICE_NAME }}:${{ github.sha }}
- name: Deploy to Cloud Run
run: |
gcloud run deploy ${{ secrets.SERVICE_NAME }} \
--image gcr.io/${{ secrets.GCP_PROJECT }}/${{ secrets.SERVICE_NAME }}:${{ github.sha }} \
--region asia-northeast1 \
--platform managed \
--quiet \
--set-env-vars PA_API_ACCESS_KEY=${{ secrets.PA_API_ACCESS_KEY }},PA_API_SECRET_KEY=${{ secrets.PA_API_SECRET_KEY }}
トラブルと対処ログ
エラー1:PERMISSION_DENIED
サービスアカウントに Cloud Build 関連ロールが未付与だったため、
roles/cloudbuild.builds.editor
を追加して解決。
エラー2:invalid image name
SERVICE_NAME
が空で、Docker イメージ名として無効だった。
GitHub Secrets に正しい値を追加して解決。
エラー3:Cloud Run 起動失敗
The container failed to start and listen on the port defined by PORT=8080.
Flutter Web はポート待ち受けを行わないため、nginx を使いポート 8080 で静的配信して解決。
エラー4:NET::ERR_CERT_COMMON_NAME_INVALID
Cloud Run の自動SSL証明書がまだ有効化されておらず発生。
数分~30分程度で自動的に証明書が反映され、HTTPS接続が成功。
成果
- Flutter Web アプリを Cloud Run にホストし、HTTPSアクセス可能に
- GitHub Actions から Cloud Build 経由で Docker イメージをビルド・デプロイ