Skip to main content

Deployment Infrastructure

Last verified: 2026-02-21 | Sources: equa-server/cloudbuild.yaml, equa-server/Dockerfile, equa-web/Dockerfile, equa-web/nginx.conf, railway.toml files, DNS records, wind-down runbook

Deployment History Timeline

Era 1: AWS (Prior Deployment)

Unconfirmed — Requires Google Drive/Confluence AuditThe Equa platform was previously deployed on AWS. Evidence of AWS services that remain active in the codebase:
  • AWS S3 — File storage via aws-sdk/clients/s3 in equa-server/modules/file-storage/src/s3.d.ts
  • AWS SES — Email sending via equa-server/modules/notifications/src/nodemailer/email-notifier.ts
The full AWS deployment architecture (compute service, database, networking, and migration details) is documented in Google Drive and Confluence but has not yet been audited or exported locally. This section will be completed after that audit.Items to confirm:
  • Compute: EC2, ECS, Elastic Beanstalk, or Lambda?
  • Database: RDS PostgreSQL instance details
  • Networking: VPC, load balancer, SSL certs
  • Migration timeline: When and why moved to GCP

Era 2: GCP Cloud Run (Current — Winding Down)

The current production deployment runs on Google Cloud Platform. A decision was made on Feb 16, 2026 to wind down the public equa.cc instance to save $300-500/month in hosting costs. The infrastructure remains active but is in the process of being decommissioned. Source: equabot/threads/wind-down-equa-cc-public-instance/CONTEXT.md

Era 3: Future (TBD)

The redeployment strategy focuses on local-first development: perfect the integrated app locally, ship as a Mac/iOS desktop app, then redeploy to production cloud hosting when ready. Hosting platform TBD — options include returning to GCP Cloud Run, Railway (configs already exist), or alternative providers.

Current GCP Cloud Run Deployment

Cloud Build Pipeline

Source: equa-server/cloudbuild.yaml
steps:
  # 1. Build Docker image
  - name: 'gcr.io/cloud-builders/docker'
    args: ['build', '-t', 'gcr.io/$PROJECT_ID/equa-backend:$COMMIT_SHA', '.']

  # 2. Push to Google Container Registry
  - name: 'gcr.io/cloud-builders/docker'
    args: ['push', 'gcr.io/$PROJECT_ID/equa-backend:$COMMIT_SHA']

  # 3. Deploy to Cloud Run
  - name: 'gcr.io/google.com/cloudsdktool/cloud-sdk'
    entrypoint: gcloud
    args: ['run', 'deploy', 'equa-backend', ...]

Cloud Run Service Configuration

PropertyValueSource
Service nameequa-backendcloudbuild.yaml line 19
Regionus-central1cloudbuild.yaml line 23
Imagegcr.io/$PROJECT_ID/equa-backend:$COMMIT_SHAcloudbuild.yaml line 7
Port3000cloudbuild.yaml line 29
Memory1Gicloudbuild.yaml line 30
CPU1cloudbuild.yaml line 31
Min instances1cloudbuild.yaml line 32
Max instances10cloudbuild.yaml line 33
Timeout300scloudbuild.yaml line 34
Access--allow-unauthenticatedcloudbuild.yaml line 27
FeaturesStartup CPU boost, CPU throttlingcloudbuild.yaml lines 39-40
LoggingCLOUD_LOGGING_ONLYcloudbuild.yaml line 46
Direct URLhttps://equa-server-333648330110.us-central1.run.appequa-web/nginx.conf line 14
Unconfirmed — Requires GCP Console Access
  • GCP Project ID ($PROJECT_ID in cloudbuild.yaml)
  • Cloud SQL instance details (type, tier, version, connection method)
  • Load balancer name and configuration specifics
  • Static IP reservation details
  • Monthly cost breakdown by SKU
The GCP cost check runbook at stacks-ranking-priorities/runbooks/EQUA_CC_COST_CHECK.md identifies Cloud SQL as the #1 cost driver.

Docker Configurations

Backend: equa-server

