Files
slp-modular-cms/aidlc-docs/features/gitea-deployment-workflow/operations/deployment/deployment-plan.md
T
Sluijsens 2f243f23c3 Fixes the account model deploy setup got wrong
webadmin turned out to be FTP-only and belongs to whoever uploads
customer websites, not to this pipeline. Switched to a separate
deploy account with its own home-directory paths, well away from
where the other sites live, and made the persistent website symlink
cross into webadmin's territory instead of the other way around.
2026-07-28 19:41:34 +02:00

3.6 KiB

Deployment Plan

Date: 2026-07-28 Decided at: Deployment Setup, per deployment-setup-plan.md (Q1 = A, Q2 = A)

Method

Gitea Actions CI/CD, already built in Construction:

  • .gitea/workflows/continuous_integration.yaml (U5) — six blocking gates, then a per-environment dotnet publish, then invokes the deploy workflow
  • .gitea/workflows/deploy-scp.yaml (U6) — reusable workflow_call workflow: backup (production only) → upload → link persistent website → atomic switch → restart → health check → prune

This stage does not change that mechanism — it documents the operational side Construction deliberately left out: host setup, real domains, the database backup script, and the rollback procedure.

Environments

Environment Host Domain Trigger
Test Raspberry Pi (linux-arm64) test.slpsoftware.nl Automatic on push to master, or any workflow_dispatch
Production Same Pi, separate directory slpsoftware.nl Only workflow_dispatch with deploy_production = true

Same physical host for both (per infrastructure-design.md § 1) — separated by directory, systemd --user unit, and local port, never by anything the workflow manages directly.

Account model (revised at Deployment Setup): the Pi's existing webadmin account is FileZilla/ SFTP-only, used by website-workspace authors uploading customer sites under /mnt/storage1/www/html/ (WEBSITE_WORKSPACE.md's role) — it cannot SSH in and stays that way. The deploy pipeline uses a separate, dedicated SSH-capable account instead (deployment-instructions.md § 1.2), so the two roles never overlap on one credential. Deploy paths live under that account's own home directory, not under html/ — this was a deliberate choice to avoid the CMS's release/current/shared structure interfering with the other websites hosted there.

Rationale for What's Documented Here vs. Already Decided

Already decided (Construction) Documented here (Operations)
Atomic switch mechanism, retention count, transport Real domains, real ports
deploy-scp.yaml's step sequence The one-time host setup that sequence assumes already exists
That a DB backup step runs before production deploys The actual backup script's content
That transport is reserved for FTPS (D-02, NFR-09) What actually changes operationally when that day comes

Automation Level

Fully automated for test (push to master → live on test.slpsoftware.nl with no human step). Production requires an explicit, manual workflow_dispatch run with the flag checked — this manual trigger is the approval gate (D-09); no separate approval workflow step exists or is needed.

Rollback Strategy

Summarized here; full procedure in rollback-plan.md. Two releases are always retained (infrastructure-design.md § 3), so rolling back is a re-point-and-restart, never a rebuild, for the most recent deploy. Migrations are required to be forward-compatible and non-destructive (D-26), so redeploying an older commit remains valid further back than just one release.

Secrets and Configuration

Per D-16, runtime configuration lives in host environment variables that the workflow never writes — see deployment-instructions.md § "Runtime Configuration" for the full list and where it lives on the host (a single shared/env file per environment, outside the swapped release directory, chmod 600). Gitea Actions secrets are limited to what the workflow itself needs to reach the host: SSH credentials (PI_MAIN_*). No application secret is ever a Gitea secret or variable.