Skip to main content

Bilko Stage Environment — Cloud Run Services (Phase 2)

Overview

MC: #10177 Phase 2  |  Deployed: 2026-04-30  |  Git SHA: 1f48fdc  |  Status: LIVE, healthy

GCP Project: tribal-sign-487920-k0  |  Region: europe-north1

WARNING — TD-3 PROD CUTOVER BLOCKER (MC #10241): bilko-staging-db uses public IP (0.0.0.0/0 authorized network, requireSsl=false). Acceptable for stage only. MUST NOT be replicated to production. Production deploy is blocked until Cloud SQL private IP + VPC connector is configured.

Live Services

ServiceURLImageMin/MaxMemoryStatus
bilko-api-stagebilko-api-stagebilko/api:stage-1f48fdc0/2512Mi, CPU 1LIVE
bilko-web-stagebilko-web-stagebilko/web:stage-1f48fdc0/2512Mi, CPU 1LIVE

Full Artifact Registry prefix: europe-north1-docker.pkg.dev/tribal-sign-487920-k0/

bilko-api-stage Detail

FieldValue
DockerfileDockerfile.api-kotlin (Kotlin/Ktor, port 4001)
JAVA_OPTSHikariCP connection pool tuned
Cloud SQLtribal-sign-487920-k0:europe-north1:bilko-staging-db via direct TCP 35.228.33.112:5432 (TD-2 + TD-3)
Secretsbilko-staging-db-password, bilko-jwt-secret, bilko-jwt-refresh-secret, bilko-staging-field-encryption-key (NEW, ADR-014), bilko-staging-field-hmac-key (NEW, ADR-014)
SA[email protected]
SA rolescloudsql.client, secretmanager.secretAccessor
SmokeGET /api/v1/health → 200 {"status":"ok","service":"bilko-api","version":"1.0.0"}
Revisionbilko-api-stage-00001-5x8 (100% traffic)

bilko-web-stage Detail

FieldValue
Dockerfileapps/web/Dockerfile (Next.js 15)
NEXT_PUBLIC_API_URLhttps://bilko-api-stage-dh4m46blja-lz.a.run.app/api/v1
NEXT_PUBLIC_APP_ENVstage
SmokeGET / → 200 (HTML, lang=sr-Latn)
Revisionbilko-web-stage-00001-c45 (100% traffic)
Build noteFresh npm install (no lockfile) — workaround TD-1 MC #10239

Smoke Test Commands

# API health (expected: {"status":"ok","service":"bilko-api","version":"1.0.0"})
curl -s https://bilko-api-stage-dh4m46blja-lz.a.run.app/api/v1/health

# Web root (expected: HTTP 200)
curl -s -o /dev/null -w "HTTP %{http_code}" https://bilko-web-stage-dh4m46blja-lz.a.run.app

Stage Rollback

# List revisions
gcloud run revisions list --service bilko-api-stage --project=tribal-sign-487920-k0 --region=europe-north1

# Route to prior revision
gcloud run services update-traffic bilko-api-stage --project=tribal-sign-487920-k0 --region=europe-north1 --to-revisions=REVISION_NAME=100

Stage Redeploy (image update only)

gcloud run services update bilko-api-stage --project=tribal-sign-487920-k0 --region=europe-north1 --image=europe-north1-docker.pkg.dev/tribal-sign-487920-k0/bilko/api:NEW_TAG
gcloud run services update bilko-web-stage --project=tribal-sign-487920-k0 --region=europe-north1 --image=europe-north1-docker.pkg.dev/tribal-sign-487920-k0/bilko/web:NEW_TAG

Phase 2 Tech Debt Tracker

IDMCDescriptionSeverityBlocks
TD-1#10239package-lock.json macOS arm64 missing linux-x64 native bins — fresh npm install workaroundMediumClean stage re-deploys
TD-2#10240postgres-socket-factory not in build.gradle.kts — Kotlin API uses direct TCP public IPMediumSecure DB connectivity
TD-3#10241bilko-staging-db: 0.0.0.0/0 + requireSsl=false — STAGE ONLY, NEVER replicate to prodBLOCKERPROD CUTOVER Phase 5

Key Learnings

  1. Lockfile drift macOS/linux: fresh npm install required per build until TD-1 fixed
  2. Kotlin Cloud SQL TCP via public IP works for stage, NOT prod (TD-2 + TD-3)
  3. --no-traffic flag invalid on new service creation — route 100% on first deploy
  4. Field encryption/HMAC keys are random per env (stage isolated from prod — ADR-014)
  5. HikariCP socketPath URL param silently ignored — always use explicit host:port for direct TCP

References

  • Phase 1 Cloud SQL: Bilko Stage Environment — Cloud SQL & IAM (Phase 1)
  • MC #10177 (parent), #10239 / #10240 / #10241 (TD items)
  • ADR-014 (field encryption), ADR-021 (blueprint Section 15)
  • DEPLOY-MAP.md section: Cloud Run Stage Services
  • RUNBOOK.md section: 7a Stage Cloud Run Services Access