🚀 Deploy
The approved deployment target is one Bun application at pwiz.loca.zone and one public Quartz wiki at wiki.pwiz.loca.zone. The app is protected by Authelia; the wiki is not.
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} - app is behind Authelia:
- include app security headers
- include Authelia server-level location snippet
- include Authelia authrequest in proxied locations
- 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
server {
listen 443 ssl;
server_name pwiz.loca.zone;
include snippets/security-headers-app.conf;
include snippets/authelia-location.conf;
client_max_body_size 8m;
location /api/events {
include snippets/authelia-authrequest.conf;
proxy_pass ${BACKEND_ORIGIN};
proxy_buffering off;
proxy_read_timeout 3600s;
}
location /api/ai/ {
include snippets/authelia-authrequest.conf;
proxy_pass ${BACKEND_ORIGIN};
proxy_read_timeout 600s;
}
location / {
include snippets/authelia-authrequest.conf;
proxy_pass ${BACKEND_ORIGIN};
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Wiki nginx contract
- host:
wiki.pwiz.loca.zone - root:
${WIKI_ROOT}/current - no Authelia
- 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 verification before declaring deploy complete.