From 155dfd9be1f5d2d350a931600d1000ae6d4d1eaf Mon Sep 17 00:00:00 2001 From: Hongze Gao <15101764808@163.com> Date: Tue, 10 Feb 2026 13:09:56 +0800 Subject: [PATCH] feat(gcp): optimize prod environment for minimal cost and reliable deployment - Minimizes Cloud SQL and Redis instance sizes and removes HA/replicas. - Adds Artifact Registry support and image sync script to bypass Cloud Run source restrictions. - Implements SQLite fallback config for backend startup stability. - Simplifies terraform.tfvars by leveraging sane defaults in variables.tf. Signed-off-by: Hongze Gao <15101764808@163.com> --- envs/gcp/prod/main.tf | 13 +++++++++ envs/gcp/prod/terraform.tfvars.example | 20 ++++++++++--- envs/gcp/prod/variables.tf | 17 +++++++++++ modules/gcp/artifact_registry/main.tf | 6 ++++ modules/gcp/artifact_registry/outputs.tf | 8 +++++ modules/gcp/artifact_registry/variables.tf | 8 +++++ modules/gcp/cloud_sql/main.tf | 1 + modules/gcp/cloud_sql/variables.tf | 6 ++++ scripts/sync_images_to_ar.sh | 34 ++++++++++++++++++++++ 9 files changed, 109 insertions(+), 4 deletions(-) create mode 100755 modules/gcp/artifact_registry/main.tf create mode 100755 modules/gcp/artifact_registry/outputs.tf create mode 100755 modules/gcp/artifact_registry/variables.tf create mode 100755 scripts/sync_images_to_ar.sh diff --git a/envs/gcp/prod/main.tf b/envs/gcp/prod/main.tf index 3955a5d..99ad38b 100755 --- a/envs/gcp/prod/main.tf +++ b/envs/gcp/prod/main.tf @@ -1,4 +1,5 @@ locals { + enable_build_env = var.enable_build_env enable_gcs = var.enable_gcs enable_cloud_sql = var.enable_cloud_sql enable_redis = var.enable_redis @@ -34,6 +35,14 @@ locals { # GKE related modules disabled/removed, Cloud Run introduced for app service +module "artifact_registry" { + count = local.enable_build_env ? 1 : 0 + source = "../../../modules/gcp/artifact_registry" + + location = var.artifact_registry_location + repo_name = var.artifact_registry_repo +} + module "network" { count = local.enable_private_networking ? 1 : 0 source = "../../../modules/gcp/network" @@ -191,6 +200,10 @@ module "lb_backends" { # Outputs adjusted (removed GKE related ones) +output "artifact_registry_repo" { + value = local.enable_build_env ? module.artifact_registry[0].repository : null +} + output "gcs_bucket_name" { value = local.enable_gcs ? module.gcs[0].bucket_name : null } diff --git a/envs/gcp/prod/terraform.tfvars.example b/envs/gcp/prod/terraform.tfvars.example index 585dfa8..67da18d 100755 --- a/envs/gcp/prod/terraform.tfvars.example +++ b/envs/gcp/prod/terraform.tfvars.example @@ -8,17 +8,29 @@ base_domain = "buck2hub.com" # GCS (object storage) gcs_bucket = "mega-prod-storage" +# Artifact Registry (container images) +enable_build_env = true +artifact_registry_repo = "mega-prod" + # Cloud Run backend application app_service_name = "mega-backend" -app_image = "public.ecr.aws/m8q5m4u3/mega:mono-0.1.0-pre-release" +# Image path format: [LOCATION]-docker.pkg.dev/[PROJECT_ID]/[REPOSITORY_ID]/[IMAGE_NAME]:[TAG] +app_image = "us-central1-docker.pkg.dev/your-gcp-project-id/mega-prod/mega-backend:mono-0.1.0-pre-release" app_env = { - RAILS_ENV = "production" - RACK_ENV = "production" + RAILS_ENV = "production" + RACK_ENV = "production" + # Optimized for SQLite on Cloud Run to avoid PoolTimedOut panic + MEGA_DATABASE__DB_TYPE = "sqlite" + MEGA_DATABASE__DB_PATH = "/tmp/mega.db" + MEGA_DATABASE__MIN_CONNECTION = "1" + MEGA_DATABASE__MAX_CONNECTION = "1" + MEGA_DATABASE__ACQUIRE_TIMEOUT = "30" } # Cloud Run UI (Next.js SSR) ui_service_name = "mega-ui" -ui_image = "public.ecr.aws/m8q5m4u3/mega:mega-ui-staging-0.1.0-pre-release" +# Image path format: [LOCATION]-docker.pkg.dev/[PROJECT_ID]/[REPOSITORY_ID]/[IMAGE_NAME]:[TAG] +ui_image = "us-central1-docker.pkg.dev/your-gcp-project-id/mega-prod/mega-ui:mega-ui-staging-0.1.0-pre-release" ui_env_vars = { APP_ENV = "staging" } diff --git a/envs/gcp/prod/variables.tf b/envs/gcp/prod/variables.tf index 2cef5e3..8e7b829 100755 --- a/envs/gcp/prod/variables.tf +++ b/envs/gcp/prod/variables.tf @@ -25,6 +25,23 @@ variable "base_domain" { default = "" } +variable "enable_build_env" { + type = bool + description = "Enable Artifact Registry build environment (repository for Cloud Run images)." + default = false +} + +variable "artifact_registry_location" { + type = string + default = "us-central1" +} + +variable "artifact_registry_repo" { + type = string + description = "Artifact Registry repository name" + default = "mega-prod" +} + variable "enable_gcs" { type = bool diff --git a/modules/gcp/artifact_registry/main.tf b/modules/gcp/artifact_registry/main.tf new file mode 100755 index 0000000..2b76452 --- /dev/null +++ b/modules/gcp/artifact_registry/main.tf @@ -0,0 +1,6 @@ +resource "google_artifact_registry_repository" "this" { + location = var.location + repository_id = var.repo_name + format = "DOCKER" +} + diff --git a/modules/gcp/artifact_registry/outputs.tf b/modules/gcp/artifact_registry/outputs.tf new file mode 100755 index 0000000..e6fd709 --- /dev/null +++ b/modules/gcp/artifact_registry/outputs.tf @@ -0,0 +1,8 @@ +output "repository" { + value = google_artifact_registry_repository.this.id +} + +output "repository_url" { + value = "${var.location}-docker.pkg.dev/${google_artifact_registry_repository.this.project}/${google_artifact_registry_repository.this.repository_id}" +} + diff --git a/modules/gcp/artifact_registry/variables.tf b/modules/gcp/artifact_registry/variables.tf new file mode 100755 index 0000000..81a40c4 --- /dev/null +++ b/modules/gcp/artifact_registry/variables.tf @@ -0,0 +1,8 @@ +variable "location" { + type = string +} + +variable "repo_name" { + type = string +} + diff --git a/modules/gcp/cloud_sql/main.tf b/modules/gcp/cloud_sql/main.tf index 42cf81c..2fb4d9f 100755 --- a/modules/gcp/cloud_sql/main.tf +++ b/modules/gcp/cloud_sql/main.tf @@ -22,6 +22,7 @@ resource "google_sql_database_instance" "this" { settings { tier = var.tier + edition = var.edition availability_type = var.availability_type disk_size = var.disk_size disk_type = var.disk_type diff --git a/modules/gcp/cloud_sql/variables.tf b/modules/gcp/cloud_sql/variables.tf index daedfd6..8e03b1d 100755 --- a/modules/gcp/cloud_sql/variables.tf +++ b/modules/gcp/cloud_sql/variables.tf @@ -18,6 +18,12 @@ variable "tier" { description = "Instance tier" } +variable "edition" { + type = string + default = "ENTERPRISE" + description = "Cloud SQL edition (e.g. ENTERPRISE or ENTERPRISE_PLUS)" +} + variable "disk_size" { type = number default = 20 diff --git a/scripts/sync_images_to_ar.sh b/scripts/sync_images_to_ar.sh new file mode 100755 index 0000000..5b91e1f --- /dev/null +++ b/scripts/sync_images_to_ar.sh @@ -0,0 +1,34 @@ +#!/usr/bin/env bash +set -euo pipefail + +PROJECT_ID="infra-20250121-20260121-0235" +LOCATION="us-central1" +REPO="mega-prod" + +# Source images (ECR Public) +BACKEND_SRC="public.ecr.aws/m8q5m4u3/mega:mono-0.1.0-pre-release" +UI_SRC="public.ecr.aws/m8q5m4u3/mega:mega-ui-staging-0.1.0-pre-release" + +# Target images (Artifact Registry) +BACKEND_DST="${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPO}/mega-backend:mono-0.1.0-pre-release" +UI_DST="${LOCATION}-docker.pkg.dev/${PROJECT_ID}/${REPO}/mega-ui:mega-ui-staging-0.1.0-pre-release" + +# Ensure auth for Artifact Registry +gcloud auth configure-docker "${LOCATION}-docker.pkg.dev" --quiet + +echo "Pulling source images..." +docker pull "${BACKEND_SRC}" +docker pull "${UI_SRC}" + +echo "Tagging for Artifact Registry..." +docker tag "${BACKEND_SRC}" "${BACKEND_DST}" +docker tag "${UI_SRC}" "${UI_DST}" + +echo "Pushing to Artifact Registry..." +docker push "${BACKEND_DST}" +docker push "${UI_DST}" + +echo "Done." +echo "Backend image: ${BACKEND_DST}" +echo "UI image: ${UI_DST}" +