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>
37 lines
1.1 KiB
Desktop File
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
|