Docs/ Deployment/ Blue-Green & Rollbacks

Blue-Green & Rollbacks

Every deployment in sh0 uses a blue-green strategy for zero-downtime releases. If something goes wrong, roll back to any previous version instantly.

Blue-Green Deployments

Blue-green deployment is a release strategy that eliminates downtime by running two identical environments in parallel. At any given time, one environment (blue) serves live traffic while the other (green) is either idle or being updated with the new version.

When you deploy a new version, sh0 starts the new container alongside the current one. Once the new container passes health checks, traffic is instantly switched from the old container to the new one. The old container is kept running briefly as a fallback before being shut down.

Blue-green deployment diagram showing two containers with traffic routing
Tip
Blue-green deployments are enabled by default for all apps in sh0. There is no configuration needed -- every deployment automatically uses this strategy.

How sh0 Implements It

Here is the step-by-step process sh0 follows for every deployment:

  1. Build: The new Docker image is built from your source code or pulled from a registry
  2. Start green container: A new container is started with the updated image, connected to the same network and volumes as the current container
  3. Health check: sh0 runs health checks against the new container (HTTP endpoint, TCP port, or custom command)
  4. Run pre-deploy hooks: If configured, pre-deploy hooks execute against the new container (e.g., database migrations)
  5. Traffic switch: Caddy's reverse proxy configuration is updated to route all traffic to the new container
  6. Run post-deploy hooks: Post-deploy hooks execute (e.g., cache clearing, notifications)
  7. Drain old container: The old container is given a grace period (default: 30 seconds) to finish processing in-flight requests
  8. Stop old container: The old container is stopped and removed
Deployment timeline showing each step of the blue-green process

The traffic switch happens at the reverse proxy level (Caddy), which means it is instantaneous. There is no gap between stopping the old container and starting the new one -- both run simultaneously during the transition.

Zero-Downtime Deploys

Because the old container continues serving traffic until the new one is verified healthy, your users never experience downtime during deployments. The transition is seamless:

  • No 502 errors during deployment
  • No dropped connections or lost requests
  • No maintenance windows required
  • WebSocket connections on the old container are allowed to complete naturally

Health Checks

Health checks are critical to zero-downtime deployments. sh0 supports three types of health checks:

TypeHow It WorksBest For
HTTPSends a GET request to a specified path and expects a 2xx responseWeb applications with a health endpoint
TCPAttempts a TCP connection to the container portDatabases, caches, non-HTTP services
CommandRuns a command inside the container and checks the exit codeCustom health logic
Health check configuration
{
  "healthcheck": {
    "type": "http",
    "path": "/health",
    "interval": 10,
    "timeout": 5,
    "retries": 3,
    "start_period": 30
  }
}
Warning
If the new container fails health checks, sh0 automatically cancels the deployment. The old container continues serving traffic, and the failed deployment is recorded in the history with an error message.

Deployment History

sh0 maintains a complete history of every deployment for each app. The deployment history includes:

  • Deployment status (success, failed, rolled back)
  • Git commit SHA and message
  • Docker image tag and digest
  • Build duration and deploy duration
  • Who triggered the deployment (user, webhook, or API)
  • Full build log
Deployment history table showing recent deployments with status, commit, and duration

Click on any deployment to view its full build log, hook execution results, and health check output. The currently live deployment is highlighted in the list.

One-Click Rollback

If a deployment introduces a bug or performance issue, you can roll back to any previous version from the deployment history. Click the Rollback button next to any successful past deployment to instantly redeploy that version.

Deployment history with rollback button highlighted on a previous successful deployment

A rollback follows the same blue-green process as a regular deployment: the old version's Docker image is used to start a new container, health checks run, and traffic is switched. This means rollbacks are also zero-downtime.

Tip
sh0 retains Docker images for recent deployments so that rollbacks are instant -- there is no need to rebuild the image. The number of retained images is configurable under App Settings → Deployment → Retained Versions (default: 10).

Rollback via API

You can also trigger rollbacks programmatically using the sh0 API. This is useful for automated rollbacks triggered by monitoring systems.

Rollback to a specific deployment
# Rollback to a specific deployment ID
curl -X POST https://your-sh0-server.com:9000/api/apps/{app_id}/rollback \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"deploy_id": "deploy_abc123"}'
Rollback to the previous deployment
# Rollback to the immediately previous version
curl -X POST https://your-sh0-server.com:9000/api/apps/{app_id}/rollback \
  -H "Authorization: Bearer YOUR_TOKEN"

When no deploy_id is specified, sh0 rolls back to the most recent successful deployment before the current one.

Rollback Behavior

Important details about how rollbacks work:

  • Code only: Rollbacks revert the application code (Docker image) but do not revert database changes. If your deployment included a database migration, you may need to write a reverse migration manually.
  • Environment variables: Rollbacks use the current environment variables, not the variables from the time of the original deployment. This ensures that updated secrets and configuration remain in effect.
  • Hooks run: Pre-deploy and post-deploy hooks execute during a rollback, just as they would during a regular deployment.
  • History entry: Rollbacks create a new entry in the deployment history with a "rollback" label, showing which deployment was restored.
Warning
Rollbacks do not revert database schema changes. If your deployment included destructive migrations (dropping columns, renaming tables), plan your rollback strategy accordingly. Consider using reversible migrations and testing rollback scenarios in preview environments first.