Files
Sluijsens 33d18ebbf8 Switches the database from SQL Server to MariaDB
The target Pi only has MariaDB, and SQL Server has no ARM64 build at
all - not a config problem, a real gap discovered during deployment
setup. Swapped the EF Core provider, regenerated every migration,
updated connection strings and the backup script everywhere they
appear.

Took two tries to land on a provider that actually works: Pomelo
builds fine against this project's EF Core 10 packages but fails at
runtime (it's compiled against 9's internal API surface, which moved
in 10 wherever Identity/DataProtection force the newer packages).
Oracle's official provider builds and migrates fine but has a real
MariaDB bug in its own migration-lock code, reproduced against a live
database. Kept Oracle's provider and worked around just that one
broken method - everything else it does is correct - rather than
give up more of the stack to chase a workaround.

Verified against a real local MariaDB end to end: all three
migrations applied, both hosts start clean, full suite still green.
2026-07-29 11:59:09 +02:00

3.2 KiB
Raw Permalink Blame History

Rollback Plan

Mechanism (D-26, infrastructure-design.md § 34): two releases are always retained — current plus exactly one previous. Pruning only ever runs after a passing health check, so a failed deploy never leaves fewer than two releases on disk.

When to Roll Back

  • The deploy workflow's health check failed (job already shows red; current was left pointing at the new, unhealthy release — no automatic rollback, per infrastructure-design.md § 4)
  • The deploy succeeded and passed its health check, but a defect surfaces afterward that only shows up under real traffic

Fast Rollback (Previous Release Still on Disk) — the Common Case

No rebuild needed. Over SSH, on the Pi:

cd ~/apps/slpsoftware/<env>/releases
ls -1t                                    # confirm which directory is the previous, working release
ln -sfn ~/apps/slpsoftware/<env>/releases/<previous-timestamp> ~/apps/slpsoftware/<env>/current
systemctl --user restart slpsoftware-<env>.service
curl -f https://<env-domain>/health       # confirm the rollback itself is healthy

This is the same atomic-switch primitive the deploy workflow itself uses — pointing it backward instead of forward. wwwroot/web/ is untouched either way, since it was never part of the switched directory to begin with (FR-08).

Rebuild-and-Redeploy Rollback (Older Than One Release Back)

If the defect predates the retained previous release, redeploy an earlier commit through the normal pipeline:

  1. git revert or check out the last-known-good commit on a branch
  2. Push to master (test) or run workflow_dispatch with deploy_production: true (production) — the same gates and deploy sequence run as any other deploy
  3. This only works because migrations are required to be forward-compatible and non-destructive (D-26) — redeploying an older commit's code against a database that has since had newer migrations applied must not break. If a migration since the target commit was destructive, this path is not safe and the database backup (§ below) is the actual recovery route instead

Database Rollback

A backup is taken before every production deploy (operations/deployment/deployment-instructions.md § 4, invoked by deploy-scp.yaml when run_db_backup: true). To restore:

gunzip -c <path-to-backup>.sql.gz | mariadb -h <server> -u <user> -p SlpSoftwareProduction

Restoring a database backup and rolling back the application release are independent actions — decide based on the actual failure whether one, the other, or both are needed. Rolling back the app without restoring the database is usually sufficient (migrations are non-destructive by design); restoring the database without rolling back the app should be rare and deliberate.

What Is Never Part of a Rollback

  • wwwroot/web/ (the customer's website) — structurally outside every release directory; no rollback action should ever touch it
  • The Data Protection key ring — lives in the database, not the release directory; rolling back the app release does not affect it
  • Gitea Actions variables/secrets — these describe the target, not a specific release; nothing about them changes during a rollback