GoatCounter is a fast, privacy-friendly, open-source web analytics platform designed to be easy to self-host. It runs as a single Go binary with built-in SQLite storage — minimal dependencies, maximum control. But that simplicity comes with a monitoring obligation: when GoatCounter goes down, you lose real-time visibility into your site traffic. Vigilmon keeps watch on your GoatCounter instance around the clock with HTTP uptime checks, API health monitors, SSL alerts, and cron heartbeats.
What You'll Set Up
- HTTP uptime monitor for the GoatCounter dashboard
- API endpoint health check
- SSL certificate expiry alert
- TCP port check as a lightweight secondary monitor
- Heartbeat monitoring for scheduled data export and backup jobs
Prerequisites
- GoatCounter deployed (binary or Docker, version 2.x recommended)
- A free Vigilmon account
- Your GoatCounter instance URL and access to the host
Step 1: Monitor the GoatCounter Dashboard
GoatCounter serves the analytics dashboard and the data-collection API from a single HTTP server. Add an uptime check against the dashboard URL:
- Log in to vigilmon.online and click Add Monitor.
- Set Type to
HTTP / HTTPS. - Enter your GoatCounter URL:
https://stats.yourdomain.com. - Set Check interval to
1 minute. - Set Expected HTTP status to
200. - Click Save.
GoatCounter responds with a redirect to the login page if you're not authenticated — that redirect still returns 200 at the final URL, so an unauthenticated uptime check is sufficient to confirm the server is alive.
Step 2: Monitor the GoatCounter Count API
GoatCounter's tracking script hits /count to record page views. A healthy response here confirms the Go process is accepting traffic and can write to SQLite. Use Vigilmon's keyword monitor to validate it:
- Click Add Monitor → HTTP / HTTPS.
- Set the URL to
https://stats.yourdomain.com/count. - Set Method to
GET. - Set Expected HTTP status to
400— GoatCounter returns400 Bad Requestfor a GET with no payload, which still confirms the endpoint is alive and reachable. - Under Keyword check, enter
hitto match the error body GoatCounter returns on a malformed request. - Click Save.
Alternatively, if you prefer a 200 check, use GoatCounter's built-in ping route:
https://stats.yourdomain.com/api/v0/me
Send a request with your API token header (Authorization: Bearer YOUR_API_TOKEN) and expect a 200 response with your site details.
Step 3: SSL Certificate Alerts
GoatCounter can use Let's Encrypt automatically (via the -tls letsencrypt flag) or be placed behind a TLS-terminating reverse proxy. Add a certificate expiry alert either way:
- Open the HTTP monitor created in Step 1.
- Enable Monitor SSL certificate.
- Set Alert when certificate expires in less than
21 days. - Click Save.
If you rely on GoatCounter's built-in Let's Encrypt support, check that port 80 is open for the HTTP-01 challenge. GoatCounter requests certificates on startup if the current certificate will expire within 30 days.
Step 4: TCP Port Monitor
A TCP monitor catches networking failures that an HTTP monitor may miss — for example, a firewall rule accidentally blocking port 443 after a server update:
- Click Add Monitor → TCP.
- Set Host to
stats.yourdomain.com. - Set Port to
443. - Set Check interval to
1 minute. - Click Save.
A TCP failure alongside an HTTP failure narrows the cause to the network layer; an HTTP failure with a passing TCP check narrows it to the application.
Step 5: Heartbeat Monitoring for Backups and Exports
GoatCounter stores data in SQLite by default. Regular backups and scheduled CSV exports are critical for data durability. Wrap these jobs with a Vigilmon heartbeat:
- In Vigilmon, click Add Monitor → Cron Heartbeat.
- Set the expected ping interval to your backup frequency (e.g.
1440minutes for daily). - Copy the heartbeat URL, e.g.
https://vigilmon.online/heartbeat/abc123.
For a daily SQLite backup:
#!/bin/bash
# /etc/cron.daily/goatcounter-backup
set -e
# Online backup using GoatCounter's built-in command
goatcounter db backup -db sqlite:///var/lib/goatcounter/goatcounter.sqlite3 \
/backups/goatcounter-$(date +%F).sqlite3
# Signal success
curl -s https://vigilmon.online/heartbeat/abc123
For a scheduled export via the API:
#!/bin/bash
curl -s -o /exports/goatcounter-$(date +%F).csv \
-H "Authorization: Bearer YOUR_API_TOKEN" \
"https://stats.yourdomain.com/api/v0/export"
curl -s https://vigilmon.online/heartbeat/abc123
If the job exits before the ping, Vigilmon alerts you after the expected interval — before the next backup window opens.
Step 6: Configure Alert Channels
- Go to Alert Channels in Vigilmon and add your preferred notification channel (Slack, email, or webhook).
- Set Consecutive failures before alert to
2on the dashboard HTTP monitor to handle brief container restart windows. - Set Consecutive failures before alert to
1on the API monitor — a/countendpoint failure means page views are being dropped.
Automate maintenance windows around GoatCounter upgrades:
# Open maintenance window before upgrade
curl -X POST https://vigilmon.online/api/maintenance \
-H "Authorization: Bearer YOUR_VIGILMON_API_KEY" \
-d '{"monitor_id": "YOUR_MONITOR_ID", "duration_minutes": 5}'
# Upgrade GoatCounter
systemctl stop goatcounter
wget https://github.com/ychaouche/goatcounter/releases/latest/download/goatcounter-linux-amd64
mv goatcounter-linux-amd64 /usr/local/bin/goatcounter
chmod +x /usr/local/bin/goatcounter
systemctl start goatcounter
Summary
| Monitor | Target | What It Catches |
|---|---|---|
| HTTP uptime | https://stats.yourdomain.com | Binary crash, OOM kill |
| API health | https://stats.yourdomain.com/count | Endpoint unresponsive, DB failure |
| SSL certificate | GoatCounter domain | Let's Encrypt renewal failure |
| TCP port | :443 | Firewall or network issue |
| Cron heartbeat | Heartbeat URL | Backup or export job failure |
GoatCounter is one of the leanest self-hosted analytics options available — and with Vigilmon watching it, you'll know the instant it needs attention before your site owners start asking where their stats went.