1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FastAPI + React(Vite) をGCP(Cloud Run)にデプロイし、Cloud SQL / GCS / Cloud Build / 独自ドメインまで構築した手順まとめ

Posted at

FastAPI + React(Vite) のプロジェクトを、GCP上で以下の構成で運用できるところまで持っていった時の手順メモです。
実際のプロジェクトID/URL/秘密情報は プレースホルダに置き換えています。

この記事でやること

  • Backend: Cloud Run(FastAPI)
  • Frontend: Cloud Run(Nginxで静的配信)
  • DB: Cloud SQL for PostgreSQL(Private IP)
  • ストレージ: Cloud Storage(ロゴ画像のアップロード先)
  • CI/CD: Cloud Build(GitHubトリガーで自動デプロイ)
  • 独自ドメイン/HTTPS: Cloud Run ドメインマッピング(例:example.jp / api.example.jp

前提

  • GCPプロジェクト作成済み(例:<PROJECT_ID> / <PROJECT_NUMBER>
  • gcloud ログイン済み
  • リージョンは例として asia-northeast1
  • Dockerでローカル起動できること

構成図(Mermaid)

1. GCP初期設定

export PROJECT_ID="<PROJECT_ID>"
export REGION="asia-northeast1"

gcloud config set project "$PROJECT_ID"
gcloud config set run/region "$REGION"

API有効化

gcloud services enable \
  run.googleapis.com \
  cloudbuild.googleapis.com \
  artifactregistry.googleapis.com \
  secretmanager.googleapis.com \
  sqladmin.googleapis.com \
  compute.googleapis.com \
  servicenetworking.googleapis.com \
  iam.googleapis.com \
  logging.googleapis.com \
  monitoring.googleapis.com \
  vpcaccess.googleapis.com \
  deploymentmanager.googleapis.com

2. Artifact Registry(コンテナ保存先)

gcloud artifacts repositories create "<AR_REPO>" \
  --repository-format=docker \
  --location="$REGION"

3. Cloud SQL(PostgreSQL) + Private IP

インスタンス作成

gcloud sql instances create "<SQL_INSTANCE>" \
  --database-version=POSTGRES_15 \
  --tier="<DB_TIER>" \
  --region="$REGION"

VPC + Private Service Access + VPCコネクタ(Cloud Run→Cloud SQLをPrivate IPで接続)

gcloud compute networks create "<VPC_NAME>" --subnet-mode=custom
gcloud compute networks subnets create "<SUBNET_NAME>" \
  --network="<VPC_NAME>" --range="10.10.0.0/24" --region="$REGION"

gcloud compute addresses create "<PSA_RANGE>" \
  --global --purpose=VPC_PEERING --prefix-length=16 --network="<VPC_NAME>"

gcloud services vpc-peerings connect \
  --service=servicenetworking.googleapis.com \
  --network="<VPC_NAME>" \
  --ranges="<PSA_RANGE>"

gcloud sql instances patch "<SQL_INSTANCE>" \
  --network="projects/$PROJECT_ID/global/networks/<VPC_NAME>"

gcloud compute networks vpc-access connectors create "<VPC_CONNECTOR>" \
  --network="<VPC_NAME>" --region="$REGION" --range="10.8.0.0/28"

DB/ユーザー作成

gcloud sql databases create "<DB_NAME>" --instance="<SQL_INSTANCE>"
gcloud sql users create "<DB_USER>" --instance="<SQL_INSTANCE>" --password="<DB_PASSWORD>"

4. Secret Manager(DATABASE_URL)

DATABASE_URL は Secret Manager に入れて Cloud Run から参照します。
パスワードに += が入るとURLとして壊れる場合があるので、URLセーフな文字列推奨です。

DB_HOST="<CLOUD_SQL_PRIVATE_IP>"
DB_NAME="<DB_NAME>"
DB_USER="<DB_USER>"
DB_PASSWORD="<DB_PASSWORD>"

echo -n "postgresql://$DB_USER:$DB_PASSWORD@$DB_HOST:5432/$DB_NAME" \
| gcloud secrets create "<SECRET_DATABASE_URL>" --data-file=-

5. Cloud Storage(ロゴ保存先)

組織ポリシーでHMACキー作成が禁止されていたため、S3互換(HMAC)ではなく GCS SDKでアップロードする実装にしました。

export LOGO_BUCKET="<LOGO_BUCKET>"

gcloud storage buckets create "gs://$LOGO_BUCKET" \
  --location="$REGION" \
  --uniform-bucket-level-access

# ロゴが公開情報なら objectViewer を allUsers へ
gcloud storage buckets add-iam-policy-binding "gs://$LOGO_BUCKET" \
  --member="allUsers" \
  --role="roles/storage.objectViewer"

6. Cloud Run(backend)

実行用サービスアカウント作成(推奨)

RUN_SA="<RUN_SA_NAME>"
RUN_SA_EMAIL="$RUN_SA@$PROJECT_ID.iam.gserviceaccount.com"

gcloud iam service-accounts create "$RUN_SA" --display-name="Cloud Run SA"

gcloud secrets add-iam-policy-binding "<SECRET_DATABASE_URL>" \
  --member="serviceAccount:$RUN_SA_EMAIL" \
  --role="roles/secretmanager.secretAccessor"

gcloud storage buckets add-iam-policy-binding "gs://$LOGO_BUCKET" \
  --member="serviceAccount:$RUN_SA_EMAIL" \
  --role="roles/storage.objectAdmin"

ビルド&デプロイ

gcloud builds submit ./backend \
  --tag="$REGION-docker.pkg.dev/$PROJECT_ID/<AR_REPO>/backend:latest"

gcloud run deploy "<BACKEND_SERVICE>" \
  --image="$REGION-docker.pkg.dev/$PROJECT_ID/<AR_REPO>/backend:latest" \
  --region="$REGION" \
  --service-account="$RUN_SA_EMAIL" \
  --allow-unauthenticated \
  --port=8000 \
  --vpc-connector="<VPC_CONNECTOR>" \
  --vpc-egress=private-ranges-only \
  --set-secrets="DATABASE_URL=<SECRET_DATABASE_URL>:latest" \
  --update-env-vars="GCS_BUCKET=$LOGO_BUCKET,GCS_PUBLIC_BASE=https://storage.googleapis.com,GCS_LOGO_PREFIX=logos/"

7. マイグレーション(Cloud Run Job)

アプリ起動時に毎回マイグレーションは避け、Jobで実行します。

gcloud run jobs create "<MIGRATE_JOB>" \
  --image="$REGION-docker.pkg.dev/$PROJECT_ID/<AR_REPO>/backend:latest" \
  --region="$REGION" \
  --service-account="$RUN_SA_EMAIL" \
  --vpc-connector="<VPC_CONNECTOR>" \
  --vpc-egress=private-ranges-only \
  --set-secrets="DATABASE_URL=<SECRET_DATABASE_URL>:latest" \
  --command="alembic" --args="upgrade,head"

gcloud run jobs execute "<MIGRATE_JOB>" --region "$REGION" --wait

8. Cloud Run(frontend)

Viteの VITE_API_URL はビルド時に埋め込むため、Cloud Buildで --build-arg を渡してビルドします。

BACKEND_URL="https://<BACKEND_BASE_URL>"

gcloud builds submit ./frontend \
  --config=frontend/cloudbuild.yaml \
  --substitutions=_REGION="$REGION",_VITE_API_URL="$BACKEND_URL"

gcloud run deploy "<FRONTEND_SERVICE>" \
  --image="$REGION-docker.pkg.dev/$PROJECT_ID/<AR_REPO>/frontend:latest" \
  --region="$REGION" \
  --allow-unauthenticated \
  --port=8080

9. CI/CD(GitHub → Cloud Build Trigger)

backend/cloudbuild.yamlfrontend/cloudbuild.yaml を用意し、GitHub連携トリガーで自動デプロイします。

ハマりどころ

  • poetry.lock.gitignore していると、Cloud Build側で COPY poetry.lock が失敗する
    • !backend/poetry.lock を追加して、backendのlockはコミットする運用にする
  • Cloud Build実行SAが Cloud Run実行SAを使うには iam.serviceaccounts.actAs が必要
    • roles/iam.serviceAccountUser を付与
  • トリガーで build.service_account を指定している場合、ログ設定が必要になることがある
    • options.logging: CLOUD_LOGGING_ONLY / options.default_logs_bucket_behavior: REGIONAL_USER_OWNED_BUCKET を設定

10. 独自ドメイン/HTTPS(Cloud Runドメインマッピング)

例:

  • example.jp → frontend
  • api.example.jp → backend

Search Console(ドメイン所有権)確認後、Cloud Runのドメインマッピングが提示する A/CNAME をDNSへ設定します。

おわりに

Cloud Run + Cloud SQL + GCS + Cloud Build + 独自ドメインまで、比較的低い運用コストで本番運用できる構成になりました。
同様の構成を作る際の参考になれば幸いです。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?