Rollback
There's no special "rollback" mode in OwnStack — a rollback is just another deployment with an older SHA (for git deploys) or older image tag (for image deploys). The mechanics are the same as a forward deploy: build, release task, restart.
Find what was running before
$ ownstack app info <app>
Stack: prod — deployed abc1234
$ ownstack remote deploy-log --app=<app> --history
ID SHA STATUS WHEN
1024 abc1234 succeeded 5 minutes ago
1023 def5678 succeeded 2 hours ago ← last known-good
1022 9abcdef failed 3 hours ago
Roll back via git deploys
$ git push origin def5678:main --force-with-lease # reset main to the good SHA
$ ownstack deploy
Or, without rewriting your branch:
$ git revert abc1234..HEAD
$ git push origin main
$ ownstack deploy
Revert keeps history straight; force-push is faster but rewrites main — be deliberate about which.
Roll back via image deploys
$ ownstack deploy --image=ghcr.io/me/my-app:def5678
Cleaner than git rollbacks because the image is already built and tested. Make sure your CI tags every build with the SHA so old images stay available.
What about migrations?
Migrations are usually forward-only. Rolling back the code does not roll back the database schema. If your "bad" deploy ran a migration that the previous code can't handle, you have two options:
- Hot-fix forward — write a new migration that reverses the change, deploy that.
- Restore the DB — pull a backup from before the bad deploy and restore it. See Restore.
The first time you need to roll back is a stressful time to learn the procedure. Ship a deliberately-noop change to staging, roll it back, time how long it takes. Now you know.
Multi-stack rollbacks
An ownstack deploy with an older SHA / image rolls back all deployable stacks. To roll back just one stack, use --stack=<name> — the others stay on the new SHA. This is occasionally useful for canary-style rollouts where you proved a regression on one stack before flipping the rest.