Source: equa-server/Dockerfile
StageBase ImagePurpose
Buildnode:18-alpineInstall deps (yarn install --frozen-lockfile), compile TypeScript (tsc --build for file-storage and api modules)
Productionnode:18-alpinePM2 runtime, health check, production serving
Build dependencies: git, python3, make, g++ (for native npm module compilation) Process manager: PM2 v5 (pm2-runtime start ecosystem.config.js --only api) Health check: wget --spider http://localhost:3000/ every 30s (3s timeout, 5s start period, 3 retries) Environment variables:
VariableDefaultPurpose
PORT3000HTTP listen port
NODE_ENVproductionNode environment
DATABASE_TYPEpostgresDatabase driver
DATABASE_HOSTPostgreSQL host
DATABASE_USERNAMEDatabase user
DATABASE_PASSWORDDatabase password
DATABASE_NAMEDatabase name
API_SSLEnable HTTPS (loads certs from SSL_PRIVATE_KEY_PATH, SSL_PUBLIC_KEY_PATH)
Source: equa-server/Dockerfile (full file), equa-server/README.md (database env vars), equa-server/modules/api/src/server.ts lines 53-97 (SSL and port config).

Frontend: equa-web

Source: equa-web/Dockerfile
StageBase ImagePurpose
Buildnode:20-alpineInstall deps, run webpack production build
Productionnginx:alpineServe static files, reverse proxy API requests
Build settings:
  • NODE_OPTIONS=--openssl-legacy-provider (required for older webpack/SSL compatibility)
  • API_URL=/api/v1 (baked into the build)
  • Webpack runs directly (node_modules/.bin/webpack --mode production), skipping TypeScript type checking
Nginx configuration (equa-web/nginx.conf):
FeatureConfiguration
Listen port8080
API proxy/api/https://equa-server-333648330110.us-central1.run.app/
Static files/usr/share/nginx/html with 1-year cache (Cache-Control: public, immutable)
SPA fallbackAll routes serve index.html
GzipEnabled for text, CSS, JSON, JS, XML
Health checkGET /health returns 200 OK
Source: equa-web/Dockerfile (full file), equa-web/nginx.conf (full file).

Railway Deployments

Four services have Railway deployment configurations:

equa-server (Railway)

Source: equa-server/railway.toml
PropertyValue
Buildernixpacks
Start commandnpm run start:api
Health check/health (timeout: 300s)
Restart policyon_failure (max 3 retries)

equa-web (Railway)

Source: equa-web/railway.toml
PropertyValue
Buildernixpacks
Start commandnpm run start
Health check/ (timeout: 100ms)
Restart policyon_failure (max 3 retries)

equa-patternlib (Railway — Storybook)

Source: equa-patternlib-nextjs/railway.toml
PropertyValue
Buildernixpacks
Build commandnpm run build-storybook
Start commandnpx http-server storybook-static -p $PORT
Health check/ (timeout: 100ms)
Restart policyon_failure (max 3 retries)

Command Center (Railway)

Source: command-center-so/railway.toml
PropertyValue
Buildernixpacks
Start commandnpm run start
Health check/command-center/api/health (timeout: 100ms)
Restart policyon_failure (max 3 retries)
Required env varsEQUABOT_GATEWAY_URL, EQUABOT_GATEWAY_TOKEN, AUTH_SECRET, AUTH_GOOGLE_ID, AUTH_GOOGLE_SECRET

DNS and Networking

Domain Records

RecordTypeValuePurpose
equa.ccA136.110.187.76Root domain → GCP static IP
api.equa.ccA136.110.187.76API subdomain → GCP static IP
app.equa.ccCNAMEghs.googlehosted.comApp subdomain → Google Hosted Services
Source: DNS lookup results verified 2026-02-21.

Load Balancer

Partially VerifiedA Google HTTPS Load Balancer fronts the equa.cc and api.equa.cc domains. The response server: Google Frontend header confirms GCP load balancing. The static IP 136.110.187.76 is a reserved external IP in GCP.Items to confirm from GCP console:
  • Load balancer name (believed to be equa-lb)
  • URL map configuration (host-based routing rules)
  • Backend service bindings (Cloud Run NEG)
  • SSL certificate names and management type

Reverse Proxy (Nginx)

