Deployment¶
CI/CD pipeline¶
All deployments must go through the CI/CD pipeline. Do not run deployment scripts manually on the server unless absolutely necessary — doing so bypasses pipeline validation and risks configuration drift between environments.
Every release should be pipeline-triggered to ensure a controlled, reproducible, and auditable flow.
User model¶
Two separate users are involved in every deployment:
| User | Purpose |
|---|---|
deploy | Used by the CI/CD pipeline to connect to the server via SSH. Shared across projects on the same server. |
<project> | The system user under which the project itself runs (e.g. peachfuzz). Each project has its own dedicated user. |
This separation ensures proper permission isolation — the pipeline can deploy without running as the project user, and projects cannot interfere with each other.
Deploy user requirements¶
- One dedicated deploy user per environment (staging, production) — never reuse personal accounts.
- Password login must be disabled; SSH key authentication only.
- Minimum permissions required — avoid
sudounless absolutely necessary. - File ownership should match the deploy user or the web group (
www-data).
Triggering a deployment¶
The easiest way to deploy is with the subscribed CLI:
subscribed deploy # fully interactive
subscribed deploy <project> --env production --ref main # non-interactive
The CLI prompts you to select a project, environment, and branch, then triggers the workflow_dispatch GitHub Actions workflow and confirms before firing. Deployments to production are restricted to the main/master branch — both interactively and when passing flags.
See subscribed-cli — deploy for the full command reference and project list.
Release model¶
See Docker — Deployment model for how timestamped releases and symlinked directories work in practice.