Architecture and safety model
The pieces that make a deployment controlled rather than a remote shell.
Privilege boundary
The dashboard service is not root. It calls a root-owned helper through a local Unix socket only for fixed operations: install an allowlisted tool, activate or remove a project/domain, delete a project, change the owner password, and read one project’s runtime log. Browser input never becomes a free-form shell command.
Deployment lifecycle
- Portal validates the project configuration and repository source.
- It creates an immutable candidate release and installs dependencies there.
- Native projects run the optional named build script, start a temporary candidate, and perform the selected HTTP health check.
- The helper activates the candidate, performs a host health check, then validates Nginx, issues/updates TLS, and reloads Nginx.
- If a required phase fails, the previous active release and managed Nginx state are restored. The release event history records safe phase-level details.
State and ownership
- Portal state and source workspaces:
/var/lib/dashboard-portal. - Portal configuration and encryption key:
/etc/dashboard-portal/dashboard-portal.env. - Native project runtime:
/srv/hostmgr/projects/<slug>. - Generated project environment file:
/etc/hostmgr/projects/<slug>.env. - Portal-owned Nginx file:
/etc/nginx/sites-available/hostmgr-<slug>.conf.
What a failed deploy preserves
The active release does not change until activation succeeds. For Native projects, Portal keeps dependency trees for the active and immediately previous release; older release dependency trees are pruned after a successful activation. Persistent application data must live outside releases and is not a rollback mechanism.
Last audited: 2026-08-25
Portal source of truth