Add url_shortening_service (prod + beta) to app_catalog and host ports #22

Closed
opened 2026-08-30 03:16:03 -07:00 by westfarn · 0 comments
Owner

Summary

Wire url_shortening_service into the deploy pipeline for prod and beta.

App repo: ai_ml_operations/url_shortening_service (default branch master).
Django 6 + uv + docker-compose.prod.yml (no bundled Postgres, no worker). Same shape as monica_site / scha.

Two public NPM hosts, same container / port:

Host Purpose
Short domain (aiml.pw and/or cidinn.li — pick when DNS is ready; beta can be short-beta.aimloperations.com) GET / landing page; GET /<code> 302 to the long URL. Do not proxy /api/, /admin/, /debug/.
API hostname (suggest shortener.aimloperations.com; beta shortener-beta.aimloperations.com) POST/GET /api/links/Bearer required. Not an open shortener. Drop /admin/.

Ansible does not manage NPM (Ryan). This ticket is catalog + ports + DB + secrets + docs.

Checklist

1. app_catalog (inventory/group_vars/all.yml)

url_shortening_service:
  type: django
  repo: "{{ git_base_url }}/ai_ml_operations/url_shortening_service.git"
  default_branch: master
  compose_file: docker-compose.prod.yml
  web_service: web
  migrate_cmd: "uv run python manage.py migrate --noinput"

No compose worker profile.

2. Host ports (host_vars for adama, roslin, starbuck, apollo, ai-server-4080)

Next free Django ports after monica_site (8004 / 8014):

- { name: url_shortening_service, env: prod, port: 8005 }
- { name: url_shortening_service, env: beta, port: 8015 }

App compose default is ${WEB_PORT:-8005}.

3. Postgres on 10.0.0.230

Create DBs + grant westfarn:

  • url_shortener (prod)
  • url_shortener_beta (beta)

Do not share a DB across envs. Active/active replicas of the same env share one DB.

4. Secrets (control node)

~/Documents/secrets/url_shortening_service/url_shortening_service_prod.env
~/Documents/secrets/url_shortening_service/url_shortening_service_beta.env

Templates: app repo .env.prod.example.

prod beta
DJANGO_ENV prod beta
DJANGO_DEBUG false false
DJANGO_ALLOWED_HOSTS short domain(s) + API hostname beta short + API hosts
DATABASE_URL .../url_shortener .../url_shortener_beta
WEB_PORT 8005 8015
SHORT_DOMAIN / PUBLIC_SHORT_URL / SHORT_PUBLIC_HOSTS aiml.pw or cidinn.li (https) beta short host
SHORT_API_HOSTS shortener.aimloperations.com (+ docker names if used) shortener-beta.aimloperations.com
SHORT_ADMIN_HOSTS localhost,127.0.0.1 same — do not put public hosts here
SHORTENER_API_TOKENS monica:<token_urlsafe(32)> different token
SHORT_ALLOWED_HOSTS mkdrealtor.com (add more later) same
CLICK_IP_PEPPER distinct from DJANGO_SECRET_KEY different pepper

Generate tokens/peppers with python -c "import secrets; print(secrets.token_urlsafe(32))". Never reuse DJANGO_SECRET_KEY.

5. Docs

  • IMPLEMENTATION.md: apps / ports / NPM / DB tables
  • scripts/deploy.sh help --app list

6. NPM (manual, out of Ansible)

Same upstreams on every app host (:8005 prod / :8015 beta):

  1. Short host/ + /[a-z0-9]{4,8}. 404 /api/, /admin/, /debug/.
  2. API host/api/ only. 404 /admin/.

Django also 404s /api/ on the short Host header even if NPM is wrong. Bearer is the lock on /api/ (empty tokens → 503; missing/wrong → 401).

7. Deploy smoke

~/Documents/repos/server-infra/scripts/deploy.sh --app url_shortening_service --env beta --ref master
~/Documents/repos/server-infra/scripts/deploy.sh --app url_shortening_service --env prod --ref master

Confirm:

  • GET /healthz/{"status":"ok"} on both ports
  • GET / on the short host → landing page ("URL Shortening Service", aimloperations.com)
  • GET /<code> → 302 after minting via Bearer on the API host
  • POST /api/links/ without Bearer → 401
  • GET /admin/ on the public API host → 404

Notes

  • Caller (monica_site) uses SHORTENER_BASE_URL=https://<api-host> and Authorization: Bearer monica:<secret>. Do not mint via the short hostname.
  • /debug/ mint UI is DEBUG only and never on the short host. Prod/beta stay DJANGO_DEBUG=false.
  • No dj-queue / worker for this app.
