The new server is hardened and running Docker ( part 2 ).
Now we move the application. The goal is a few minutes of downtime, zero lost
data, and a rollback plan we never have to improvise.
To keep the commands concrete, this part uses a small example application. Swap
in your own names; the method doesn't change.
0. The example application
notes-api is a small REST API: users sign in and create, read and delete
notes. It's the same shape as most small production services:
Piece What it does State it holds
server the API, a container image built by CI and pushed to ghcr.io/<you>/notes-api none
postgres PostgreSQL 16: users, notes, schema migrations everything that matters
valkey Valkey (the open-source Redis fork): response cache and rate-limit counters short-lived only
caddy reverse proxy; gets and renews the TLS certificate automatically a certificate it can re-fetch
Users sign in with a token signed by a secret in .env.prod ( JWT_SECRET ), and
a nightly backup job writes a compressed pg_dump…