Expose one private app through a narrow HTTPS edge.
The MVP target is a single-purpose Dockerized VPS behind an HTTPS reverse proxy. Before the official long-lived VPS cutover, use the same container/edge/runtime shape on a disposable private test-VPS-like rehearsal host. This page defines the production-edge assumptions without adding raw IP/user-agent identity ledgers to the application database.
Production assumptions
| Layer | Required posture | Privacy stance |
|---|---|---|
| Public TLS | Terminate HTTPS at a reverse proxy in front of the Rust app. | The app emits HSTS only when NOCTURNE_PUBLIC_ORIGIN is an https:// origin. |
| App bind | Keep the app reachable only by the local host proxy or private Docker network. | Do not publish the application port directly to the public internet in production. |
| Cookies | Set NOCTURNE_SECURE_COOKIES=true for production and keep owner sessions short. | Member sessions store only server-side digests; owner cookies use host-prefix/Secure posture plus HMAC-signed timestamped values with server-side expiry checks. |
| Owner gate | Configure NOCTURNE_OWNER_KEY_SHA256 or a startup-only NOCTURNE_OWNER_KEY; tune NOCTURNE_OWNER_SESSION_MAX_AGE_SECONDS if needed. | The owner dashboard remains disabled by default; plaintext owner keys are not stored in settings/database, and owner cookies contain no identity fields. |
| Body limits | The app enforces a 16 KiB default form limit and an 8 KiB public report limit; edge limits should be equal or stricter for public paths. | Reject oversized input without collecting reporter identity. |
| Public health | /healthz stays shallow; run doctor locally for details. | Database, filesystem, checkout, and media diagnostics are not disclosed to unauthenticated visitors. |
| Operational recovery | Set NOCTURNE_BACKUP_POSTURE before production exposure and run an isolated restore drill. | Backups recover pseudonymous records and private media without expanding live identity collection. |
| Logs | Use purpose-bound operational logs with short retention at the proxy. | The application remains designed around pseudonymous records and non-identifying abuse controls. |
| Proxy templates | Use the copy-safe Caddy or nginx example as the first public edge scaffold after preflight is clean. | Both disable persistent access logs and avoid forwarding client-IP headers; nginx adds memory-only sensitive-POST buckets, while stock Caddy requires a separately validated trusted-edge throttle before widening. |
Production-edge variables
NOCTURNE_DEPLOYMENT_PROFILE=production
NOCTURNE_PUBLIC_ORIGIN=https://final-brand.example
NOCTURNE_SECURE_COOKIES=true
NOCTURNE_OWNER_KEY_SHA256=64_character_sha256_hex_digest
NOCTURNE_OWNER_SESSION_MAX_AGE_SECONDS=1800
NOCTURNE_BACKUP_POSTURE=configured
NOCTURNE_BACKUP_DIR=/srv/nocturne/backups
NOCTURNE_BIND=0.0.0.0:3000
NOCTURNE_BIND=0.0.0.0:3000 is acceptable inside a private Docker network. If the app runs directly on the host, prefer a loopback bind and let the reverse proxy own public ports 80/443.
Local readiness checks
Use doctor for general environment diagnostics, vps-bootstrap-plan for non-destructive env/compose/proxy-template review before services start, deployment-rehearsal-plan for the secret-free operator sequence, and production-preflight as the stricter before-exposure gate on the VPS.
cargo run -- doctor
cargo run -- vps-bootstrap-plan --env-file .env.production
cargo run -- deployment-rehearsal-plan --origin https://members.final-domain.example --backup-id backup-YYYYMMDD
cargo run -- production-preflight
vps-bootstrap-planfails if the live env is still the committed example, placeholders remain, the env file is not private, runtime backup/evidence ledgers are not git-ignored, the VPS compose file publishes host ports, required backup/manifest/custody named volumes are missing, or proxy templates drift away from body-cap/log-minimization/header and abuse-control-boundary posture.deployment-rehearsal-planrejects placeholder origins, example env files, source-tree evidence paths, and ambiguous backup IDs while printing the intended evidence/backup/readiness command flow without executing it.NOCTURNE_DEPLOYMENT_PROFILE=productionturns missing HTTPS origin, insecure cookies, and missing owner gate into failing doctor checks;production-preflightalso blocks placeholder origins and owner sessions longer than one hour.- Production mode also fails when
NOCTURNE_BACKUP_POSTURE=local; useconfiguredfor an owner-managed writable backup target orexternalfor documented offsite/provider-managed backups. - A public
https://origin enables the HSTS header:Strict-Transport-Security: max-age=31536000. - Binding to all interfaces remains a warning, not a hard failure, because containerized reverse-proxy deployments commonly bind inside private networks. The VPS compose skeleton therefore publishes no app host port, persists private media/backups/manifest/custody ledgers in named volumes, and leaves public exposure to the HTTPS proxy.
- Reverse proxy templates now define the starting Caddy/nginx edge: 16 KiB default body cap, 8 KiB
/reportcap, no persistent access log by default, and a private app upstream. nginx also provides memory-only source buckets for sensitive anonymous POST routes; stock Caddy has no built-in request throttle and requires a separately validated privacy-minimizing trusted-edge equivalent before widening. External edge smoke verifies the selected public origin after proxy attachment,smoke-member-provisioncreates the disposable authenticated test account, and external member smoke verifies member routes through the same edge before cleanup. Deployment evidence records sanitized pass/fail artifacts,backup-manifest-checkverifies a sealed dump/media hash pair,backup-custody-checkverifies current encrypted/offsite retention, and private VPS readiness combines preflight, evidence, origin consistency, backup posture, backup manifest completeness, and custody retention before wider testing. - The nginx throttle is a private-test baseline, not production WAF/DDoS proof. Controlled
429behavior, shared-NAT false positives, production tuning, automated backup scheduling, successful restore drills, official VPS cutover, and external trust/safety escalation remain separate readiness work.
What this slice intentionally avoids
- No raw IP address or user-agent capture in the application database.
- No analytics fingerprinting or behavioral identity graph.
- No promise that proxy logs are impossible; the operational commitment is minimization, restricted access, and short retention.
- No provider-specific CDN/WAF dependency until deployment jurisdiction and hosting provider are chosen.