In production, equa-web’s Nginx container proxies API requests:
/api/*  →  https://equa-server-333648330110.us-central1.run.app/
Headers set: Host (Cloud Run service hostname), X-Real-IP, X-Forwarded-For, X-Forwarded-Proto. Source: equa-web/nginx.conf lines 13-19.

AWS Services (Active in Codebase)

S3 File Storage

The file-storage module uses the AWS SDK v2 for S3 operations:
FunctionPurposeSource
newS3Client(config)Create S3 client from configmodules/file-storage/src/s3.d.ts
uploadS3(s3, bucket, stream, file, contentType)Upload file to bucketmodules/file-storage/src/s3.d.ts
downloadS3(s3, bucket)Download file from bucketmodules/file-storage/src/s3.d.ts
newS3FileUploader(s3, bucket)Create file uploader instancemodules/file-storage/src/s3.d.ts
Configuration via AwsFileStorageConfig (env vars — bucket name, region, access key, secret key).
Unconfirmed: S3 bucket name, region, and whether this is the same AWS account as the prior full AWS deployment.

SES Email

The notifications module uses AWS SES as the primary email transport with SMTP as fallback: Source: equa-server/modules/notifications/src/nodemailer/email-notifier.ts
Unconfirmed: SES region, verified sender domains/emails, and sending limits.

Database Infrastructure

PostgreSQL (Confirmed from Code)

PropertyValueSource
Database typePostgreSQLequa-server/README.md
ORMTypeORM 0.2.24equa-server/modules/persistence/package.json
Entity count92+ entitiesequa-server/modules/persistence/src/schema.ts (~2000 lines)
Schema definitionequa-server/modules/persistence/src/schema.tsTypeORM entity classes
Connection configEnvironment variablesequa-server/README.md
Session storageTypeORM session store (express-session)equa-server/modules/api/src/server.ts line 189
Access patternAll modules use persistence helpers, not direct TypeORM callsequa-server/README.md line 106
Connection environment variables:
DATABASE_TYPE=postgres
DATABASE_HOST=localhost
DATABASE_USERNAME=postgres
DATABASE_PASSWORD=password
DATABASE_NAME=equa
DATABASE_LOGS=query,error      # optional
DATABASE_SCHEMA=               # optional
DATABASE_SYNC=                 # auto-sync in development
Source: equa-server/README.md lines 14-23.

Production Database

Unconfirmed — Requires GCP Console AccessThe production database is likely Cloud SQL (PostgreSQL), based on:
  • stacks-ranking-priorities/runbooks/EQUA_CC_COST_CHECK.md identifies Cloud SQL as the #1 cost driver
  • The wind-down runbook at equabot/threads/wind-down-equa-cc-public-instance/WIND-DOWN-RUNBOOK.md explicitly marks the database type as unknown (“Cloud SQL? Firestore? both?”)
Items to confirm:
  • Cloud SQL instance name, tier, and PostgreSQL version
  • Connection method (Cloud SQL Auth Proxy, direct IP, Unix socket)
  • Backup configuration and retention
  • Storage size and IOPS

SSL/TLS

Cloud Run (Automatic)

Cloud Run provides automatic HTTPS with Google-managed SSL certificates for the service URL (equa-server-333648330110.us-central1.run.app).

Custom Domains

Partially VerifiedGoogle-managed SSL certificates are expected for equa.cc and api.equa.cc based on the GCP HTTPS Load Balancer pattern. Certificate names and exact configuration require GCP console verification.

Server-Side SSL (Optional)

The equa-server supports optional SSL termination at the application level:
Env VarPurpose
API_SSLEnable HTTPS server
SSL_PRIVATE_KEY_PATHPath to private key file
SSL_PUBLIC_KEY_PATHPath to public certificate file
When enabled, Express starts an HTTPS server instead of HTTP. This is typically not needed when running behind Cloud Run or a reverse proxy that handles TLS termination. Source: equa-server/modules/api/src/server.ts lines 53-80.

Local Development Setup

Service Map

ServiceStart CommandPortDirectory
PostgreSQLdocker run (or local install)5432
equa-serveryarn start:dev3000equa-server/
equa-webyarn dev8080equa-web/
equa-patternlibnpm run storybook6006equa-patternlib-nextjs/
command-center-sonpm run dev3001command-center-so/
equabot-gatewayequabot gateway start18789equabot/ (workspace root)
OllamaSystem service11434

Proxy Configuration (Development)

In development, the Webpack dev server handles API proxying:
PathTarget
/apihttp://localhost:3000 (equa-server)
/equanaut-apihttp://localhost:19792
Source: equa-web/webpack.config.js (dev server proxy configuration).

Prerequisites

  1. Node.js 18+ (Node 22+ recommended per equabot-gateway requirements)
  2. Yarn (equa-server and equa-web use Yarn workspaces)
  3. npm (command-center-so, equa-patternlib use npm)
  4. PostgreSQL (local or Docker: docker run -e POSTGRES_PASSWORD=password -p 5432:5432 postgres)
  5. Git (all repos cloned to /Users/shawnowen/Documents/repos/)

Setup Steps

# 1. equa-server
cd equa-server
cp .env.example .env  # configure DATABASE_* vars
yarn install
yarn tsc
yarn init:db          # if fresh database
yarn start:dev

# 2. equa-web
cd equa-web
yarn install
yarn dev              # serves on :8080, proxies /api to :3000

# 3. command-center-so
cd command-center-so
npm install
npm run dev           # serves on :3001

# 4. equa-patternlib (optional, for component development)
cd equa-patternlib-nextjs
npm install
npm run storybook     # serves on :6006
Source: equa-server/README.md, equa-web/package.json scripts, command-center-so/package.json scripts.

Health Endpoints

ServiceEndpointResponse
equa-serverGET /health{"status": "healthy", "timestamp": "..."}
equa-serverGET /{"message": "API is running"}
equa-web (Nginx)GET /health200 OK (text/plain)
command-center-soGET /command-center/api/healthHealth status JSON
Source: equa-server/modules/api/src/server.ts lines 110-117, equa-web/nginx.conf lines 35-38.

Wind-Down Status

Decision Context

ItemDetail
Decision dateFebruary 16, 2026
ReasonSave $300-500/month; no paying customers
StrategyLocal-first development focus
ReversibilityFull — all data backed up, infrastructure documented
GitHub issue#358

Redeployment Triggers

  1. Feature-complete local version (Mac/iOS desktop app)
  2. Paying customer pipeline ready
  3. Funding available for hosting
  4. Hosting platform decision finalized (GCP vs Railway vs other)

Wind-Down Runbook

A detailed runbook exists at equabot/threads/wind-down-equa-cc-public-instance/WIND-DOWN-RUNBOOK.md covering:
  • Pre-flight scope confirmation
  • Inventory of all billable GCP resources
  • Database and config backups/exports
  • Traffic cutover and service scaling
  • Cost verification

Cost Analysis

The cost check runbook at stacks-ranking-priorities/runbooks/EQUA_CC_COST_CHECK.md identifies common lingering charge sources:
  • Cloud SQL (often #1 cost driver)
  • Cloud Load Balancing (forwarding rules, URL maps, proxies)
  • Cloud NAT (if used)
  • Compute Engine (disks, snapshots)
  • Artifact Registry storage
  • Cloud Logging ingestion/retention

Appendix: Unconfirmed Items Requiring Audit

The following items cannot be verified from source code alone and require access to external systems. Use the Phase 1 Audit Runbook for step-by-step instructions to complete these audits and then update this document.

Google Drive / Confluence Audit Required

ItemExpected Source
Full AWS deployment architecture (prior era)Google Drive infrastructure docs
AWS → GCP migration timeline and rationaleConfluence
Original AWS infrastructure diagramsGoogle Drive
Database migration recordsConfluence

GCP Console Access Required

ItemHow to Verify
GCP project IDGCP Console → Project selector
Cloud SQL instance detailsGCP Console → SQL → Instances
Load balancer configurationGCP Console → Network Services → Load Balancing
Static IP reservationGCP Console → VPC Network → External IP Addresses
SSL certificate namesGCP Console → Security → Certificate Manager
Monthly cost by SKUGCP Console → Billing → Reports (last 30 days)
Nameserver configurationGCP Console → Cloud DNS → Zone details

AWS Console Access Required

ItemHow to Verify
S3 bucket name and regionAWS Console → S3 → Buckets
SES verified domains/emailsAWS Console → SES → Verified Identities
SES sending regionAWS Console → SES → Account Dashboard
IAM user/role for S3+SES accessAWS Console → IAM
Once these audits are complete, the “Unconfirmed” sections in this document should be updated with verified details and the warning boxes removed.

Deployment Checklist

Source: Confluence KnowledgeBase — Deployment Checklist (by Christopher Johnson, v2.27.0)

Standard Deployment Procedure

  1. Pull code
  2. Bump versions
  3. Push frontend staging code
  4. Push backend staging code
  5. Notify team that deployment has started
  6. Push frontend production code
  7. Push backend production code
  8. Restart backend server
  9. Migrate database
  10. Watch for frontend to finish deploying
  11. Check production site
  12. Notify team that deployment is finished

Pre-Deploy Checks (supplementary)

  • All tests passing on target branch
  • Database migrations reviewed and tested on staging
  • Environment variables verified for target environment
  • Stakeholder sign-off obtained

Post-Deploy Verification (supplementary)

  • Health endpoint responds 200
  • Login flow functional
  • Key API endpoints return expected data
  • No new error spikes in monitoring

Rollback Procedure

  • Identify the issue (logs, monitoring, user reports)
  • Revert to previous Cloud Run revision or Railway deployment
  • Verify rollback successful
  • Investigate root cause before re-deploying