Property PrismDev Hub

Infrastructure & Operations

CI/CD pipelines, deployment, monitoring, Docker, and operational procedures.

Updated Apr 3, 2026

Hosting Architecture

┌─────────────────────────────────────────────────────────────┐
│                     Cloudflare Edge                          │
│  TLS termination, WAF, CDN caching, DNS                    │
├──────────────────────┬──────────────────────────────────────┤
│  Cloudflare Pages    │  Cloudflare Tunnel/Proxy             │
│  (Frontend SPA)      │  → Render (Backend)                  │
└──────────────────────┴──────────────────────────────────────┘
                              │
         ┌────────────────────┼────────────────────┐
         │                    │                    │
    ┌────▼────┐         ┌────▼────┐          ┌────▼────┐
    │ Supabase│         │ Upstash │          │  Clerk  │
    │ Postgres│         │  Redis  │          │  Auth   │
    └─────────┘         └─────────┘          └─────────┘
ComponentPlatformNotes
FrontendCloudflare PagesStatic SPA, auto-deploy from git
BackendRenderDocker container, auto-deploy from git
DatabaseSupabaseManaged Postgres 15 + PostGIS
CacheUpstashManaged Redis
AuthClerkSSO, MFA, JWT issuance
SecretsInfisicalAuto-syncs to Render + Cloudflare Pages
Error TrackingSentryFrontend + backend error/performance
DNS/CDN/TLSCloudflareEdge termination, HSTS

CI/CD Pipeline

GitHub Actions Workflow

File: .github/workflows/go-backend-ci.yml

