Rollback Strategies: Designing for Recovery and Reliability
Master the art of the rollback. Learn how to design a reliable recovery process for your CI/CD pipeline to minimize downtime when deployments fail.

Previously in this course, we covered production-deployment-automating-secure-cd-pipelines and manual-approval-gates-controlling-production-deployments. While those lessons focused on moving code forward, this lesson adds the critical safety mechanism every engineer needs: how to move backward when things break.
The Philosophy of Recovery
In a perfect world, your automated tests—which we built in running-tests-in-ci-automating-your-validation-pipeline—would catch every bug. In reality, production environments are unpredictable. A "rollback" isn't a sign of failure; it's a sign of a mature, reliable system.
When a deployment causes an outage or a critical regression, your immediate goal isn't to "fix forward" (debugging in production while users suffer). Your goal is recovery: restoring the service to the last known good state as quickly as possible.
Designing a Rollback Process
A rollback process requires two things: an immutable artifact and a deployment mechanism that is idempotent (as discussed in idempotency-in-distributed-systems-building-reliable-apis).
If you are using containers, your "previous version" is simply the Docker image tag of your last successful build. Your rollback process follows these logical steps:
- Identify: Pinpoint the version currently running and the last stable version.
- Revert: Execute the deployment command using the previous stable image tag.
- Verify: Run health checks to confirm the service is healthy.
- Post-Mortem: Investigate why the new version failed, away from the pressure of a live incident.
Worked Example: Manual Rollback
Suppose you deployed version v1.2.1, but it’s crashing. You need to roll back to v1.2.0. Since we use GitHub Actions to deploy, we can trigger a manual deployment of the previous image.
Assuming your deployment script takes an image tag as an argument, here is how you perform a manual rollback using a workflow input:
YAMLname: Manual Rollback on: workflow_dispatch: inputs: image_tag: description: 'The stable image tag to roll back to' required: true jobs: rollback: runs-on: ubuntu-latest steps: - name: Deploy previous version run: | echo "Rolling back to image: ${{ github.event.inputs.image_tag }}" ./deploy.sh --image-tag ${{ github.event.inputs.image_tag }}
By using workflow_dispatch, you gain a UI button in GitHub Actions to trigger this job instantly. You simply type in the old version tag and hit "Run."
Hands-on Exercise
- Identify your last two successful image tags from your GitHub Actions run history.
- Create a new file in your
.github/workflows/directory namedrollback.yml. - Paste the code above into the file.
- Commit and push to your main branch.
- Navigate to the Actions tab in your repository, select "Manual Rollback," and trigger it with the tag of your last known good release. Verify your deployment script successfully pulls that image.
Common Pitfalls
- Database Schema Mismatches: If your new version applied a destructive database migration (e.g., dropping a column), rolling back the code won't fix the database. Always ensure migrations are backward-compatible.
- Assuming "Fixing Forward" is Faster: It rarely is. If the fix takes more than 5 minutes to identify, roll back first.
- Manual Deployment drift: If you deploy manually, ensure your CI system knows about it. If you don't update your "current" state in the repo, the next automated deploy might re-deploy the broken version.
FAQ
What if my rollback fails? If the rollback fails, you are dealing with a system-wide incident. Focus on isolating the environment (isolating-failing-code-segments-strategies-for-bug-localization) and potentially reverting to even older versions.
Should rollbacks be automated? For beginners, manual rollbacks are safer because they force human oversight. As you scale, you can automate this by having your health check step trigger a rollback automatically if it fails.
Recap
Reliability is built on your ability to recover. By creating a dedicated rollback workflow, you remove the panic from deployment failures. Remember: you are moving back to a known-stable state, not just guessing at a fix.
Up next: We will learn how to document our workflow inputs and outputs so your team understands how to operate these pipelines.
Work with me

CI/CD Pipeline & Docker Containerization
Ship with confidence: automated CI/CD pipelines and Docker setups so every push is tested and deployed — no more manual, error-prone releases.

VPS Server Setup, Deployment & Hardening
Get your app live on a fast, secure server — properly configured, hardened, and deployment-ready. No more wrestling with the command line.


