Table of Contents

Deployment

What a server needs to run the application. Nothing here depends on a particular hosting provider.

Requirements

Need Detail
Operating system Linux x64 (the release is published self-contained, so no .NET install is needed; otherwise the .NET 10 runtime)
Database PostgreSQL 17 or later; the exclusion constraint that refuses double room bookings needs PostgreSQL
Persistent data directory Outside the release directory, kept across deploys: attachments/, logs/, keys/ (data-protection key ring). Private to the service user
Reverse proxy TLS termination (the camera and secure cookies need https), WebSocket support (Blazor circuits on /_blazor), forwarded headers, and a request size that lets photo uploads through
Process model One instance. The realtime bus and the caches are in-process; a second instance needs a backplane first
Health check GET /health answers 200 when the app is ready

Configuration

Environment variables (double underscore for :):

Key Purpose
ConnectionStrings__Default PostgreSQL connection string
ASPNETCORE_ENVIRONMENT Production (no demo accounts, HSTS on)
Seed__AdminPassword The first administrator's password, read once on the first start
Attachments__Path, Logging__Path, DataProtection__Path The three folders of the data directory
AllowedHosts The host names the app answers on
Proxy__Known, Proxy__Hops The proxies trusted for forwarded headers
Proxy__Cdn__Header, Proxy__Cdn__Ranges__N Behind a CDN: the header with the client address, and the CDN's ranges
Email__From, Email__FromName, Email__BaseUrl Sender and the public address links in e-mails point to
Email__Host, Email__Port, Email__User, Email__Password SMTP, any provider
Email__Api=resend (with Email__Password as the API key) Send through an HTTPS e-mail API instead of SMTP, where outgoing SMTP is blocked
Login__Limit Login attempts per source per minute

With no e-mail configured, notifications stay in the app and nothing is kept to send later.

Start-up

  • EF Core migrations are applied at start-up, then the seeds and one-time folds run, each guarded by an audit marker so it runs once.
  • The startup catalog check refuses to start on a service definition the rules would refuse.
  • deploy/hangar/start.sh is the reference start script: it refuses to start without a data directory, creates the three folders with private permissions, and sets the paths before starting the app.

Releasing

  1. Run ./verify.sh on the exact commit, from a clean checkout (a git worktree), never a working tree with unfinished work.
  2. Publish self-contained for linux-x64 and upload the release.
  3. Switch traffic only after /health answers.
  4. Add the release's line to the changelog (Changelog.cs), with the build's commit written into the previous release.

Operations

  • Logs: Serilog, console and rolling JSON files in Logging__Path; readable under «سجل النظام» by ViewSystemLogs. Slow SQL over 500 ms is logged.
  • Backups: the database and the data directory together: attachments live on disk, and losing the key ring signs everyone out and breaks open forms.
  • Before going live: the repository's README.md lists the remaining blockers and sign-off items.