## Summary Wire `url_shortening_service` into the deploy pipeline for **prod** and **beta**. App repo: [`ai_ml_operations/url_shortening_service`](https://git.aimloperations.com/ai_ml_operations/url_shortening_service) (default branch `master`). Django 6 + uv + `docker-compose.prod.yml` (no bundled Postgres, no worker). Same shape as `monica_site` / `scha`. **Two public NPM hosts, same container / port:** | Host | Purpose | |------|--------| | Short domain (`aiml.pw` and/or `cidinn.li` — pick when DNS is ready; beta can be `short-beta.aimloperations.com`) | `GET /` landing page; `GET /<code>` 302 to the long URL. **Do not** proxy `/api/`, `/admin/`, `/debug/`. | | API hostname (suggest `shortener.aimloperations.com`; beta `shortener-beta.aimloperations.com`) | `POST/GET /api/links/` — **Bearer required**. Not an open shortener. Drop `/admin/`. | Ansible does not manage NPM (Ryan). This ticket is catalog + ports + DB + secrets + docs. ## Checklist ### 1. `app_catalog` (`inventory/group_vars/all.yml`) ```yaml url_shortening_service: type: django repo: "{{ git_base_url }}/ai_ml_operations/url_shortening_service.git" default_branch: master compose_file: docker-compose.prod.yml web_service: web migrate_cmd: "uv run python manage.py migrate --noinput" ``` No compose `worker` profile. ### 2. Host ports (`host_vars` for adama, roslin, starbuck, apollo, ai-server-4080) Next free Django ports after `monica_site` (8004 / 8014): ```yaml - { name: url_shortening_service, env: prod, port: 8005 } - { name: url_shortening_service, env: beta, port: 8015 } ``` App compose default is `${WEB_PORT:-8005}`. ### 3. Postgres on `10.0.0.230` Create DBs + grant `westfarn`: - `url_shortener` (prod) - `url_shortener_beta` (beta) Do **not** share a DB across envs. Active/active replicas of the same env share one DB. ### 4. Secrets (control node) ```text ~/Documents/secrets/url_shortening_service/url_shortening_service_prod.env ~/Documents/secrets/url_shortening_service/url_shortening_service_beta.env ``` Templates: app repo `.env.prod.example`. | | prod | beta | |--|--|--| | `DJANGO_ENV` | `prod` | `beta` | | `DJANGO_DEBUG` | `false` | `false` | | `DJANGO_ALLOWED_HOSTS` | short domain(s) + API hostname | beta short + API hosts | | `DATABASE_URL` | `.../url_shortener` | `.../url_shortener_beta` | | `WEB_PORT` | `8005` | `8015` | | `SHORT_DOMAIN` / `PUBLIC_SHORT_URL` / `SHORT_PUBLIC_HOSTS` | `aiml.pw` or `cidinn.li` (https) | beta short host | | `SHORT_API_HOSTS` | `shortener.aimloperations.com` (+ docker names if used) | `shortener-beta.aimloperations.com` | | `SHORT_ADMIN_HOSTS` | `localhost,127.0.0.1` | same — do not put public hosts here | | `SHORTENER_API_TOKENS` | `monica:<token_urlsafe(32)>` | different token | | `SHORT_ALLOWED_HOSTS` | `mkdrealtor.com` (add more later) | same | | `CLICK_IP_PEPPER` | distinct from `DJANGO_SECRET_KEY` | different pepper | Generate tokens/peppers with `python -c "import secrets; print(secrets.token_urlsafe(32))"`. Never reuse `DJANGO_SECRET_KEY`. ### 5. Docs - `IMPLEMENTATION.md`: apps / ports / NPM / DB tables - `scripts/deploy.sh` help `--app` list ### 6. NPM (manual, out of Ansible) Same upstreams on every app host (`:8005` prod / `:8015` beta): 1. **Short host** — `/` + `/[a-z0-9]{4,8}`. 404 `/api/`, `/admin/`, `/debug/`. 2. **API host** — `/api/` only. 404 `/admin/`. Django also 404s `/api/` on the short `Host` header even if NPM is wrong. Bearer is the lock on `/api/` (empty tokens → 503; missing/wrong → 401). ### 7. Deploy smoke ```bash ~/Documents/repos/server-infra/scripts/deploy.sh --app url_shortening_service --env beta --ref master ~/Documents/repos/server-infra/scripts/deploy.sh --app url_shortening_service --env prod --ref master ``` Confirm: - `GET /healthz/` → `{"status":"ok"}` on both ports - `GET /` on the short host → landing page ("URL Shortening Service", aimloperations.com) - `GET /<code>` → 302 after minting via Bearer on the API host - `POST /api/links/` without Bearer → 401 - `GET /admin/` on the public API host → 404 ## Notes - Caller (`monica_site`) uses `SHORTENER_BASE_URL=https://<api-host>` and `Authorization: Bearer monica:<secret>`. Do not mint via the short hostname. - `/debug/` mint UI is **DEBUG only** and never on the short host. Prod/beta stay `DJANGO_DEBUG=false`. - No dj-queue / worker for this app.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: ai_ml_operations/server-infra#22