[{"data":1,"prerenderedAt":186},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-healthchecks-cron-monitoring-vps-ma-en":6,"promo-bar-likely":20},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-healthchecks-cron-monitoring-vps-ma-en",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":20,"publishedAt":21,"updatedAt":22,"category":23,"categories":29,"featuredImage":31,"bgImage":32,"posterImage":33,"relatedSolution":34,"intro":37,"sections":38,"ctaTitle":120,"ctaBody":121,"ctaButton":122,"ctaUrl":123,"relatedPosts":124},504,"self-host-healthchecks-cron-monitoring-vps",{"fr":12,"en":10,"ar":13,"es":14},"self-host-healthchecks-vps","استضافة-healthchecks-على-vps-مراقبة-مهام-cron","autoalojar-healthchecks-monitorizar-cron-vps","Self-Host Healthchecks: Cron Job Monitoring on a VPS","Install Healthchecks on a VPS: every cron job, backup or scheduled task sends a ping, and you are alerted as soon as one is missing, fails or runs too long.",6,0,false,true,"2026-10-24T00:00:00+00:00","2026-11-04T16:30:29+00:00",{"id":24,"name":25,"slug":26,"color":27,"icon":28},7,"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[30],{"id":24,"name":25,"slug":26,"color":27,"icon":28},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-healthchecks-vps-poster.svg",{"categorySlug":35,"appSlug":36},"monitoring-observability","healthchecks","A cron job that stops running makes no noise. The nightly backup fails, log cleanup stops, a supplier sync breaks — and nothing warns you, because nothing runs. Healthchecks is an open-source (BSD-3 licensed) tool that flips the problem around: each job sends a ping when it finishes, and Healthchecks alerts you when that ping does not arrive. This guide installs it as a single Docker container on a VPS, puts it behind an HTTPS reverse proxy and wires up a first cron job.",[39,43,53,85,88,104,108,111,114,117],{"type":40,"title":41,"body":42},"h2","Why monitor what must run, not just what responds","An uptime monitor checks that a service responds. It cannot see what happens between two requests: the 3 a.m. backup, invoice sending, a certificate renewal, the export to your accountant. These jobs fail silently — a full disk, an expired password, a server rebooted without its timer — and you notice on the day you need them.\n\nCron's `MAILTO` variable barely helps: it only sends a message if the job runs and writes to its output, and says nothing when the job never starts. Healthchecks starts from absence: every job has an expected schedule, and silence beyond the grace time triggers the alert.",{"type":44,"title":45,"items":46},"ul","What Healthchecks brings",[47,48,49,50,51,52],"**Ping-based monitoring** — each job calls a unique URL; a missing ping triggers the alert.","**Cron or period schedules** — a cron expression with time zone, or a simple interval, plus a grace time.","**Run duration** — `\u002Fstart` and `\u002Ffail` pings measure duration and report explicit failures.","**Exit codes and logs** — the exit code and the tail of the command output, viewable in the dashboard.","**More than twenty integrations** — email, webhook, Slack, Discord, Matrix, ntfy, Telegram, Gotify, PagerDuty, Opsgenie…","**Team and API** — separate projects, invited members, status badges and a REST API to create checks from your scripts.",{"type":54,"title":55,"headers":56,"rows":60},"comparison","Healthchecks compared with common approaches",[5,57,58,59],"Healthchecks","Cron MAILTO","Uptime monitor",[61,65,69,72,76,81],[62,63,64,64],"Alert if the job never starts","Yes","No",[66,67,68,64],"Alert if the job fails","Yes, exit code or \u002Ffail","Only if it writes output",[70,71,64,64],"Run duration","Measured",[73,74,63,75],"Machines with no open port","Yes, a simple outbound HTTPS call","No, the target must be reachable",[77,78,79,80],"Alert channels","More than twenty integrations","Local email","Depends on the tool",[82,83,64,84],"Central history","Yes, per check","Yes, for services",{"type":40,"title":86,"body":87},"Prerequisites","An Ubuntu 24.04 VPS with **1 GB of RAM** is enough: Healthchecks runs as a single container and stores its data in an SQLite database. You need Docker with the Compose plugin, and a **domain name** pointing to the VPS, with nginx and an HTTPS certificate: ping URLs and alert links are built on that address, and the application rejects requests sent to another name.\n\nIdeally, install Healthchecks on a machine **separate** from the servers it watches: if it goes down with them, nobody will warn you.",{"type":89,"title":90,"steps":91},"steps","Install Healthchecks with Docker Compose",[92,95,98,101],{"title":93,"body":94},"Prepare the .env file","Create the application directory and a `.env` file holding the secret key and the public address. Replace `hc.example.com` with your domain.\n```bash\nmkdir -p \u002Fopt\u002Fhealthchecks && cd \u002Fopt\u002Fhealthchecks\ncat > .env \u003C\u003CEOF\nSECRET_KEY=$(openssl rand -hex 24)\nSITE_ROOT=https:\u002F\u002Fhc.example.com\nEOF\n```",{"title":96,"body":97},"Create the Compose file","Put this `docker-compose.yml` in the same directory. The port is published on the loopback only, public sign-up is closed and the SQLite database lives in a volume.\n```yaml\nservices:\n  healthchecks:\n    image: healthchecks\u002Fhealthchecks:v5.0.1\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:8102:8000\"\n    env_file: .env\n    environment:\n      DEBUG: \"False\"\n      DB_NAME: \u002Fdata\u002Fhc.sqlite\n      REGISTRATION_OPEN: \"False\"\n      GUNICORN_WORKERS: \"2\"\n    volumes:\n      - healthchecks-data:\u002Fdata\nvolumes:\n  healthchecks-data: {}\n```",{"title":99,"body":100},"Start and create the administrator account","On start, the container runs the migrations, then launches the web server and the alert-sending processes. Then create your account: the command asks for an email address and a password.\n```bash\ndocker compose up -d\ndocker compose exec healthchecks .\u002Fmanage.py createsuperuser\n```",{"title":102,"body":103},"Publish over HTTPS behind nginx","Add a `server` block for your domain, with a Let's Encrypt certificate, and forward the origin headers: without `X-Forwarded-Proto`, login fails with a CSRF error.\n```nginx\nlocation \u002F {\n    proxy_pass http:\u002F\u002F127.0.0.1:8102;\n    proxy_set_header Host $host;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n}\n```",{"type":105,"title":106,"body":107},"tip","Keep sign-up closed","By default, Healthchecks accepts public sign-ups. `REGISTRATION_OPEN: \"False\"` closes them: only the accounts you create or invite into a project can log in. On a server exposed to the Internet, set this from the very first start.",{"type":40,"title":109,"body":110},"Wire up your cron jobs","In the dashboard, create a check, enter the schedule — the job's cron expression and its time zone — then a grace time covering its normal duration. Copy the ping URL and append it to the job.\n```bash\n# crontab: backup at 3 a.m., ping only on success\n0 3 * * * \u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh && curl -fsS -m 10 --retry 5 -o \u002Fdev\u002Fnull https:\u002F\u002Fhc.example.com\u002Fping\u002F\u003Cuuid>\n\n# variant: signal the start, then send the exit code\nURL=https:\u002F\u002Fhc.example.com\u002Fping\u002F\u003Cuuid>\ncurl -fsS -m 10 --retry 5 -o \u002Fdev\u002Fnull \"$URL\u002Fstart\"\n\u002Fusr\u002Flocal\u002Fbin\u002Fbackup.sh > \u002Ftmp\u002Fbackup.log 2>&1\ncurl -fsS -m 10 --retry 5 -o \u002Fdev\u002Fnull --data-binary @\u002Ftmp\u002Fbackup.log \"$URL\u002F$?\"\n```\n\nThe first form pings only on success: a failure shows up as a missing ping, hence an alert after the grace time. The second is more telling: `\u002Fstart` measures the duration, the exit code sent in place of the ping reports failure immediately, and the output sent in the request body appears in the check's history. The `-m 10 --retry 5` options keep a flaky network from blocking the job or faking an outage.",{"type":40,"title":112,"body":113},"Receive the alerts","Under **Integrations**, add at least one channel you actually read, then attach it to your checks. Webhook, Slack (incoming webhook), Mattermost, ntfy and Gotify work without any server-side configuration. Other integrations need credentials declared in `.env`: a bot token for Telegram, an account and token for Matrix, an OAuth app for Discord.\n\n**Email** alerts go through an SMTP server: add `EMAIL_HOST`, `EMAIL_PORT`, `EMAIL_HOST_USER`, `EMAIL_HOST_PASSWORD` and `DEFAULT_FROM_EMAIL` to `.env`, then restart with `docker compose up -d`. The same settings serve team invitations and periodic reports.",{"type":40,"title":115,"body":116},"Troubleshooting","**The page returns a 400 error.** The request does not arrive with the right host name: check that `SITE_ROOT` exactly matches the domain served by nginx, and that the `location` block forwards the `Host` header.\n\n**Login fails with a CSRF error.** nginx does not forward `X-Forwarded-Proto`: the application thinks it receives HTTP while the browser speaks HTTPS. Add the header and reload nginx.\n\n**A check goes into alert although the job ran.** The ping did not leave: run the `curl` command by hand from the machine concerned, check outbound HTTPS access, and lengthen the grace time if the job lasts longer than expected.\n\n**No email arrives.** Without `EMAIL_HOST`, Healthchecks sends nothing and says so in its logs at start-up: check `docker compose logs healthchecks`.",{"type":40,"title":118,"body":119},"One-click install from the ServOrbit Marketplace","The ServOrbit Marketplace installs Healthchecks on your VPS without a command line: it deploys the container with sign-up closed, creates the administrator account with a generated password, and publishes the application over HTTPS on a subdomain of your domain or on the VPS's free subdomain. The login and password appear in your client area; all that is left is to create your checks.","Your scheduled jobs under watch, on your own VPS","A ServOrbit Ubuntu 24.04 VPS with 1 GB of RAM is enough for Healthchecks. One-click install from the Marketplace, HTTPS on your domain or on the VPS's free subdomain, administrator account created for you.","Install Healthchecks","\u002Fapplications\u002Fmonitoring-observability\u002Fhealthchecks",[125,146,169],{"id":126,"slug":127,"slugs":128,"title":132,"excerpt":133,"readTime":134,"views":135,"isPinned":19,"noindex":19,"publishedAt":136,"updatedAt":137,"category":138,"categories":143,"featuredImage":31,"bgImage":32,"posterImage":145,"relatedSolution":31},230,"cron-vs-systemd-timers-automate-your-linux-vps",{"fr":129,"en":127,"ar":130,"es":131},"cron-systemd-timers-automatisation-vps","cron-مقابل-systemd-timers-أتمتة-vps-linux","cron-vs-systemd-timers-automatizar-vps-linux","cron vs systemd timers: Automate Your Linux VPS","Practical comparison of cron and systemd timers: syntax, logs, migration and troubleshooting for recurring tasks on a Linux VPS.",12,1,"2026-08-06T00:00:00+00:00","2026-09-20T21:13:53+00:00",{"id":139,"name":140,"slug":141,"color":142,"icon":141},2,"Automation","automatisation","bg-brand-action\u002F10 text-brand-action",[144],{"id":139,"name":140,"slug":141,"color":142,"icon":141},"\u002Fblog\u002Fcovers\u002Fcron-systemd-timers-automatisation-vps-poster.svg",{"id":147,"slug":148,"slugs":149,"title":153,"excerpt":154,"readTime":155,"views":139,"isPinned":19,"noindex":19,"publishedAt":156,"updatedAt":157,"category":158,"categories":164,"featuredImage":31,"bgImage":32,"posterImage":166,"relatedSolution":167},194,"self-host-ntfy-on-a-vps-push-notifications-for-scripts-and-cicd",{"fr":150,"en":148,"ar":151,"es":152},"self-host-ntfy-vps","استضافة-ntfy-على-vps-إشعارات-فورية-من-سكريبتاتك-وcicd","autoalojar-ntfy-en-un-vps","Self-host ntfy on a VPS: push notifications for scripts and CI\u002FCD","Deploy ntfy on your VPS and send push notifications from any script, cron job or CI\u002FCD pipeline with a plain curl — no SaaS, no API key, no subscription.",16,"2026-07-28T00:00:00+00:00","2026-11-04T16:30:26+00:00",{"id":159,"name":160,"slug":161,"color":162,"icon":163},8,"Security & Monitoring","securite-monitoring","bg-rose-500\u002F10 text-rose-400","security",[165],{"id":159,"name":160,"slug":161,"color":162,"icon":163},"\u002Fblog\u002Fcovers\u002Fself-host-ntfy-vps-poster.svg",{"categorySlug":35,"appSlug":168},"ntfy",{"id":170,"slug":171,"slugs":172,"title":176,"excerpt":177,"readTime":159,"views":18,"isPinned":19,"noindex":19,"publishedAt":178,"updatedAt":179,"category":180,"categories":181,"featuredImage":31,"bgImage":32,"posterImage":183,"relatedSolution":184},105,"monitoring-your-vps-with-uptime-kuma",{"fr":173,"en":171,"ar":174,"es":175},"superviser-vps-uptime-kuma","مراقبة-خادمك-الافتراضي-vps-باستخدام-uptime-kuma","supervisar-vps-con-uptime-kuma","Monitoring your VPS with Uptime Kuma","Deploy Uptime Kuma on your VPS to monitor your sites and services self-hosted, with alerts and a public status page.","2026-03-07T00:00:00+00:00","2026-11-09T20:55:19+00:00",{"id":159,"name":160,"slug":161,"color":162,"icon":163},[182],{"id":159,"name":160,"slug":161,"color":162,"icon":163},"\u002Fblog\u002Fcovers\u002Fsuperviser-vps-uptime-kuma-poster.svg",{"categorySlug":35,"appSlug":185},"uptime-kuma",1794270487140]