Monitor a Django Site With Uptime Kuma

Self-host Uptime Kuma to monitor Django: add HTTP checks against a health endpoint with keyword matching, monitor TLS expiry, use push monitors for Celery beat and cron jobs, send alerts to email, Slack, or Telegram, and publish a status page.

Problem statement

You need to know within a minute or two when the Django site is down, when HTTPS certificates are about to expire, and when scheduled jobs silently stop running, without paying per monitor. Uptime Kuma is a self-hosted monitoring tool with a web UI, many check types, dozens of notification channels, and status pages. Pointed at the right Django endpoints, it covers availability, certificates, and job heartbeats.

Uptime Kuma for DjangoHTTP check/healthz/ + keywordTLS expirydays remainingPush monitorscron, beatAlertsemail, Slack, TelegramActive checks catch outages; push monitors catch jobs that stop running.
  1. Run Uptime Kuma with Docker on a server separate from the app: docker run -d -p 127.0.0.1:3001:3001 -v uptime-kuma:/app/data louislam/uptime-kuma:1.
  2. Add an HTTP(s) keyword monitor for https://shop.example.com/healthz/ expecting a word such as ok.
  3. Enable certificate expiry notifications on HTTPS monitors.
  4. Create push monitors for Celery beat, cron jobs, and backups, and call their URLs at the end of each run.
  5. Configure notifications and a public or private status page.

Step-by-step solution

1. Deploy Uptime Kuma

docker volume create uptime-kuma
docker run -d --restart=unless-stopped --name uptime-kuma \
  -p 127.0.0.1:3001:3001 -v uptime-kuma:/app/data louislam/uptime-kuma:1

Put it behind a reverse proxy with TLS, or reach it through a VPN. Run it on a different server or provider from the Django app, so a host or network outage does not take down the monitor too.

2. Monitor the health endpoint

Add a monitor of type HTTP(s) - Keyword:

  • URL: https://shop.example.com/healthz/
  • Keyword: ok
  • Interval: 60 seconds, retries: 2

A Django health view that checks the database and cache and returns ok lets the keyword check catch application failures, not just "the server answered". Avoid pointing it at the home page: it may be cached by a CDN and keep looking healthy while Django is down.

monitor type and what it catchesTypeCatchesHTTP keyword /healthz/active, every 60 sapp and DB downTLS expiryon HTTPS monitorrenewal failuresPush: Celery beatpassive heartbeatscheduler stoppedPush: nightly backuppassive heartbeatbackup not runTCP: Postgres (private)active, from VPNdatabase unreachableActive checks find outages; heartbeats find silent failuresdjango-deployment.com
A job that stops running produces no error; only a missing heartbeat reveals it.

3. Watch certificate expiry

In the HTTPS monitor settings, enable Certificate Expiry Notification and choose days (for example 21, 14, 7). With Let's Encrypt renewing at 30 days before expiry, a warning at 21 days means renewal has been failing for over a week.

4. Push monitors for jobs

Create a monitor of type Push; Uptime Kuma shows a URL. Call it when a job finishes successfully:

# in a management command or Celery task
import requests

def heartbeat(url):
    try:
        requests.get(url, timeout=5)
    except requests.RequestException:
        pass  # monitoring must never break the job

def handle(self, *args, **options):
    run_nightly_report()
    heartbeat(os.environ["KUMA_PUSH_NIGHTLY_REPORT"])

Set the monitor's heartbeat interval slightly longer than the job's schedule (for example 25 hours for a daily job). If the ping does not arrive, Uptime Kuma alerts. For Celery beat, schedule a small task every 5 minutes that pings a push monitor; it proves both beat and a worker are running.

5. Notifications and status page

Add notification channels (email via SMTP, Slack, Microsoft Teams, Telegram, Discord, PagerDuty, webhooks) and attach them to monitors. A status page groups monitors for customers or internal teams; publish it on a subdomain such as status.example.com.

setup order1Deploy on a separate hostDocker, TLS proxy2Add /healthz/ keyword check60 s interval3Turn on TLS expiry alerts21, 14, 7 days4Push monitors for jobsbeat, cron, backups5Notifications + status pagetest an alertTest each alert path once so you know it reaches someonedjango-deployment.com
Pause monitors during planned maintenance to avoid alert fatigue.

Explanation

Uptime Kuma runs scheduled checks from wherever it is hosted and keeps history in a local SQLite database (or MariaDB in newer versions). Active monitors (HTTP, TCP, DNS, ping) detect when something stops responding. Push monitors invert the direction: your jobs report in, and silence triggers the alert, which is the only reliable way to notice that a scheduled task stopped running. Together they cover the failures Django's own error tracking cannot see.

Edge cases / notes

  • Single location. Checks come from one place; network problems near the monitor can cause false alerts. Combine with an external service for critical sites if needed.
  • Backups. Back up the uptime-kuma volume; it holds monitors, history, and notification settings.
  • Health endpoint cost. Keep the health view cheap; it runs every minute.

Next steps

FAQ

Should Uptime Kuma run on the same server as Django?

No. Run it elsewhere so it can report when the app's server is down.

What URL should I monitor?

A dedicated health endpoint that checks the database and returns a known keyword, not a cached page.

How do I monitor Celery beat?

Schedule a small periodic task that calls a push monitor URL; missing pings mean beat or the workers stopped.

Does Uptime Kuma check SSL certificates?

Yes. Enable certificate expiry notifications on HTTPS monitors.

Keep going