Build the artefact once
The rule that prevents an entire class of incident is that the artefact deployed to production is byte-identical to the one tested in staging. Build the container image once, tag it with the commit SHA, and promote that exact image through environments. Rebuilding per environment means production runs something no one ever tested, and the differences surface at the worst possible time.
Configuration therefore has to come from the environment at runtime, never baked into the image. This is the discipline that makes promotion meaningful: staging and production differ only in the values injected, so a passing staging deploy is genuine evidence rather than a rehearsal of something similar.
Test stages ordered by how fast they fail
Order the pipeline so the cheapest checks fail first: linting and type checking in seconds, unit tests in a minute, integration tests against a real containerised database after that. There is no point spending four minutes on integration tests to discover a type error that would have surfaced in ten seconds.
Integration tests should run against the real database engine in a container, not an in-memory substitute. The substitute's SQL dialect differs precisely where things break in production — date handling, constraint behaviour, transaction isolation. Those extra seconds buy genuine confidence rather than the appearance of it.
Blue/green: why it beats rolling for risky changes
Blue/green stands up a complete new version alongside the old one, shifts traffic when the new one is healthy, and keeps the old one warm long enough to shift back instantly. Rollback is a routing change measured in seconds rather than another deployment measured in minutes.
Rolling deployments are cheaper in infrastructure and mean both versions serve traffic simultaneously for a while, which is fine if they are compatible and painful if they are not. I use blue/green when a change is risky or hard to reverse, and rolling for routine changes. The decision is about how badly you need instant rollback, not about which is fashionable.
Health checks are what make it automatic
Automatic rollback is only as good as the signal it watches. A health check returning 200 as long as the process is running will happily certify a version that cannot reach its database. The check should verify the dependencies the service genuinely needs, so a broken deployment fails the check rather than passing it and failing the users.
Add a post-deployment window where error rate and latency are watched before the old version is torn down. Some failures do not appear in a health check — they appear as a rise in 500s on one endpoint under real traffic. Watching real signals for a few minutes catches what a synthetic probe cannot.
Database migrations are the hard part
Zero-downtime application deploys are straightforward. Zero-downtime schema changes are where teams get hurt, because during a blue/green cutover both versions run against the same database. Any migration must therefore be backward compatible with the version still serving traffic.
The pattern is expand, migrate, contract, across separate deploys. Add the new column as nullable and deploy code writing to both. Backfill. Deploy code reading the new column. Only in a later release drop the old one. It is more steps and it is the only way a rollback does not become a data-recovery exercise.
Secrets, permissions and pipeline hygiene
The pipeline holds credentials to your production infrastructure, which makes it a high-value target. Use short-lived federated credentials rather than long-lived access keys stored as secrets, scope permissions to exactly what the deploy needs, and restrict which branches can deploy to production.
Treat pipeline definitions as reviewed code, because a change to the workflow file is a change to production access. And pin action versions to a commit rather than a moving tag — a mutable tag in a third-party action is a supply-chain path straight into your deploy credentials.
Key takeaways
- Build the image once, tag it with the commit SHA, and promote that exact artefact through environments
- Order pipeline stages cheapest-first, and integration-test against a real containerised database engine
- Use blue/green when you need instant rollback; rolling is fine for routine, compatible changes
- Make health checks verify real dependencies, and watch error rate and latency before tearing down the old version
- Use expand-migrate-contract across separate deploys so both versions can run against the same schema
- Use short-lived federated credentials, restrict deploy branches, and pin third-party actions to a commit SHA
Conclusion
Zero downtime is mostly the discipline of building once, making health checks tell the truth, and treating schema changes as multi-release work. The pipeline mechanics are the easy half; the migration strategy is what separates a deploy you can reverse from one you cannot.
Enjoyed this article?

Vivek Kumar Singh
Technical Expert · Full Stack Cloud Engineer · Tokyo, Japan
Related articles
Workflow Automation That Actually Sticks: My Framework After 10 Enterprise Integrations
August 5, 2025 · 12 min read
RPA vs API Automation: Choosing the Right Tool for Enterprise Workflows
October 15, 2025 · 9 min read
VivekUI: A Free React Component Library With Zero Dependencies
August 23, 2026 · 9 min read