tutorial

Monitoring Caddy Web Server with Vigilmon: Admin API Health, HTTPS Certificates & Reverse Proxy Uptime

How to monitor Caddy web server with Vigilmon — admin API health checks, automatic HTTPS certificate monitoring, reverse proxy uptime, and alerting for Caddy-fronted services.

Caddy is a modern web server famous for automatic HTTPS — it provisions and renews TLS certificates from Let's Encrypt and ZeroSSL without any configuration. But "automatic" doesn't mean "invisible": if your ACME challenge fails, your certificate renewal silently breaks, or your upstream service goes down behind Caddy's reverse proxy, users see errors without any alert reaching you. Vigilmon gives you external visibility into Caddy's health — the admin API, the HTTPS certificates Caddy manages, and the upstream services it proxies.

What You'll Build

  • A monitor on Caddy's admin API health endpoint
  • SSL certificate monitoring for every domain Caddy serves
  • Uptime checks for services running behind Caddy's reverse proxy
  • An alerting setup that distinguishes Caddy failures from upstream failures

Prerequisites

  • A running Caddy server with at least one site (HTTPS recommended — Caddy handles this automatically)
  • Access to the Caddy admin API (default: http://localhost:2019)
  • A free account at vigilmon.online

Step 1: Verify Caddy's Admin API

Caddy exposes a REST admin API on port 2019 by default. The /config/ endpoint returns the current Caddy configuration — a lightweight health signal that proves Caddy is running and its config is loaded:

curl http://localhost:2019/config/

A healthy Caddy returns the current JSON configuration (or null for a fresh default config). A non-200 response or connection refused means Caddy is down.

Security: The admin API binds to localhost by default and should not be exposed to the internet. For external Vigilmon monitoring, either:

  1. Preferred: Create a thin internal health endpoint (see Step 3) and monitor it externally.
  2. Alternative: Use a Vigilmon agent on the same machine to probe localhost:2019 and report status.

Step 2: Expose a Public Health Endpoint via Caddy

The cleanest approach is to serve a lightweight health endpoint through Caddy itself — this validates both Caddy's HTTP serving and its admin status simultaneously:

Add this to your Caddyfile:

your-domain.com {
  handle /health {
    respond "ok" 200
  }
  
  reverse_proxy /api/* localhost:3000
  # ... rest of your config
}

Or if you want richer health data, route to a small health service:

your-domain.com {
  handle /health/caddy {
    reverse_proxy localhost:2019 {
      rewrite /config/
    }
  }
}

After reloading Caddy (caddy reload), this endpoint is accessible externally at https://your-domain.com/health.


Step 3: Create a Vigilmon HTTP Monitor for Caddy

  1. Log in to VigilmonAdd Monitor → HTTP.
  2. URL: https://your-domain.com/health (the health endpoint you exposed in Step 2).
  3. Check interval: 60 seconds.
  4. Response timeout: 10 seconds.
  5. Expected status: 200.
  6. Keyword: ok (matches the response body from the respond directive).
  7. Click Save.

This monitor validates:

  • Caddy is running and accepting connections
  • HTTPS termination is working (TLS handshake succeeds)
  • Caddy's routing is correctly serving your health handler
  • DNS is resolving to your server

Step 4: Monitor SSL Certificates for Every Domain

Caddy's automatic HTTPS is one of its best features, but certificate renewal can fail silently if:

  • ACME challenge files can't be written (disk full, permissions issue)
  • Port 80 is blocked (needed for HTTP-01 ACME challenges)
  • Your domain's DNS stops resolving correctly
  • Let's Encrypt rate limits are hit

Add an SSL monitor for every domain Caddy serves:

  1. Add Monitor → SSL Certificate.
  2. Domain: your primary domain (e.g., your-domain.com).
  3. Alert when expiry is within: 30 days (Let's Encrypt certificates last 90 days; Caddy renews at 30 days — this gives you early warning if renewal is failing).
  4. Alert again: 14 days, 7 days, 3 days, 1 day.
  5. Repeat for each domain in your Caddyfile.

Why 30 days? Caddy attempts renewal at 30 days before expiry. If your SSL monitor alerts at 30 days, Caddy's renewal is already failing. This gives you a full 30-day window to diagnose and fix the issue before users see certificate errors.


Step 5: Monitor Upstream Services Behind the Reverse Proxy

Caddy is often used as a reverse proxy in front of application servers. When the upstream goes down, Caddy returns a 502 Bad Gateway. Add separate monitors for each upstream service:

Direct upstream check (from inside the network, if Vigilmon agent is available):

Create a Vigilmon monitor on the upstream's local address:

  • URL: http://localhost:3000/health (your app's health endpoint)
  • This catches cases where Caddy is up but the upstream is down

External check through Caddy:

  • URL: https://your-domain.com/api/health
  • Expected status: 200
  • Keyword: something specific to your API's health response (e.g., "status": "ok")
  • Interval: 60 seconds

When this monitor fails, compare with the Caddy health monitor from Step 3:

  • Both down → Caddy itself is down or DNS is broken
  • Caddy health OK but API health down → upstream application failure
  • Caddy health OK but API returns 502 → upstream is down, Caddy is routing correctly but has no backend

This distinction is invaluable during incidents — it tells you immediately whether to restart Caddy or restart your application.


Step 6: Monitor Caddy's Automatic HTTPS with a Heartbeat

Caddy logs certificate renewal events. Use a cron job to monitor Caddy's certificate status and send a Vigilmon heartbeat:

#!/bin/bash
# /etc/cron.d/caddy-cert-heartbeat
# Run every 6 hours — checks all managed certificates

CADDY_CERTS=$(curl -s http://localhost:2019/config/ | python3 -c "import sys, json; print('ok')" 2>&1)

if [ "$CADDY_CERTS" = "ok" ]; then
  curl -fsS -X POST https://vigilmon.online/api/heartbeat/YOUR-HEARTBEAT-ID
fi

Create a Heartbeat monitor in Vigilmon with a 12-hour grace period. If Caddy's admin API becomes unreachable (process crashed, port conflict), the heartbeat stops and you get an alert.


Step 7: Monitor Multiple Vhosts

If Caddy hosts multiple virtual hosts, add individual monitors for each:

https://app1.example.com/health     → Monitor: "App 1 via Caddy"
https://app2.example.com/health     → Monitor: "App 2 via Caddy"
https://api.example.com/v1/health   → Monitor: "API via Caddy"

Label each monitor clearly. When an alert fires, you'll know immediately which vhost is affected rather than SSHing in to investigate.


Step 8: Configure Alerting

In Vigilmon under Settings → Notifications, set up your alert channels:

| Monitor | Trigger | Action | |---|---|---| | Caddy health endpoint | Non-200 or keyword missing | Check systemctl status caddy; review journalctl -u caddy | | SSL certificate < 30 days | Expiry warning | Check Caddy logs for ACME errors; verify port 80 is open | | Upstream health (direct) | Non-200 | Restart the application service | | API health through Caddy | 502 or non-200 | Upstream is down; Caddy routing is fine | | Caddy admin heartbeat | Missed > 12 h | Caddy process likely crashed; restart it |

Alert after: 1 consecutive failure for SSL alerts (there's no good reason for a 30-day-to-expiry situation). 2 consecutive failures for HTTP monitors (brief network blips can cause a single false positive).


Common Caddy Failure Modes and What Vigilmon Catches

| Scenario | Vigilmon monitor | |---|---| | Caddy process crashes | Health endpoint unreachable; alert within 60 s | | ACME challenge fails → certificate expires | SSL monitor alerts at 30 days | | Upstream app crashes → 502 from Caddy | API monitor fires; Caddy health monitor stays green | | Disk full → Caddy can't write ACME files | Certificate stops renewing; SSL monitor alerts | | DNS misconfigured → domain unreachable | Both health and SSL monitors fire | | Port 80 blocked → HTTP-01 challenge fails | SSL monitor catches it at 30-day window | | Caddyfile syntax error → reload fails | Health endpoint may still serve old config; admin heartbeat catches process state |


Caddy's automatic HTTPS and zero-downtime reloads make it a remarkably low-maintenance web server. But "low maintenance" should mean "rarely needs attention" — not "never monitored." Vigilmon gives Caddy the external oversight it deserves: watching the admin API, every certificate it manages, and every service it proxies, so you catch problems long before your SSL certificate expires or your users see a 502.

Start monitoring Caddy in under 5 minutes — register free at vigilmon.online.

Monitor your app with Vigilmon

Free plan — 5 monitors, no credit card required. Up and running in 60 seconds.

Start free →