Skip to Content
Kido Bag
Domain Combo SuitesPillar 2. High-Concurrency & Caching

@kido/zero-downtime-deploy

Universal Zero-Downtime Deployment & Rollout Toolkit - Blue-Green Atomic Swap, Linux Kernel Inode Directory Swap, Caddy Edge Hold-and-Retry Buffer, and Shadow Canary.

@kido/zero-downtime-deploy

Architecture Paradigm: Single-VPS Blue-Green Pre-Warm Promotion + Linux Inode Atomic Directory Swap + Caddy Reverse Proxy Hold-and-Retry TCP Buffer + Automated Rollback Healthcheck Gate + Shadow Parity & Canary Error Verification.


💥 The Real-World Bottleneck

Deploying updates to single VPS instances or container clusters without enterprise orchestration often introduces noticeable downtime and broken user sessions:

  1. The "Docker Recreate" 502 Downtime Window:
    # The Naive Disaster: Stopping the running container before starting the new one
    docker compose down && docker compose up -d
    During the 5 to 45 seconds while V8 compiles and database connection pools warm up, all incoming client HTTP requests receive 502 Bad Gateway or connection refused errors.
  2. The Frontend Inode Inconsistency Window: Copying new static chunks directly into a public webroot (rsync -avz ./dist/ /var/www/html/) takes 2-5 seconds. Users requesting HTML receive references to JavaScript chunks that have not yet arrived on disk, resulting in ChunkLoadError crashes.
  3. The Poisoned Release Crash-Loop: If a newly deployed container has a missing environment variable or database connection error, it crashes immediately on startup. Without automated health probes and rollback scripts, production remains completely offline until engineers intervene manually.

🏛️ 3-Tier Production Evolution Ladder

Scale DimensionTier 1 (SME Zero-Infra)Tier 2 (Growth & Commercial SaaS)Tier 3 (Big-Tech Standard)
ArchitectureSingle-VPS Blue-Green Pre-Warm + Frontend Inode SwapBlue-Green Pre-Warm + Caddy Hold-and-Retry BufferZero-Gap Network-Alias Swap + Shadow Parity Diff + Canary Gate
Infra & Cost\$5/mo (Single Linux VPS, \$0 Kubernetes)\$20 - \$50/mo (Single/HA VPS + Caddy)\$100 - \$300+/mo (Multi-Node Cluster)
Downtime Duration0ms Frontend, < 50ms backend rename0.00ms Absolute Downtime, 0 dropped TCP sockets0.00ms Absolute Downtime, 0 DNS propagation gaps
RAM Utilization1x RAM 24/7 (2x RAM for ~10s during pre-warm)1x RAM 24/7 (Caddy buffers in-flight sockets)Dedicated shadow and canary execution pools
Rollback SafetyAutomated health probe with container rollbackEdge Next-Action scanner blocker + Instant revert5x parallel shadow queries + 10s log canary audit
Architecture BlueprintMermaid
Compiling architecture diagram...

📦 Architecture & Core API Exports

@kido/zero-downtime-deploy provides end-to-end zero-downtime deployment scripting and runtime controllers:

1. Atomic Blue-Green Container Swap (src/index.ts)

  • generateAtomicSwapBeScript(config): Produces a robust bash script starting app_next, validating /health for up to 45 seconds, executing an atomic rename sequence (api $\to$ api_old, api_next $\to$ api), draining active connections, and auto-rolling back if the candidate fails.
  • generateAtomicSwapFeScript(config): Emits a Linux kernel inode swap script (mv staging target) that switches the frontend directory in < 1ms with zero partial-read windows.
  • performHealthCheck(url, options): Programmatic health probe validating HTTP status and response body tokens with configurable timeouts.

2. Caddy Edge Hold-and-Retry Buffer (src/caddy-reload.ts)

  • generateCaddyZeroDowntimeSnippet(options): Configures Caddy's upstream load balancer to hold incoming TCP connections and retry up to 5 seconds (lb_try_duration 5s, lb_try_interval 150ms) during the container rename gap.
  • generateCaddyNextJsActionGuardSnippet(): Edge WAF block returning HTTP 403 for malicious automated scans probing Next.js Server Actions.
  • buildInodeSafeCaddyReloadCmd(): Inode-safe Caddy container reload command.

3. Graceful Process Draining (src/graceful-shutdown.ts)

  • setupGracefulShutdown(server, options): Registers SIGTERM and SIGINT handlers on Node.js/Bun servers, closing HTTP listener sockets, draining active keep-alive connections, and disconnecting database pools gracefully.

4. Shadow Parity & Canary Error Gate (src/shadow-canary.ts)

  • runShadowParityCheck(options): Replays production read-only traffic with X-Shadow-Probe headers against the candidate to pre-warm JIT caches and verify database schema parity.
  • buildShadowAndCanaryBashGate(options): Automated bash gate enforcing a 10-second live canary bake and checking logs for panics before completing deployment.

💻 Production Implementation & Code Snippet

Express / Hono Graceful Shutdown & Caddyfile Integration

import { createServer } from 'node:http';
import { Hono } from 'hono';
import { setupGracefulShutdown } from '@kido/zero-downtime-deploy';

const app = new Hono();

app.get('/health', (c) => {
  // Healthcheck endpoint probed by CI/CD before atomic promotion
  return c.json({ status: 'ok', version: process.env.APP_VERSION || 'v2' });
});

app.get('/api/orders', async (c) => {
  return c.json({ orders: [] });
});

const server = createServer(app.fetch);

// Install Graceful Shutdown Controller (Connection Draining)
const shutdownController = setupGracefulShutdown(server, {
  timeoutMs: 10000, // 10-second drain window
  onShutdown: async (signal) => {
    console.log(`Received ${signal}. Draining database connections...`);
    await db.$disconnect();
    await redis.quit();
  },
});

server.listen(3000, () => {
  console.log('API Server running on port 3000');
});

Caddyfile Zero-Downtime Reverse Proxy Configuration

# /etc/caddy/Caddyfile
(zero_downtime_proxy) {
    lb_policy round_robin
    lb_try_duration 5s
    lb_try_interval 150ms
    fail_duration 10s
    max_fails 1
}

api.kido.vn {
    reverse_proxy api:3000 {
        import zero_downtime_proxy
    }
}

⚡ Benchmark & Verified k6 Performance

Stress-tested under simulated 2,500 active HTTP requests during a live container promotion:

Deployment StrategyTotal HTTP Requests502 / Connection ErrorsMax Latency During Swap
Standard docker compose up -d2,500318 dropped (12.7%)Connection refused
Blue-Green without Buffer2,5008 dropped (0.32%)850 ms
@kido/zero-downtime-deploy (Tier 2/3)2,5000 dropped (0.00%)180 ms (Buffered & Retried)
Frontend Static Directory Swap10,000 requests0 ChunkLoadErrors< 1 ms (Kernel Inode Swap)
Corrupt Release Auto-RollbackCI/CD testActive pod preserved (100%)Zero customer impact

🚀 Surgical Extraction & CLI Installation

# Install directly via Kido CLI
npx @kido/cli add @kido/zero-downtime-deploy

On this page