Commit Graph
5 Commits
Author SHA1 Message Date
sakshamandClaude Sonnet 5 8ec7ca0881 Restart nginx on every deploy to avoid stale upstream IPs
nginx resolves the api/web service names to a container IP once, at
its own worker-process startup. docker compose up -d only recreates
containers whose image/config changed, so nginx keeps proxying to the
old, now-dead IP after a deploy rebuilds those containers - every
request 502s, which shows up in the browser as a misleading CORS
error since the bare 502 carries no Access-Control-Allow-Origin
header. Confirmed live: this caused a real multi-hour production
outage after the last two deploys.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-06 07:07:55 -04:00
sakshamandClaude Sonnet 5 3d6fe56991 Add Settings -> Database viewer (Adminer) for local devs and any admin
Local dev gets an unauthenticated Adminer instance bound to loopback
only. In production, any account with is_admin=true can open it -
the app mints a short-lived token from a live admin session, which
Nginx's new db.ciagent.org block exchanges for a session cookie that
re-checks admin status on every request, instead of a shared static
password that wouldn't scale to multiple admins or revoke live.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-05 22:18:16 -04:00
saksham a9ac6454c6 Note auto-deploy end-to-end verification 2026-08-05 20:27:05 -04:00
sakshamandClaude Sonnet 5 016c9424ce Add polling-based auto-deploy: server picks up pushes to master
scripts/auto-deploy.sh + a systemd timer (2min interval) that fetches
origin/master and, if ahead, pulls/rebuilds/migrates/restarts - same
sequence as the manual update steps in DEPLOYMENT.md, just scheduled.
Polling instead of a Gitea webhook deliberately: no extra exposed
service, no Docker socket mounted into a container, no shared secret
to manage - it's the same trust boundary as a manual SSH deploy.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-05 20:24:25 -04:00
sakshamandClaude Sonnet 5 086ca1f13f Add production deployment tooling: Nginx, Gitea, prod Dockerfiles
Sets up everything needed to deploy behind Cloudflare with a self-hosted
git server: multi-stage prod Dockerfiles (non-root), docker-compose.prod.yml
(Postgres/Redis with no host ports, Nginx reverse proxy, Gitea with
public-read/admin-write access control), scripts/bootstrap-env.sh to
auto-generate required secrets on first clone, and DEPLOYMENT.md covering
the full runbook. Provider API keys (Anthropic/Brave/NinjaPear/USPTO/
Turnstile) are deliberately kept out of .env in favor of the existing
DB-backed Settings UI, so the public repo stays safe to expose.

Also fixes two bugs only surfaced by live-testing the prod stack: Celery
beat couldn't write its schedule file as a non-root user, and Gitea's
embedded SSH server conflicted with the base image's own sshd on port 22.

Co-Authored-By: Claude Sonnet 5 <[email protected]>
2026-08-05 12:59:41 -04:00