Real World Example

Zero-Downtime Release

Banking and e-commerce apps release several times a day without stopping service. The pattern: build once, tag the image with the commit SHA, roll out to one instance at a time, and only send traffic after readiness is UP.

v41 running on app-1, app-2, app-3
   |
   1. LB removes app-1 (readiness DOWN during graceful shutdown, in-flight requests finish)
   2. app-1 restarts with v42, readiness UP -> LB adds it back
   3. repeat for app-2, app-3
   |
v42 running everywhere; any failed health check -> stop and redeploy v41 image

Example

Graceful shutdown settings that make it safe:

application-prod.yml

server:
  shutdown: graceful
spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s
management:
  endpoint:
    health:
      probes:
        enabled: true

Example

Rollback is just redeploying the previous tag:

IMAGE_TAG=9f1c2ab docker compose up -d app && curl -fs localhost:8080/actuator/health

Example output

[+] Running 1/1
 ✔ Container shopease-app-1  Started
{"status":"UP"}