Self-hosted zero-downtime Docker deploys on metal you control

QUICK START →
BUILDHEALTHSWAPROLLBACK

VersionGate

Zero-downtime deploys that keep a warm slot ready.

Push to GitHub. VersionGate builds on the idle slot, proves health, then rewrites Nginx — with rollback as a local image swap.

The gap

Shipping got fast.
Recovery stayed manual.

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

Four steps.
One blue-green loop.

From idle-slot build to warm-swap recovery — slot isolation, health gates, atomic upstream rewrites.

01 //Build

Idle slot compilation

Pull the commit, build on the idle blue or green slot, and keep live traffic on the active upstream.

02 //Prove

Health-gated promotion

Hit the container health endpoint on the isolated host port. No rewrite until the new revision answers clean.

03 //Swap

Atomic Nginx rewrite

Reload upstream mapping in place. Request loss stays at zero while the previous slot stays warm.

04 //Recover

Warm-swap rollback

Reuse the cached image on the sibling slot. Rollbacks land in under two seconds without a rebuild.

Warm swap

The rollback that already has the image.

Other tools rebuild to go back. VersionGate keeps the previous slot warm and flips upstream when health says so — usually under two seconds.

rollback stream1.48s

[ 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

Watch a deploy, rollback, and token flow.

Same log grammar and JSON payloads the engine emits in production.

Blue/Green Zero-Downtime Deployment[ Real-time Stream ]
[ INFO ] Job #4912 enqueued (Project: web-app, Environment: production)
[ INFO ] Inspecting container slots: BLUE (:3100) ACTIVE | GREEN (:3101) IDLE
[ INFO ] Building image tag versiongate-web-app:v14 from git commit 8f92a1c...
[ INFO ] Launching target container slot GREEN on host port 3101
[ OK ] Health check passed: http://127.0.0.1:3101/health returned 200 OK in 14ms
[ OK ] Atomically reloaded Nginx upstream config versiongate_web-app -> 127.0.0.1:3101
[ INFO ] Decommissioned legacy container slot BLUE (:3100)
[ OK ] Deployment completed with 0 ms downtime.
API Telemetry Payload[ 200 OK ]
{
  "status": "SUCCESS",
  "jobId": "job_4912",
  "project": "web-app",
  "environment": "production",
  "slot": "GREEN",
  "port": 3101,
  "durationMs": 1420,
  "healthCheck": {
    "status": 200,
    "latencyMs": 14
  }
}

Capabilities

Engine surface area, command-ready.

Filter by category and copy the CLI that drives each capability.

Filter:
DeploymentCore Engine

Blue-Green Zero Downtime

Atomic idle slot container compilation and Nginx upstream reload with zero HTTP request loss.

versiongate deploy --project web-app --env production
Deploymentv2.3 Feature

Vercel Platform Structural Overhaul

Complete structural overhaul featuring top scope bar, horizontal sub-nav, 4-column telemetry hero matrix, and grid/table view modes.

versiongate ui overhaul --layout vercel-platform
Deploymentv1.4 Feature

Instant Warm-Swap Rollback

Sub-second rollbacks reusing locally cached Docker image tags without git re-pulling or context rebuilds.

versiongate rollback --project web-app --env production
Networkingv1.4 Feature

Stage Path Reverse Proxy

Reverse proxies stage environments cleanly on /p/:projectName/:stage without exposing raw host ports.

versiongate proxy add --path /p/web-app/staging
Securityv1.4 Feature

Bearer API Access Tokens

SHA-256 hashed persistent vg_live_... API Bearer tokens for external CI/CD workflow automation.

versiongate tokens create --name 'GitHub Actions CI'
Securityv2.1 Feature

CLI & Dashboard Password Management

Self-hosted CLI password reset tools and in-dashboard administrator password management.

bun run reset-password admin@example.com 'NewPass123!'
Monitoringv2.2 Feature

Vercel Geist Obsidian Visual Remodel

Full platform aesthetic redesign featuring Geist typography, #000000 obsidian dark canvas, hairline cards, and solid white CTAs.

versiongate theme set --preset vercel-geist
Monitoringv1.5 Feature

In-Process Worker & Base Href Proxy

Embedded worker for Docker/single-process installs; PM2 splits API and worker with explicit queue ownership.

versiongate worker start --auto-heal
Monitoringv1.4 Feature

Native Background Health Audit

Continuous background thread auditing DB connection latency, Redis locks, container states, and disk/RAM limits.

versiongate monitor status
Securityv1.4 Feature

Per-Environment Variable Overrides

Stage-specific environment variables for dev, staging, and prod overriding global project environment defaults.

versiongate env set --env staging --key DB_HOST --val staging-db
Securityv1.4 Feature

GitHub App Relay & Custom Manifests

Dual GitHub integration supporting zero-config central cloud relay or 1-click custom GitHub App Manifest creation.

versiongate github mode --type relay
Deploymentv1.8 Feature

Multi-Stage Git Webhook Auto-Deploy

Automatic multi-stage deployments targeting staging, dev, and production based on Git push ref.

versiongate webhook test --branch staging
Deploymentv1.8 Feature

Bun Text Lockfile & Multi-Runtime Dockerfiles

Native Dockerfile generation supporting modern text bun.lock, bun.lockb, go.mod without go.sum, and Node package-lock.

versiongate build --detect
Deploymentv1.9 Feature

Non-Blocking Async Engine Self-Update

Background self-update pipeline streaming live build logs with zero connection drops and graceful PM2 / standalone reload.

versiongate system update --async
Monitoringv1.9 Feature

Zero-Flicker Dashboard & Smart Scroll

SWR-style silent data revalidation, clean slot metrics, and intelligent terminal scroll locking without layout shifts.

versiongate dashboard status
Securityv2.0 Feature

Automated Host Certbot & TLS Provisioning

1-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 bash

Pipeline

From signed webhook to Nginx reload.

Trace ingestion through Redis locks, idle-slot builds, health gates, and atomic upstream swaps.

01 // Git Webhook IngressStep 1 of 5

GitHub webhook sends a signed POST payload (/api/webhooks/github) verified with HMAC SHA-256.

System Operation Payload
X-Hub-Signature-256: sha256=8f92a1c...

Install

Two files.
Zero rewrite.

Bootstrap one host, then trigger deploys from CI with a Bearer token.

install.shStep 1 of 2
curl -fsSL https://versiongate.tech/install.sh | sudo bash
deploy.ymlStep 2 of 2
curl -X POST "$VG_URL/api/v1/deploy" \
  -H "Authorization: Bearer $VG_TOKEN" \
  -d '{"project":"web-app","env":"production"}'

Knowledge base

Verified answers from the field.

Troubleshooting threads with concrete snippets for proxy paths, rollbacks, and token scopes.

Nginx[ ACCEPTED SOLUTION ]

How does VersionGate switch traffic atomically without dropping active requests?

Asked by dinesh_k · 2 days ago
When deploying a new version to the green container slot on port 3101, how does VersionGate avoid dropping HTTP requests currently hitting the blue slot on port 3100?
Verified Engine Solution:

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
Rollbacks[ ACCEPTED SOLUTION ]

Why is the warm-swap rollback under 2 seconds?

Asked by alex_dev · 3 days ago
When I trigger a rollback to a previous deployment version, why is it so much faster than a fresh deployment?
Verified Engine Solution:

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, ...);
}
API Tokens[ ACCEPTED SOLUTION ]

How do I authenticate GitHub Actions to trigger deployments without logging in?

Asked by devops_sam · 5 days ago
I want to trigger VersionGate deployments from a GitHub Actions workflow on PR merge. How do I generate and use API tokens?
Verified Engine Solution:

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"}'
Docker[ ACCEPTED SOLUTION ]

What happens if a newly deployed container crashes on startup?

Asked by marcus_b · 1 week ago
If I deploy a broken code change that causes Node/Python to crash-loop on container launch, does VersionGate tear down my working production app?
Verified Engine Solution:

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.
Troubleshooting[ ACCEPTED SOLUTION ]

How to resolve 'port already allocated' errors on manual container restarts?

Asked by chen_wei · 1 week ago
I get a Docker port allocation error when attempting to force restart a container bound to port 3100. How does VersionGate handle port collisions?
Verified Engine Solution:

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

One service.
One deploy window.

See what zero downtime feels like when rollback already has the image.