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.
How sh0 Implements It
Here is the step-by-step process sh0 follows for every deployment:
- Build: The new Docker image is built from your source code or pulled from a registry
- Start green container: A new container is started with the updated image, connected to the same network and volumes as the current container
- Health check: sh0 runs health checks against the new container (HTTP endpoint, TCP port, or custom command)
- Run pre-deploy hooks: If configured, pre-deploy hooks execute against the new container (e.g., database migrations)
- Traffic switch: Caddy's reverse proxy configuration is updated to route all traffic to the new container
- Run post-deploy hooks: Post-deploy hooks execute (e.g., cache clearing, notifications)
- Drain old container: The old container is given a grace period (default: 30 seconds) to finish processing in-flight requests
- Stop old container: The old container is stopped and removed
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:
| Type | How It Works | Best For |
|---|---|---|
| HTTP | Sends a GET request to a specified path and expects a 2xx response | Web applications with a health endpoint |
| TCP | Attempts a TCP connection to the container port | Databases, caches, non-HTTP services |
| Command | Runs a command inside the container and checks the exit code | Custom health logic |
{
"healthcheck": {
"type": "http",
"path": "/health",
"interval": 10,
"timeout": 5,
"retries": 3,
"start_period": 30
}
}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
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.
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.
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 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 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.