Pre-Merge Validation for Metabase TCP Setup
Before merging the Metabase TCP-based setup changes, run these validation commands to ensure everything is configured correctly.
Quick Validation Script
Run the automated pre-merge validation script:
./scripts/validate-metabase-pre-merge.sh
This script checks:
- ✅ Dockerfile contains Cloud SQL Proxy installation
- ✅ Dockerfile has startup script with CLOUD_SQL_INSTANCES handling
- ✅ Workflow uses
MB_DB_HOST=localhostandMB_DB_PORT=5432 - ✅ Workflow includes
CLOUD_SQL_INSTANCESenvironment variable - ✅ Workflow does NOT use
--add-cloudsql-instances(we run proxy ourselves) - ✅ Connection string format is valid
- ✅ Cloud SQL instances exist and are RUNNABLE
- ✅ Service account has
roles/cloudsql.clientpermission
Manual Validation with gcloud
1. Validate Cloud SQL Instances
# Staging
gcloud sql instances describe metabase-db-staging \
--project=barto-dev \
--format="value(state)"
gcloud sql instances describe flowpos-db \
--project=barto-dev \
--format="value(state)"
# Production
gcloud sql instances describe metabase-db-production \
--project=barto-prod \
--format="value(state)"
gcloud sql instances describe flowpos-db-production \
--project=barto-prod \
--format="value(state)"
Expected output: RUNNABLE
2. Validate Service Account Permissions
# Staging
PROJECT_NUMBER="723334209984"
COMPUTE_SA="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
gcloud projects get-iam-policy barto-dev \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$COMPUTE_SA AND bindings.role:roles/cloudsql.client" \
--format="value(bindings.role)"
# Production
PROJECT_NUMBER="136147256555"
COMPUTE_SA="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
gcloud projects get-iam-policy barto-prod \
--flatten="bindings[].members" \
--filter="bindings.members:serviceAccount:$COMPUTE_SA AND bindings.role:roles/cloudsql.client" \
--format="value(bindings.role)"
Expected output: roles/cloudsql.client
3. Test Cloud SQL Proxy Connection Locally
Test that Cloud SQL Proxy can connect to the instances:
# Staging
./scripts/test-cloudsql-proxy-connection.sh staging
# Production
./scripts/test-cloudsql-proxy-connection.sh production
This will:
- Download Cloud SQL Proxy if needed
- Start the proxy on
localhost:5432 - Test the connection
- Keep the proxy running for manual testing
Press Ctrl+C to stop the script (proxy will continue running).
4. Validate Existing Service Configuration (if service exists)
# Staging
SERVICE_NAME="flowpos-metabase-staging"
REGION="us-central1"
PROJECT_ID="barto-dev"
# Get latest revision
LATEST_REVISION=$(gcloud run revisions list \
--service="$SERVICE_NAME" \
--region="$REGION" \
--project="$PROJECT_ID" \
--format="value(name)" \
--limit=1)
# Check environment variables
gcloud run revisions describe "$LATEST_REVISION" \
--region="$REGION" \
--project="$PROJECT_ID" \
--format="value(spec.template.spec.containers[0].env[?(@.name=='MB_DB_HOST')].value)"
gcloud run revisions describe "$LATEST_REVISION" \
--region="$REGION" \
--project="$PROJECT_ID" \
--format="value(spec.template.spec.containers[0].env[?(@.name=='MB_DB_PORT')].value)"
gcloud run revisions describe "$LATEST_REVISION" \
--region="$REGION" \
--project="$PROJECT_ID" \
--format="value(spec.template.spec.containers[0].env[?(@.name=='CLOUD_SQL_INSTANCES')].value)"
# Check that Cloud SQL annotation is NOT set
gcloud run revisions describe "$LATEST_REVISION" \
--region="$REGION" \
--project="$PROJECT_ID" \
--format="value(spec.template.metadata.annotations['run.googleapis.com/cloudsql-instances'])"
# Check that VPC connector is NOT set
gcloud run revisions describe "$LATEST_REVISION" \
--region="$REGION" \
--project="$PROJECT_ID" \
--format="value(spec.template.metadata.annotations['run.googleapis.com/vpc-access-connector'])"
Expected values:
MB_DB_HOST:localhostMB_DB_PORT:5432CLOUD_SQL_INSTANCES:barto-dev:us-central1:metabase-db-staging,barto-dev:us-central1:flowpos-db(or production equivalents)- Cloud SQL annotation: (empty)
- VPC connector: (empty)
5. Full Validation Script
Run the comprehensive validation script:
./scripts/validate-metabase-setup.sh
This checks both staging and production environments.
What Changed
Before (Unix Sockets - Not Supported by Metabase)
- Used
--add-cloudsql-instancesannotation - Set
MB_DB_HOSTto Unix socket path (/cloudsql/...) - Did NOT set
MB_DB_PORT - Result: Metabase constructed invalid JDBC URL
After (TCP via Cloud SQL Proxy)
- Run Cloud SQL Proxy in container (TCP mode on
localhost:5432) - Set
MB_DB_HOST=localhost - Set
MB_DB_PORT=5432 - Set
CLOUD_SQL_INSTANCESenvironment variable - Do NOT use
--add-cloudsql-instancesannotation - Result: Metabase connects via standard TCP connection
Key Files Changed
-
deploy/gcp/metabase.Dockerfile- Installs Cloud SQL Proxy
- Creates startup script that runs proxy in TCP mode
- Starts Metabase after proxy is ready
-
.github/workflows/deploy-metabase.yml- Sets
MB_DB_HOST=localhost - Sets
MB_DB_PORT=5432 - Sets
CLOUD_SQL_INSTANCESenvironment variable - Removes
--add-cloudsql-instancesannotation
- Sets
Troubleshooting
If validation fails:
-
Cloud SQL instances not RUNNABLE
gcloud sql instances list --project=barto-dev -
Service account missing permissions
PROJECT_NUMBER="723334209984"
COMPUTE_SA="${PROJECT_NUMBER}-compute@developer.gserviceaccount.com"
gcloud projects add-iam-policy-binding barto-dev \
--member="serviceAccount:$COMPUTE_SA" \
--role="roles/cloudsql.client" -
Dockerfile syntax errors
docker build -f deploy/gcp/metabase.Dockerfile -t test-metabase . -
Workflow YAML syntax errors
# Check YAML syntax
yamllint .github/workflows/deploy-metabase.yml
Next Steps
After validation passes:
- ✅ Merge the PR
- ✅ GitHub Actions will automatically deploy
- ✅ Monitor deployment logs
- ✅ Verify Metabase connects successfully