Work / Zero-downtime deploys
Zero-downtime deploys, several times a day
Blue-green releases with Docker, GitHub Actions and nginx, shared by every product I lead and shipping several times a day.
The problem
Before this, some services restarted in place on every release, so every deploy was a small outage, and the team waited for the evening to ship.
The goal was simple: deploys safe enough to run on a Tuesday afternoon without anyone noticing, and a bad release that never reaches users.
How a release works
- Build. GitHub Actions validates the pull request, builds the Docker image and ships it to the server.
- Start the idle slot. The new version boots in the slot that isn't serving traffic, next to the live one.
- Health gate. The new slot has to pass its health check. If it doesn't, nothing switches and users never see the bad release.
- Switch. nginx reloads with the new slot as its upstream. Requests already in flight finish on the old one.
- Report. The result goes to the team's Discord.
What can't be blue-green
Running two versions side by side is the easy part. The real design work is in the pieces that must never run twice, or must work with both versions at once.
Database migrations
Migrations follow expand and contract: add first, remove only after no running version needs the old shape. During a switch, old and new code both run against the same schema.
Workers and scheduled jobs
Queue workers and cron jobs run as a single instance and are not duplicated. Queues are paused through an endpoint during the switch, so no job is picked up twice. Financial jobs live in a dedicated worker role, so there is exactly one writer.
Stateful connections
The messaging gateway holds long-lived connections that only one process can own at a time, so it never runs twice. It restarts gracefully instead of going blue-green.
Trade-offA few seconds of reconnection on that one service, in exchange for never having two processes fight over the same connection.
Around the deploy
- Daily PostgreSQL backups to S3, with versioning and retention rules and least-privilege credentials.
- One health-check contract shared by the AI platform's services. A customer's disconnected WhatsApp never turns the platform status red.
- Dependabot and pull-request validation on every main repository.
Outcome
Deploys stopped being an event. All five production services ship through the same process, several times a day, during working hours, and a failed release stops at the health gate instead of reaching users.
Deploy frequency comes from the GitHub Actions history of the five production services. Server details are withheld.