project-bifrost-platform/deploy/bifrost-portal.service
Arlind 819f8fa91c feat(deploy): nginx reverse-proxy deploy setup for bifrost-portal.fenja.ai
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>
2026-06-17 12:54:35 +02:00

37 lines
1.1 KiB
Desktop File

# systemd unit for the Bifrost portal (bifrost-portal.fenja.ai)
# Install to /etc/systemd/system/bifrost-portal.service
# Then: sudo systemctl daemon-reload && sudo systemctl enable --now bifrost-portal
#
# Assumes:
# - code checkout at /opt/bifrost-portal (built in place: dist/server/entry.mjs)
# - environment file at /etc/bifrost-portal.env (chmod 600, see .env.production.example)
# - a dedicated unprivileged service user `bifrost`
# - persistent data under /var/lib/bifrost-portal (db + uploads)
[Unit]
Description=Bifrost portal (Astro SSR, Node standalone)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=bifrost
Group=bifrost
WorkingDirectory=/opt/bifrost-portal
EnvironmentFile=/etc/bifrost-portal.env
ExecStart=/usr/bin/node /opt/bifrost-portal/dist/server/entry.mjs
Restart=on-failure
RestartSec=3
# Hardening — the service only needs to read its code and write its data dir.
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/lib/bifrost-portal
ProtectKernelTunables=true
ProtectControlGroups=true
RestrictSUIDSGID=true
[Install]
WantedBy=multi-user.target