Triggers:

  • Pull requests touching go-backend/**
  • Pushes to main and qa branches touching go-backend/**

CI Services:

  • PostgreSQL 16 + PostGIS (via postgis/postgis:16-3.4-alpine service container)

Steps:

  1. Checkout code
  2. Apply database schema — runs PRISM_vNext_FINAL.sql + all migrations against test DB
  3. Create test rolesauthenticated, prism_app roles with RLS stubs
  4. Setup Go toolchain
  5. Go testsgo test ./... (includes integration tests against real Postgres)
  6. Race detectiongo test -race ./internal/...
  7. Go vetgo vet ./...
  8. Swagger drift checkmake api-docs-check (ensures generated docs match handler annotations)
  9. Docker compose validationdocker compose config for ops configs

Branch Strategy

feature → qa → main (production)
BranchPurposeDeploys To
Feature branchesDevelopment work
qaIntegration testing, QA validationStaging
mainProduction releasesProduction

Release Flow

  1. Feature branches merge into qa via PR
  2. CI runs automatically on PR + push
  3. QA validation on staging environment
  4. PR from qamain requires 1 approving review + all CI green
  5. Merge to main triggers production deploy
  6. Post-deploy verification via /health, /ready

Docker Compose Stack

Full Development Stack

File: go-backend/ops/docker-compose.yml

Services:

  • postgres — PostgreSQL 15 + PostGIS
  • redis — Redis 7
  • api — Prism Go backend (builds from Dockerfile)
  • prometheus — Metrics collection and alerting rules
  • alertmanager — Alert routing to Slack
  • grafana — Dashboards and visualization
cd go-backend/ops
cp .env.example .env
docker compose up --build -d

VM/EC2 Deploy Stack

File: go-backend/ops/deploy/docker-compose.yml

Minimal stack — API container only (point at managed Postgres/Redis):

cd go-backend/ops/deploy
cp .env.example .env
docker compose up -d --build

Monitoring

Production Monitoring

ToolPurpose
SentryError tracking, performance monitoring, release tracking
Render MetricsCPU, memory, request stats, restarts
Cloudflare AnalyticsEdge traffic, WAF events, cache hit rates

Local Development Monitoring

ToolPortPurpose
Prometheus:9090Metrics scraping and alerting rules
Alertmanager:9093Alert routing to Slack
Grafana:3000Dashboards and visualization

Prometheus Alert Rules

File: go-backend/ops/prometheus/prism-api-alerts.yml (full profile)
File: go-backend/ops/prometheus/prism-api-alerts.dev.yml (low-noise dev profile)

Alert categories:

  • Request latency (warning: P95 > 500ms, critical: P95 > 2s)
  • Error rate (warning: > 1% 5xx, critical: > 5%)
  • Request rate anomalies
  • Go runtime (goroutine count, memory)

Slack Alert Routing

  • Warning alerts → SLACK_WARNING_CHANNEL
  • Critical alerts → SLACK_CRITICAL_CHANNEL
  • Webhook URLs configured in go-backend/ops/.env

Grafana Dashboard

Pre-configured dashboard: go-backend/ops/grafana/dashboards/prism-api-overview.json

Panels: request rate, latency percentiles, error rate, active goroutines, memory usage.

Grafana Alloy (OpenTelemetry)

File: go-backend/ops/alloy/config.alloy

Grafana Alloy is configured as an OpenTelemetry collector for traces and metrics forwarding.


Backend Metrics Endpoint

The backend exposes Prometheus metrics at GET /metrics.

Production protection: When ENV=production, the /metrics endpoint requires either:

  • Bearer token matching METRICS_SCRAPE_TOKEN
  • Auth with audit:read scope

Metrics exposed:

  • http_requests_total — request counter by method, path, status
  • http_request_duration_seconds — request latency histogram
  • http_request_size_bytes — request body size
  • http_response_size_bytes — response body size
  • Go runtime metrics (goroutines, memory, GC)

Performance Testing

k6 Smoke Test

Script: go-backend/perf/k6-smoke.js
Run: cd go-backend && make load-smoke

SLO thresholds (documented in docs/ops/k6-smoke-test.md):

  • P95 latency < target
  • Error rate < threshold
  • Throughput > minimum

Use as a release gate before promoting qa → main.


Secrets Management

All secrets managed in Infisical as single source of truth.

Infisical Folder Structure

/backend/     → Go backend secrets (synced to Render)
/frontend/    → Frontend secrets + config (synced to Cloudflare Pages)
/ops/         → Monitoring / alerting secrets (deferred)

Sync Targets

FolderSyncs To
/backend/Render (backend service)
/frontend/Cloudflare Pages (build environment)

Key Secrets

SecretPlatformSensitivity
DATABASE_URLRenderHigh (embedded password)
REDIS_URLRenderHigh (embedded password)
CLERK_SECRET_KEYRenderHigh
CLERK_SECRET_KEYCloudflareHigh (Clerk proxy function)
SENTRY_AUTH_TOKENCloudflareHigh
SENTRY_DSNRenderLow
ALLOWED_ORIGINSRenderLow

Rotation Policy

  • Database credentials: 90 days or on compromise
  • Clerk keys: on staff change or compromise
  • Sentry tokens: on compromise
  • Slack webhooks: rotate immediately if exposed

Deployment Procedures

Pre-Deploy Checklist

  • All CI checks pass on target commit
  • No open high/critical Dependabot alerts
  • ENV=production set in Infisical /backend/
  • STRICT_CLERK_SCOPES=true set
  • Database backup exists before migrations
  • Any pending migrations reviewed and ready
  • Edge/TLS/HSTS healthy

Database Migration Policy

  • Fresh environments: Apply database/PRISM_vNext_FINAL.sql
  • Existing databases: Apply targeted files from database/migrations/ (non-destructive)
  • Always back up before applying migrations
  • Validate key objects after schema changes

Rollback Procedure

  1. Identify the last known-good commit
  2. Revert in Render to previous deploy
  3. If migration caused the issue: apply rollback migration or restore from backup
  4. Verify /health and /ready endpoints
  5. Spot-check key business endpoints

Post-Deploy Verification

  1. Check GET /health → 200
  2. Check GET /ready → 200
  3. Verify Sentry for new error groups
  4. Spot-check: building list, comp list, auth flow
  5. Monitor for 15 minutes

Frontend Deployment

Platform: Cloudflare Pages
Build: npm run build (Vite production build)
Output: frontend/dist/ (static assets)

Environment variables injected at build time via Cloudflare Pages settings (synced from Infisical /frontend/).

See docs/frontend/deploy-cloudflare-pages.md for detailed setup.


TLS / HTTPS

TLS is terminated at the Cloudflare edge. The backend service listens on :8080 (HTTP) behind the edge proxy.

  • HSTS enabled at edge
  • Backend is not directly reachable from public internet
  • TRUST_CLOUDFLARE_HEADERS must be set correctly for real IP extraction

See docs/ops/https-tls.md for detailed configuration.