# dd0c/route — V1 Infrastructure Stack ## Hosting (Bootstrap Budget) | Component | Provider | Tier | Monthly Cost | |-----------|----------|------|-------------| | Proxy Engine | Fly.io | 1x shared-cpu-1x (256MB) | ~$3 | | Dashboard API | Fly.io | 1x shared-cpu-1x (scale-to-zero) | ~$2 | | Dashboard UI | Cloudflare Pages | Free | $0 | | PostgreSQL (config) | Neon | Free (0.5GB) | $0 | | TimescaleDB (telemetry) | Neon (plain PG) | Free (0.5GB) | $0 | | Redis (cache) | Upstash | Free (10K cmd/day) | $0 | | CI/CD | Gitea Actions | Self-hosted (NAS) | $0 | | DNS + CDN | Cloudflare | Free | $0 | | Email (digests) | Resend | Free (100/day) | $0 | | **Total** | | | **~$5/mo** | ## Migration Path to AWS (at scale) When dd0c/route hits ~$1K MRR or needs guaranteed SLAs: | Component | From | To | |-----------|------|----| | Proxy | Fly.io | ECS Fargate (same Docker image) | | API | Fly.io | ECS Fargate | | UI | Cloudflare Pages | CloudFront + S3 | | PostgreSQL | Neon | RDS PostgreSQL | | TimescaleDB | Neon | RDS + TimescaleDB extension | | Redis | Upstash | ElastiCache | | CI/CD | Gitea Actions | Gitea Actions (keep) | | Email | Resend | SES | The migration is container-level — same Dockerfiles, same binaries. Only env vars change. ## Gitea Actions Setup Runner on Brian's NAS (TrueNAS, 500/500 fiber): ```bash # Install Gitea runner wget https://dl.gitea.com/act_runner/latest/act_runner-linux-amd64 chmod +x act_runner-linux-amd64 ./act_runner-linux-amd64 register --instance http://192.168.86.11:3005 --token ./act_runner-linux-amd64 daemon ``` Workflows at `.gitea/workflows/`: - `ci.yml` — Rust tests + clippy + fmt + UI build (every push) - `benchmark.yml` — Proxy latency P99 gate (pushes to src/proxy/) - `deploy.yml` — Fly.io + Cloudflare Pages deploy (main branch) ## Secrets Required Set in Gitea → Repository → Settings → Secrets: - `FLY_API_TOKEN` — Fly.io deploy token - `CLOUDFLARE_API_TOKEN` — Cloudflare Pages deploy - `CLOUDFLARE_ACCOUNT_ID` — Cloudflare account - `DATABASE_URL` — Neon connection string - `REDIS_URL` — Upstash connection string - `JWT_SECRET` — Production JWT signing key ## DNS ``` route.dd0c.dev → Fly.io proxy (CNAME dd0c-route-proxy.fly.dev) api.dd0c.dev → Fly.io API (CNAME dd0c-route-api.fly.dev) app.dd0c.dev → Cloudflare Pages (auto) ```