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

  1. Portal validates the project configuration and repository source.
  2. It creates an immutable candidate release and installs dependencies there.
  3. Native projects run the optional named build script, start a temporary candidate, and perform the selected HTTP health check.
  4. The helper activates the candidate, performs a host health check, then validates Nginx, issues/updates TLS, and reloads Nginx.
  5. 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