Deployment Infrastructure

Summary

GoLiveBro’s control plane infrastructure has undergone two major architectural shifts documented in these plans. The first was the migration of the API server and database from AWS EC2 (8/mo) on 2026-03-20, consolidating the control plane onto the same host already running the personal relay. The second is a repo split plan (approved 2026-04-02) that separates the monorepo into a public MIT-licensed OBS plugin repository and a private proprietary backend repository, in preparation for public launch.

The current production topology runs PostgreSQL 16, the Go API binary (glb-api), and the Go jobs binary (glb-jobs) in Docker Compose on the Advin VPS at 208.84.101.84. Cloudflare terminates TLS and proxies api.telemyapp.com (migrating to api.golivebro.com) to port 8080 on the origin. UFW restricts port 8080 to Cloudflare IPv4 ranges only. The relay stack runs separately on the same or other Advin VPS nodes as Docker Compose services (srtla_rec + SLS).

The repo split design establishes a hybrid open-source model: the OBS plugin C++ source, headers, tests, and built dock bundle go into a public Telemy repo under MIT license, while the Go control plane, SQL migrations, dock JSX source, deploy scripts, and all private documentation move to a private telemy-api repo. The split uses git-filter-repo to purge backend code from the public repo’s history before force-pushing. After the split, dock UI development follows a cross-repo workflow: edit JSX in private repo, build with esbuild, copy minified bundle to public repo, commit.

Timeline

  • 2026-03-20: API migration plan created for EC2 to Advin VPS move. Goal: reduce monthly cost from ~8 (Advin VPS, already running).
  • 2026-03-20: Migration plan covers 8 phases: preparation, PostgreSQL in Docker, database migration (pg_dump/pg_restore), control plane deployment, UFW rules (Cloudflare-only), parallel verification, DNS cutover via Cloudflare A record, and EC2 teardown.
  • 2026-03-22: AWS references retired from documentation. Pool relay model became canonical.
  • 2026-03-23: Always-ready relay model deployed. AWS provisioner deprecated.
  • 2026-04-02: Repo split design document created and approved. Hybrid open-source model chosen.
  • 2026-04-02: Repo split implementation plan created with 9 tasks covering private repo creation, public repo history purge, LICENSE change to MIT, README rewrite, CHANGELOG cleanup, .gitignore update, force push, verification, and CLAUDE.md updates.

Current State

The control plane runs on the Advin VPS in Docker Compose. The deployment layout:

  • /opt/golivebro/ is the control plane root directory
  • /opt/golivebro/bin/glb-api and /opt/golivebro/bin/glb-jobs are the Go binaries (cross-compiled GOOS=linux GOARCH=amd64)
  • /opt/golivebro/docker-compose.yml defines three services: postgres (postgres:16-alpine), glb-api (alpine:3.20 + binary mount), glb-jobs (alpine:3.20 + binary mount)
  • /opt/golivebro/.env.glb is the canonical environment file (read by docker-compose.yml), contains all GLB_-prefixed variables (migrated from TELEMY_). The .env file is a symlink to .env.glb for backward compatibility with any scripts that historically referenced the plain name.
  • /opt/golivebro/secrets/db_password.txt is the PostgreSQL password (Docker secrets, chmod 600)
  • PostgreSQL data persists in a named Docker volume pgdata
  • PostgreSQL binds to 127.0.0.1:5432 only (not exposed externally)
  • Database connection string uses Docker network hostname postgres:5432

Cloudflare handles TLS termination. The origin A record for api.golivebro.com points to 208.84.101.84 with Proxied (orange cloud) enabled. An existing Cloudflare Origin Rule rewrites the port to 8080. SSL is set to Flexible mode.

UFW restricts port 8080 to 15 Cloudflare IPv4 CIDR ranges (173.245.48.0/20, 103.21.244.0/22, 103.22.200.0/22, 103.31.4.0/22, 141.101.64.0/18, 108.162.192.0/18, 190.93.240.0/20, 188.114.96.0/20, 197.234.240.0/22, 198.41.128.0/17, 162.158.0.0/15, 104.16.0.0/13, 104.24.0.0/14, 172.64.0.0/13, 131.0.72.0/22). Port 8080 is NOT open to 0.0.0.0.

The deploy workflow for API updates:

  1. Build: cd api && GOOS=linux GOARCH=amd64 go build -o dist/glb-api ./cmd/api/
  2. Stop: ssh advin "cd /opt/golivebro && docker compose stop glb-api"
  3. Upload: scp api/dist/glb-api advin:/opt/golivebro/bin/glb-api
  4. Start: ssh advin "chmod +x /opt/golivebro/bin/glb-api && cd /opt/golivebro && docker compose start glb-api"

The web frontend deploys to Cloudflare Pages from inside the web/ directory using npx wrangler pages deploy . --project-name=golivebro --branch=main --commit-dirty=true.

The repo split has not been executed yet. The monorepo still contains both the OBS plugin source and the Go control plane.

