Run the Astro Node standalone server as a hardened systemd service on
127.0.0.1:4322, behind the existing nginx which terminates TLS and proxies
the bifrost-portal.fenja.ai hostname. Coexists with the other Fenja site;
its config is untouched.
- deploy/bifrost-portal.service: systemd unit (bifrost user, EnvironmentFile,
ProtectSystem, ReadWritePaths to the data dir only)
- deploy/nginx/bifrost-portal.fenja.ai.conf: HTTP->HTTPS + proxy site block
- .env.production.example: prod env vars (secret, db path, uploads, host/port)
- scripts/deploy.sh: server-side pull -> install (rebuild native dep) ->
build -> migrate -> restart; persistent data untouched
- scripts/backup.sh: nightly online .backup, 30-day retention
- DEPLOY.md: full runbook (port check, DNS, provision, TLS, backups, rollback)
Persistent data (db, uploads, backups) lives in /var/lib/bifrost-portal,
outside the /opt/bifrost-portal build dir, so redeploys never wipe it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Admin can now upload a png/jpg event photo (SPEC §8 exception added):
- new image-upload admin field kind with live preview, uploading via
POST /api/admin/upload (fenja-only, type + 5MB validation);
- files stored under data/uploads (gitignored, BIFROST_UPLOAD_DIR
overridable) and served by GET /uploads/[file] with a traversal guard.
Reworks the /pulse event card: the greeting moved inside a taller box, the
"next gathering" label sits above the date + title, and the photo renders
as a top-right background that blends into the indigo via gradient masks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>