Idle slot compilation
Pull the commit, build on the idle blue or green slot, and keep live traffic on the active upstream.
Self-hosted zero-downtime Docker deploys on metal you control
QUICK START →VersionGate
Push to GitHub. VersionGate builds on the idle slot, proves health, then rewrites Nginx — with rollback as a local image swap.
The gap
CI/CD solved the push problem. Images land constantly, manifests churn, and every VPS becomes a miniature fleet. What did not improve is the moment after a bad deploy — when traffic is already wrong and the previous revision is a rebuild away.
Flat restart scripts treat a CSS tweak like a schema migration. Dashboards fire the same alarm for both, or miss the outage entirely while someone digs for the last known-good tag.
VersionGate is different. It keeps two slots warm, proves the next revision before the rewrite, and makes rollback a local image swap — not a prayer and a rebuild.
Architecture
From idle-slot build to warm-swap recovery — slot isolation, health gates, atomic upstream rewrites.
Pull the commit, build on the idle blue or green slot, and keep live traffic on the active upstream.
Hit the container health endpoint on the isolated host port. No rewrite until the new revision answers clean.
Reload upstream mapping in place. Request loss stays at zero while the previous slot stays warm.
Reuse the cached image on the sibling slot. Rollbacks land in under two seconds without a rebuild.
Warm swap
Other tools rebuild to go back. VersionGate keeps the previous slot warm and flips upstream when health says so — usually under two seconds.
[ INFO ] Rollback → commit 3a1f8b
[ OK ] Cache hit versiongate-web-app:v13
[ WARN-SWAP ] Skip rebuild
[ OK ] Health 200 · 8ms
[ OK ] Upstream → BLUE · warm-swap complete
Simulator
Same log grammar and JSON payloads the engine emits in production.
{
"status": "SUCCESS",
"jobId": "job_4912",
"project": "web-app",
"environment": "production",
"slot": "GREEN",
"port": 3101,
"durationMs": 1420,
"healthCheck": {
"status": 200,
"latencyMs": 14
}
}Capabilities
Filter by category and copy the CLI that drives each capability.
Atomic idle slot container compilation and Nginx upstream reload with zero HTTP request loss.
versiongate deploy --project web-app --env productionComplete structural overhaul featuring top scope bar, horizontal sub-nav, 4-column telemetry hero matrix, and grid/table view modes.
versiongate ui overhaul --layout vercel-platformSub-second rollbacks reusing locally cached Docker image tags without git re-pulling or context rebuilds.
versiongate rollback --project web-app --env productionReverse proxies stage environments cleanly on /p/:projectName/:stage without exposing raw host ports.
versiongate proxy add --path /p/web-app/stagingSHA-256 hashed persistent vg_live_... API Bearer tokens for external CI/CD workflow automation.
versiongate tokens create --name 'GitHub Actions CI'Self-hosted CLI password reset tools and in-dashboard administrator password management.
bun run reset-password admin@example.com 'NewPass123!'Full platform aesthetic redesign featuring Geist typography, #000000 obsidian dark canvas, hairline cards, and solid white CTAs.
versiongate theme set --preset vercel-geistEmbedded worker for Docker/single-process installs; PM2 splits API and worker with explicit queue ownership.
versiongate worker start --auto-healContinuous background thread auditing DB connection latency, Redis locks, container states, and disk/RAM limits.
versiongate monitor statusStage-specific environment variables for dev, staging, and prod overriding global project environment defaults.
versiongate env set --env staging --key DB_HOST --val staging-dbDual GitHub integration supporting zero-config central cloud relay or 1-click custom GitHub App Manifest creation.
versiongate github mode --type relayAutomatic multi-stage deployments targeting staging, dev, and production based on Git push ref.
versiongate webhook test --branch stagingNative Dockerfile generation supporting modern text bun.lock, bun.lockb, go.mod without go.sum, and Node package-lock.
versiongate build --detectBackground self-update pipeline streaming live build logs with zero connection drops and graceful PM2 / standalone reload.
versiongate system update --asyncSWR-style silent data revalidation, clean slot metrics, and intelligent terminal scroll locking without layout shifts.
versiongate dashboard status1-command host installer pre-packages Certbot and python3-certbot-nginx for instant 1-click HTTPS in Settings.
curl -fsSL https://versiongate.tech/install.sh | sudo bashPipeline
Trace ingestion through Redis locks, idle-slot builds, health gates, and atomic upstream swaps.
GitHub webhook sends a signed POST payload (/api/webhooks/github) verified with HMAC SHA-256.
X-Hub-Signature-256: sha256=8f92a1c...
Install
Bootstrap one host, then trigger deploys from CI with a Bearer token.
curl -fsSL https://versiongate.tech/install.sh | sudo bashcurl -X POST "$VG_URL/api/v1/deploy" \
-H "Authorization: Bearer $VG_TOKEN" \
-d '{"project":"web-app","env":"production"}'Knowledge base
Troubleshooting threads with concrete snippets for proxy paths, rollbacks, and token scopes.
VersionGate generates an updated Nginx upstream configuration file mapping the project's upstream name to 127.0.0.1:3101. It runs `nginx -s reload` (or SIGHUP), which instructs Nginx to spawn new worker processes for new incoming connections while allowing old worker processes to finish serving existing in-flight connections gracefully.
# Nginx upstream reload execution versiongate traffic switch --port 3101 --upstream versiongate_api-backend # Reloads Nginx gracefully without closing active socket connections
VersionGate warm-swap checks if the Docker container or local Docker image tag (e.g. `versiongate-my-app:v13`) already exists on the VPS host. If present, it skips git cloning, dependency installation, and Docker build context compilation, directly executing `docker run` on the cached image and verifying health immediately.
// Warm-swap check in src/services/rollback.service.ts
const isCached = await imageExists(previous.imageTag);
if (isCached) {
await runContainer(previous.containerName, previous.imageTag, ...);
}Navigate to Dashboard → Settings → API Access Tokens and click 'Generate Token'. Copy the raw token (`vg_live_...`). In your GitHub repository secrets, add `VERSIONGATE_API_TOKEN`. Pass it in the HTTP header: `Authorization: Bearer vg_live_...`.
# GitHub Actions Step
- name: Trigger VersionGate Deploy
run: |
curl -X POST https://your-server.com/api/v1/deploy \
-H "Authorization: Bearer ${{ secrets.VERSIONGATE_API_TOKEN }}" \
-d '{"projectId":"proj_123","environmentId":"env_prod"}'No. Live traffic remains 100% connected to the active blue slot container. VersionGate runs an internal health validation check against `http://127.0.0.1:<idle_port><healthPath>`. If the health check fails or times out, the deployment job is marked `FAILED`, the broken green container is stopped and removed, and Nginx traffic is never switched.
[ FAIL ] Health check failed: http://127.0.0.1:3101/health returned 500 Internal Server Error [ INFO ] Deployment aborted. Active traffic remains safely connected to port 3100.
VersionGate includes a `freeHostPort(port)` utility function that queries `docker ps -q --filter publish=PORT` and force-removes any leftover orphan containers occupying that port before attempting to bind new containers.
await freeHostPort(hostPort); // Kills and cleans up any orphaned containers bound to hostPort prior to docker run
Start small
See what zero downtime feels like when rollback already has the image.