Key Decisions

  • 2026-03-20: Chose Docker Compose on Advin VPS over staying on EC2. Rationale: $15-20/mo savings, simpler ops (one host for API + relay), PostgreSQL in Docker eliminates host-level dependency management.
  • 2026-03-20: Chose Docker secrets for PostgreSQL password (POSTGRES_PASSWORD_FILE) over environment variable injection.
  • 2026-03-20: Chose UFW with Cloudflare IP allowlists over security groups. Only Cloudflare edge IPs can reach port 8080.
  • 2026-03-20: Chose Cloudflare orange-cloud DNS for instant rollback capability. DNS changes take effect in seconds, not hours.
  • 2026-03-20: Planned 24-hour waiting period before EC2 termination after cutover. Created AMI snapshot as final backup.
  • 2026-04-02: Chose MIT license for public OBS plugin repo over AGPL. Rationale: AGPL’s network clause does not apply to a locally-running DLL. MIT chosen for maximum trust and community adoption.
  • 2026-04-02: Chose to check in the built dock bundle (telemy-dock-app.js) as a minified artifact in the public repo rather than including JSX source. Rationale: dock UI contains pricing logic, feature gating, and product decisions that represent competitive intelligence.
  • 2026-04-02: Chose git-filter-repo for history purge over BFG Repo-Cleaner. Purges control-plane/ and all dock .jsx files from every historical commit.
  • 2026-04-02: Decided against BELABOX’s model (AGPL for relay + closed cloud). GoLiveBro approach is cleaner: open the client, close the server, no bait-and-switch with deprecated self-hosting.
  • 2026-04-17: DNS automation token rotated as rebrand cleanup. Previous token was Edit zone DNS, scoped to the telemyapp.com zone (pre-rebrand leftover), which caused CreateOrUpdateRecord in api/internal/dns/cloudflare.go to silently 4xx when provisioning {slug}.relay.golivebro.com records. New token is named golivebro-api-dns-mgmt, Zone.DNS:Edit scoped to the golivebro.com zone only. CLOUDFLARE_ZONE_ID in /opt/golivebro/.env corrected from the telemyapp zone id to the golivebro.com zone id (050c79877ae828b7e871ae45645b2fef). Old token revoked.

Gotchas & Known Issues

  • Go binaries may be dynamically linked (glibc dependency). If file reports “dynamically linked,” the Docker image must use ubuntu:24.04 or debian:bookworm-slim. If statically linked (CGO_ENABLED=0), scratch or alpine are viable.
  • The migration plan references telemy-api and telemy-jobs binary names. These have since been renamed to glb-api and glb-jobs as part of the GoLiveBro rebrand.
  • Environment variables were TELEMY_-prefixed in the migration plan. They are being migrated to GLB_ prefix.
  • The migration plan references aegis as the database name and user. Verify current naming.
  • Rollback trigger criteria from the migration plan: roll back immediately if health endpoint returns non-200, OBS plugin fails to connect/auth, database errors appear in logs, or any relay provisioning failures occur.
  • Repo split Task 7 (force push) requires manually unprotecting the main branch on GitLab before pushing and re-protecting after.
  • After repo split, the dock UI development workflow becomes cross-repo: edit JSX in telemy-api/dock-src/, build with esbuild, copy telemy-dock-app.js to Telemy/obs-plugin/dock/, commit bundle to public repo.
  • The migration plan’s Phase 2 (DB migration) mentions checking for migrations 0001-0013 plus 004/005. The actual migration count has grown significantly since then (0019+ for billing, 0025+ for password reset tokens).
  • The verification step in the repo split plan greps for sensitive strings including Advin, BuyVM, LemonSqueezy, server IPs, and pricing. Any of these in the public repo after split indicates incomplete purge.
  • The relay stack (/opt/srtla-receiver/) on Advin uses its own Docker Compose, separate from the control plane’s compose file at /opt/golivebro/.
  • Database backups are recommended as a cron job: docker exec glb-postgres pg_dump -U aegis aegis | gzip > /opt/golivebro/backups/telemy-$(date +%Y%m%d).sql.gz. This is documented in the migration plan but automated setup is not specified.

Open Questions

  • Repo split execution has not started. Tasks 1-9 from the implementation plan are pending.
  • The private repo organization names reference Telemyapp / telemy on GitHub/GitLab. These may need updating to GoLiveBro / golivebro post-rebrand.
  • Whether the Go binaries need CGO_ENABLED=0 for static linking in Docker is noted as a verification step but not resolved in the plans.
  • The migration plan’s Phase 8 (EC2 teardown) status is unclear. The plan specifies waiting 24 hours post-cutover, creating an AMI snapshot, then terminating. Whether the old EC2 instance at 52.13.2.122 has been terminated is not documented in the source files.
  • Database backup automation (cron job) is recommended but not confirmed as implemented.
  • The ubuntu:24.04 base image for API/jobs containers adds unnecessary bloat if binaries are statically linked. This optimization is deferred.
  • Stripe migration progress (GLB_STRIPE_* env vars) affects billing webhook configuration on the deployed infrastructure.

Sources