Deploy Runbook

Preconditions

  • SSH access to the WordPress host works.
  • PROD_SSH_TARGET is set to the production server's SSH alias in .env.
  • REHEARSAL_SSH_TARGET is set to the rehearsal server's SSH alias in .env.
  • Remote WordPress roots use the paths defined in lib/remote.sh.
  • You have reviewed the dry-run output.
  • Stage checks passed before prod deploy.
  • Production WordPress code deploys run from GitHub Actions on the remote main branch.

WordPress Stage

task deploy:wordpress:stage
task deploy:wordpress:stage -- --apply
task health:stage

Stage health runs database hygiene only because the stage domain is protected by Cloudflare Access. Use the GitHub Deploy WordPress workflow with target=stage to deploy stage from GitHub Actions.

WordPress Prod

Merge the tested change to main, then run the GitHub Deploy WordPress workflow:

target: prod
apply: true

The workflow checks that it is running from main before writing prod code.

NixOS

Check and dry-build locally:

task test:nixos:check

Dry-activate on the disposable rehearsal host before production import:

task deploy:nixos:rehearsal

Switch only after reviewing the dry activation result:

CONFIRM_NIXOS_PROD=prod task deploy:nixos:prod -- --apply
task health:stage
task health:prod

Rollback

For WordPress code, use the release id printed by the deploy command:

task rollback:wordpress:stage -- <release-id>
task rollback:wordpress:stage -- <release-id> --apply
task health:stage

Use rollback:wordpress:prod for production. Review the dry-run output before adding --apply. Apply a production rollback through the GitHub Rollback WordPress workflow on main.

For NixOS, use the system generation rollback on the host if a switch breaks the machine, then fix the repo before switching again.