-
Notifications
You must be signed in to change notification settings - Fork 0
Deployment
Three good options. Pick by ops preference.
Cheapest, predictable, full control.
docker build -t webhook-to-email .
docker run -d \
--name webhook \
--restart unless-stopped \
-p 3000:3000 \
--env-file .env \
webhook-to-emaildocker-compose up -ddocker-compose.yml ships in the repo with a healthcheck on /health.
| Provider | Spec | Monthly cost | Notes |
|---|---|---|---|
| Hetzner CX22 | 2 vCPU, 4GB | €4 | Cheapest sane option |
| Fly.io | shared 1x | $0 (small) - $5 | Global edge, good for multi-region |
| Render | starter | $7 | Heroku-feel, simple deploys |
| Railway | hobby | $5 | Easy Postgres if you add a queue |
| DigitalOcean | basic droplet | $6 | Familiar |
Hetzner is the price/perf winner in 2026.
Caddyfile:
your-domain.com {
reverse_proxy localhost:3000
}
Run Caddy via systemd. HTTPS provisioned automatically by Let's Encrypt.
Auto multi-region. Free tier covers small apps.
fly launch
# follow prompts, accept defaults
fly secrets set RESEND_API_KEY=re_... NOTIFY_EMAIL=you@... WEBHOOK_SECRET=...
fly deployfly.toml is auto-generated. Default config is reasonable: 1 instance, auto-stop on idle.
fly scale count 2 # 2 instances for HA
fly scale memory 256 # 256MB per instanceFree tier covers ~3 small apps. Beyond that, ~$2/month per shared 1x instance.
Web service, auto-deploy on push.
- New → Web Service → Connect repo
- Environment: Node
- Build:
npm install - Start:
npm start - Add env vars in Settings
- Free tier sleeps after 15 min idle (wakes in ~20s)
For always-on, upgrade to $7/month starter.
All three platforms accept custom domains. DNS:
CNAME hooks.your-domain.com → your-app.fly.dev (or render URL or VPS IP via A record)
Then point Stripe / GitHub / Cal.com webhooks at https://hooks.your-domain.com/hooks/<source>.
curl https://your-domain.com/health
# {"ok":true}
curl -X POST https://your-domain.com/hooks/test \
-H "Content-Type: application/json" \
-d '{"hello":"world"}'
# {"ok":true}Email should arrive in 2-3 seconds.
Track:
| Metric | Why |
|---|---|
| Request rate per source | Detect anomalies |
| Email send error rate | Resend issues |
| 401 rate | Wrong secret or attack |
| 500 rate | Bugs in templates |
| P95 latency | Performance regression |
Tools:
- BetterStack Logs — structured log aggregation, free tier good
- Axiom — same idea, cheaper at scale
- Sentry — error tracking, useful for template exceptions
- Plausible / Umami — overkill for a webhook receiver
Real numbers for a typical setup:
| Item | Per month |
|---|---|
| Hetzner CX22 | €4 |
| Resend (3,000 emails free, then $20 for 50k) | £0 - £15 |
| Domain | £0.50 |
| Total | £4 - £20 |
For 10,000 webhooks/month with email forwarding, well under £20 all-in.