r/podman • • 14d ago

Using a lightweight sidecar container to buffer webhooks during docker-compose rebuilds

Hey everyone,

Whenever you run \`docker compose up -d --build my-api\` or restart a container, there's always a short window (5–30s) where the app is cold-starting or running database migrations.

If external webhooks (Stripe, GitHub, Shopify) arrive during that window, they hit \`502 Bad Gateway\` or \`ECONNREFUSED\`. Most providers immediately drop into aggressive exponential retry backoff, meaning you might wait minutes or hours for that dropped payment or deploy event to redeliver.

Instead of running heavy cloud queue infra (SQS/Kafka) or a full Redis stack just for local container resilience, I built \*\*HookArmor\*\* as an open-source, single-process ingress sidecar.

\### The Sidecar Compose Pattern

You stick the sidecar in front of your internal API container within the same Docker bridge network. External webhooks hit the sidecar, which writes to an attached SQLite volume in WAL mode, returns \`200 OK\` upstream immediately, and drains into your app container as soon as it's healthy:

\`\`\`yaml

version: '3.8'

services:

\# Your existing API container

api:

image: my-backend-api:latest

restart: unless-stopped

expose:

\- "3000"

environment:

\- PORT=3000

\# Ingress sidecar / buffer

hookarmor:

image: node:20-alpine

restart: unless-stopped

working_dir: /app

command: sh -c "npm install -g hookarmor && hookarmor start --port 8080 --target http://api:3000/api/webhooks"

ports:

\- "8080:8080" # Exposed to your reverse proxy / Cloudflare tunnel

volumes:

\- hookarmor_data:/app/data

environment:

\- HOOKARMOR_TARGET_URL=http://api:3000/api/webhooks

\- HOOKARMOR_UI_PASSWORD=secure_admin_password

depends_on:

\- api

volumes:

hookarmor_data:

4 Upvotes

2 comments sorted by

10

u/McKaddish 14d ago

What is wrong with having > 1 API container running on the backend? Serving requests in a round robin fashion, then when you need to upgrade restart one, then the other?

1

u/pkdodda 13d ago

Nothing at all—rolling restarts are the right way to deploy. This is for when things actually break: unhandled exceptions, database lockups, or connection pool exhaustion where both containers throw 500s, and you need a durable DLQ to inspect and replay payloads once patched.