Enable beta auto-deploy on master; manual prod button (#26) (#30)
Deploy Beta / unit-tests (push) Successful in 10s
Unit Tests / test (push) Successful in 9s
Deploy Beta / docker (push) Successful in 17s
Deploy Beta / deploy-beta (push) Successful in 1m3s

## Summary

Closes #26.

- Replace auto-prod `deploy.yml` with `deploy-beta.yml` (push to `master` → tests → `--env beta`) and `deploy-prod.yml` (`workflow_dispatch` only → `--env prod`), matching `dta_service` / `chat_web_app`
- Default `ALLOWED_HOSTS` / `CORS_ALLOWED_ORIGINS` include beta API + SPA hosts so beta frontend (and Tianji-instrumented pages) can call the API
- Expand `.env.prod.example` beta block (CORS, CSRF, OAuth callbacks, `FRONTEND_BASE_URL`, Tianji note)
- Harden `validate-env.sh` for beta secrets; README documents beta auto / prod button

## Tianji

Backend does not load `tracker.js`. FE already owns wiring (`chat_web_app#35`, closed).

- Beta SPA origin: `https://beta.chat.aimloperations.com`
- Beta Tianji website ID (FE `.env.beta`): `cms38bw671mf9n5jjw3xp1j3q`

## Coordination

- Infra: [server-infra#7](ai_ml_operations/server-infra#7) (`host_apps` beta `:8013`, `chat_backend_beta` DB, secret, NPM)
- FE companion: [chat_web_app#35](ai_ml_operations/chat_web_app#35)

## Test plan

- [ ] PR CI / unit tests green
- [ ] Merge to `master` triggers **Deploy Beta** only (not prod)
- [ ] Manual **Deploy Prod** `workflow_dispatch` still deploys `--env prod`
- [ ] After infra#7: beta container healthy on **8013** with `chat_backend_beta`
- [ ] Beta hosts / CSRF / CORS allow `https://beta.chat.aimloperations.com`Reviewed-on: #30
This commit was merged in pull request #30.
This commit is contained in:
2026-07-27 08:35:07 -07:00
parent acb3a51618
commit 5d5b448868
7 changed files with 176 additions and 28 deletions
+22 -8
View File
@@ -93,8 +93,8 @@ with `COMPOSE_DATABASE_URL` if needed.
| `ENABLE_ACCOUNT_REGISTRATION` | `false` | optional | Self-serve sign-up; keep false until ready |
| `STRIPE_SECRET_KEY` / `STRIPE_PUBLISHABLE_KEY` / `STRIPE_WEBHOOK_SECRET` | empty | yes for billing | Stripe API + webhook |
| `STRIPE_PRICE_ID` | empty | optional | Pre-created Price; else `$10/mo` from settings |
| `FRONTEND_BASE_URL` | `http://localhost:3000` | set in prod | Checkout success/cancel base |
| `CORS_ALLOWED_ORIGINS` | local + chat FE | set in prod | Frontend origin |
| `FRONTEND_BASE_URL` | `http://localhost:3000` | set in prod/beta | Checkout success/cancel + OAuth return |
| `CORS_ALLOWED_ORIGINS` | local + chat FE (+ beta FE default) | set in prod/beta | Frontend origin(s) |
| `USE_TLS_PROXY` | false (dev) | true behind NPM | Sets `SECURE_PROXY_SSL_HEADER` |
| `GUNICORN_WORKERS` / `GUNICORN_BIND` | 2 / `0.0.0.0:8000` | optional | Entrypoint |
| `SKIP_RAG_INIT` | unset | CI/migrate often `1` | Skip Chroma/Ollama boot work |
@@ -105,16 +105,18 @@ generation prompts (chat, RAG, data analysis). Not env-configurable.
Templates: `.env.example` (local), `.env.prod.example` (control-node secret).
Control-node secret path (server-infra on ai-server-4080):
Control-node secret paths (server-infra on ai-server-4080):
```text
~/Documents/secrets/chat_backend/chat_backend_prod.env
~/Documents/secrets/chat_backend/chat_backend_beta.env
```
Validate with:
```bash
./scripts/validate-env.sh ~/Documents/secrets/chat_backend/chat_backend_prod.env
./scripts/validate-env.sh ~/Documents/secrets/chat_backend/chat_backend_beta.env
```
If `DATABASE_URL` password contains `$`, escape each as `$$` for Compose.
@@ -141,29 +143,41 @@ RAG loaders that need a path materialize a short-lived temp file, then delete it
Chromas vector index may still use a volume (`chroma_db`); that is embeddings
metadata, not the original upload.
## Production (docker-compose.prod.yml)
## Production / beta (docker-compose.prod.yml)
- Single `web` service; **no** bundled DB — `DATABASE_URL` → shared Postgres (`10.0.0.230`).
- Host port from `WEB_PORT` (catalog: **8003**; beta reserved **8013**).
- Host port from `WEB_PORT` (prod **8003**; beta **8013**).
- Entrypoint: wait DB → migrate → collectstatic → `gunicorn` + `UvicornWorker`
(ASGI for HTTP **and** WebSockets).
- Active/active on **adama + roslin + ai-server-4080**; NPM balances upstreams.
- Deployed by:
- Manual / local deploy:
```bash
# beta (day-to-day)
~/Documents/repos/server-infra/scripts/deploy.sh \
--app chat_backend --env beta --ref <sha>
# prod (intentional)
~/Documents/repos/server-infra/scripts/deploy.sh \
--app chat_backend --env prod --ref <sha>
```
Beta hosts / CORS: `beta.chatbackend.aimloperations.com` API +
`https://beta.chat.aimloperations.com` SPA (see `.env.prod.example` beta block).
DB: `chat_backend_beta`. Pair with [server-infra#7](https://git.aimloperations.com/ai_ml_operations/server-infra/issues/7)
and frontend [chat_web_app#35](https://git.aimloperations.com/ai_ml_operations/chat_web_app/issues/35).
## CI / CD (Gitea Actions)
| Workflow | Trigger | Action |
|----------|---------|--------|
| `unittests.yml` | push + PR → `master` | `uv sync` + `manage.py test` |
| `ci.yml` | PR → `master` | same unit tests |
| `deploy.yml` | after Unit Tests succeeds on `master` **push** | docker build + tests on **ephemeral compose Postgres**`deploy.sh` |
| `deploy-beta.yml` | **push** to `master` | unit tests → docker compose tests`deploy.sh --env beta` |
| `deploy-prod.yml` | **manual** `workflow_dispatch` only | unit tests → docker compose tests → `deploy.sh --env prod` |
Deploy never runs on PRs.
Push/merge to `master` auto-deploys **beta** only. Prod requires the Gitea
**Run workflow** button on **Deploy Prod**. Deploy never runs on PRs.
## Security note