Deployment & CI/CD Wiki¶
The canonical guide for provisioning, securing, building, and deploying a Twycis project. Every project follows the same shape, so this wiki is written as a reusable template: wherever a real value is needed, it appears as a placeholder you swap for your project's own (see Conventions below).
The generic project name used throughout is App-name.
New here?
- Bootstrapping a brand-new project? Start at New Project Setup.
- Joining an existing project? Start at Developer Onboarding.
- Developing day-to-day? See Local Development — local Supabase, data, and migrations.
- Setting up the servers? Work through Infrastructure → Services → CI/CD in order.
What this covers¶
| Area | Pages |
|---|---|
| Infrastructure | AWS EC2 · Cloudflare Tunnel · Nginx |
| Services | Supabase (hosted) · Supabase (local) · Secrets & Env · SonarCloud |
| CI/CD | Overview · Deploy to Test · Deploy to Production · Docker & GHCR · Rollback · Skills Sync |
| Database | Migrations · Dump & Load |
| Guides | Onboarding · Local Development · New Project · Versioning · Agent Workflows · Auth Flow |
| Reference | Env Var Matrix · Secrets Matrix · Troubleshooting |
Architecture at a glance¶
flowchart TB
dev[Developer] -->|git push / tag| gh[GitHub]
gh -->|GitHub Actions| ci{Quality Gates}
ci -->|SonarCloud · E2E · npm audit · Trivy| build[Build & push images]
build -->|ghcr.io| ghcr[(GHCR)]
build -->|SSH via Cloudflare Tunnel| ec2
subgraph AWS["AWS EC2 — App-name host"]
nginx[Nginx reverse proxy] --> fe[Frontend container]
nginx --> be[Backend container]
be --> ghcr
fe --> ghcr
end
cf[Cloudflare] -->|Tunnel + Zero Trust| ec2[(EC2 instance)]
user[End user] -->|HTTPS| cf
be -->|Postgres + Auth| supa[(Supabase)]
The same topology is deployed twice — once for test, once for production — differing only in hostnames, image tags, and secrets.
Environments¶
This setup uses two environments. There is no separate acceptance/staging tier.
| Environment | Trigger | Host placeholder | Image tag | Deploy path |
|---|---|---|---|---|
| Test | push to main (and PRs run gates) |
test.<your-domain> |
:<git-sha> |
/opt/app-name |
| Production | push a v* tag |
<your-domain> |
:<tag> (e.g. v1.2.0) + :latest |
/opt/app-name-prod |
Both run the same quality gates before deploying: SonarCloud quality gate, an E2E
results gate, npm audit, an architecture check, and Trivy image + filesystem scans.
See Pipeline Overview.
Tech stack¶
| Layer | Technology |
|---|---|
| Frontend | React + Vite (TypeScript), Node 24 |
| Backend | FastAPI (Python 3.12) + SQLModel |
| Database | PostgreSQL via Supabase |
| ORM / migrations | SQLModel models + Alembic |
| Auth | Supabase Auth — Google + Microsoft OAuth, TOTP MFA |
| Containers | Docker + Docker Compose, images in GHCR (ghcr.io) |
| Reverse proxy | Nginx |
| Host | AWS EC2 (Ubuntu 26.04 LTS, or latest LTS) |
| Network/edge | Cloudflare Tunnel + Zero Trust (WARP for admins, service tokens for CI) |
| CI/CD | GitHub Actions |
| Code quality | SonarCloud |
| Image/dep scanning | Trivy + npm audit |
Conventions¶
This wiki is a template. Replace these placeholders with your project's real values. They are used consistently on every page.
| Placeholder | Meaning | Example real value |
|---|---|---|
App-name / app-name |
The project name (display / slug) | DoubleDiamond / doublediamond |
<org> |
GitHub / GHCR org or owner | twycis |
<your-domain> |
Production domain | app.example.com |
test.<your-domain> |
Test domain | app-test.example.com |
/opt/app-name |
Server deploy path (test) | /opt/doublediamond |
/opt/app-name-prod |
Server deploy path (production) | /opt/doublediamond-prod |
ghcr.io/<org>/app-name-backend |
Backend image | ghcr.io/twycis/doublediamond-backend |
ghcr.io/<org>/app-name-frontend |
Frontend image | ghcr.io/twycis/doublediamond-frontend |
<env> |
Environment name | test or production |
Note
Secrets and environment variables follow a single-source-of-truth strategy: GitHub holds the canonical values and injects them at deploy time. See Secrets & Environment and the Secrets Matrix.