🚀 Deploy
The deployment target is one publicly usable Bun application at pwiz.loca.zone and one public Quartz wiki at wiki.pwiz.loca.zone. D-169 (2026-09-26) retains anonymous shared public access while optional Authelia SSO supplies signed-in identities and admin groups.
Service contract
- service name:
pwiz.service - service type: simple
- user and group: app operator account
- working directory:
${APP_ROOT} - environment:
NODE_ENV=productionHOST=${BIND_HOST}PORT=52222HOME=${OPERATOR_HOME}PATH=${OMP_BIN_DIR}:${BUN_BIN_DIR}:/usr/local/bin:/usr/bin:/bin
- exec:
${BUN} run server/index.ts
- restart:
- always
- restart delay: 5 seconds
- stop timeout: 20 seconds
[Unit]
Description=Prompt Wizard application
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=${APP_USER}
Group=${APP_GROUP}
WorkingDirectory=${APP_ROOT}
Environment=NODE_ENV=production
Environment=HOST=${BIND_HOST}
Environment=PORT=52222
Environment=HOME=${OPERATOR_HOME}
Environment=PATH=${OMP_BIN_DIR}:${BUN_BIN_DIR}:/usr/local/bin:/usr/bin:/bin
ExecStart=${BUN} run server/index.ts
Restart=always
RestartSec=5
TimeoutStopSec=20
[Install]
WantedBy=multi-user.targetApp nginx contract
- host:
pwiz.loca.zone - app backend:
${BACKEND_ORIGIN} - optional-SSO identity boundary (D-169):
- include app security headers and preserve the installed optional identity subrequest/fallback locations
- use trusted signed-in user/groups when SSO succeeds; fall back to group-less
publicfor anonymous visits, without redirecting app XHR into a required login - overwrite client-supplied identity headers before proxying
- admin routes require
adminsorpwiz-admins; anonymous and signed-in non-admin requests receive 403 - retain effective-identity scoping of ordinary library queries
- upload limit:
client_max_body_size 8m
- SSE route:
/api/events- proxy buffering off
- read timeout 3600 seconds
- AI route:
/api/ai/- read timeout 600 seconds
- general route:
- proxy HTTP 1.1
- upgrade headers retained for compatibility
- forwarded host and protocol headers retained
The installed vhost is the load-bearing routing source. The older nginx example that pinned every request to public is intentionally removed: copying it would undo D-169 and make admin tools unreachable. Likewise, the original all-gated vhost is a historical rollback anchor, not the current optional-login deployment recipe. Auth/nginx changes require their own approved mission; an application deployment does not change this boundary.
Wiki nginx contract
- host:
wiki.pwiz.loca.zone - root:
${WIKI_ROOT}/current - public without an identity gate
- immutable cache for assets
- route fallback:
- try exact file
- try generated
.html - try directory
- otherwise 404
server {
listen 443 ssl;
server_name wiki.pwiz.loca.zone;
include snippets/security-headers.conf;
root ${WIKI_ROOT}/current;
index index.html;
location ~* \.(css|js|png|webp|ico|json|woff2?|svg|map)$ {
expires 1y;
add_header Cache-Control "public, immutable";
try_files $uri =404;
}
location / {
try_files $uri $uri.html $uri/ =404;
}
}Certificate and registration
- certificate:
- one SAN certificate for app and wiki hosts
- nginx authenticator and installer
- ECDSA key type
- port registry:
- app port: 52222
- reserve adjacent future port: 52223
- startup order:
- install dependencies
- build app
- seed app data
- install service file
- enable and start service
- publish wiki
- reload nginx after valid config
See 🔒 Private runbook (login) before declaring deploy complete.