A Hands-Off Server — The Small cron Automations That Keep It Running

Written by

in

Self-Hosting Build Guide, Part 14 (final). Backups (Part 12) and sync (Part 13) all have to run “at a set time, on their own.” That engine is cron.

← Previous: Part 13 — My Notes on My Server (Obsidian LiveSync)
→ Next: Part 15 — The Link That Won’t Tap (Telegram→Obsidian)

TL;DR

  • cron is the built-in Linux scheduler that runs commands at set times — nothing to install
  • What our server does on its own every day: backup · DB dump · cache cleanup · health check · summary
  • One crontab line = minute, hour, day, month, weekday + the command to run
  • Trap 1: cron has almost no PATH → without absolute paths you get “command not found”
  • Trap 2: silent failure — if you don’t log, you find out days later that it never ran

1. What cron Is — an Alarm Clock With Nothing to Install

cron ships with Linux by default. Register a time and a command — “run this script at 4:30 every morning” — and as long as the machine is on, it runs on its own. In self-hosting, almost every repetitive chore can be handed to cron.

2. Reading One crontab Line

The list of jobs is called the crontab. One line is five time fields + a command.

Field Meaning Range
1 minute 0–59
2 hour 0–23
3 day 1–31
4 month 1–12
5 weekday 0–6 (0=Sun)

A * means “every.” So 30 4 * * * means 4:30 every day.

30 4 * * *   /home/user/bin/db-dump.sh    >> /var/log/db-dump.log 2>&1
0  5 * * *   /home/user/bin/backup.sh      >> /var/log/backup.log 2>&1
Anatomy of one crontab line The example line 30 4 * * * /home/user/bin/db-dump.sh >> log 2>&1 split into its parts. The first five fields are minute, hour, day, month and weekday, which together mean 4:30 every day. An asterisk means every. Next comes the command to run, written with an absolute path (Trap 1), and the last part sends output and errors to a log file (Trap 2). The time follows the server clock, so on a UTC server it may run in the early afternoon your time (Trap 3). One crontab line = five time fields + a command 30 4 * * * /home/user/bin/db-dump.sh >> logfile 2>&1 minute hour day month weekday Command to run Output + errors to a file Trap ①: use absolute paths Trap ②: keep a log = 4:30 every day * means “every” Trap ③: the time follows the server clock. If the server is on UTC, it may run in the early afternoon your time.
Figure 1. One crontab line split into its parts: five time fields, then the command, with the spot where each of the three traps bites.

3. What Our Server Does Every Day

Small cron jobs stack up into a “hands-off server.”

  • DB dump — the database to a safe file (before the backup)
  • File backup — shipped to a NAS (Part 12)
  • Cache cleanup — clear piled-up temp files and expired cache
  • Health check — is the service alive? alert if it died
  • Summary — yesterday’s visitors and errors on one page
Five small cron jobs that run every day cron on the left runs five jobs at set times every day. DB dump saves the database to a safe file and runs before the backup (example 04:30). File backup ships files to a NAS (example 05:00). Cache cleanup clears piled-up temp files and expired cache. Health check confirms the service is alive and alerts if it died. Summary puts yesterday’s visitors and errors on one page. Stacked together, they make a server that takes care of itself without daily hands-on work. Five small cron jobs that run on their own every day cron runs at set times every day DB dump File backup Cache cleanup Health check Summary Database to a safe file (before the backup) Shipped to a NAS (Part 12) Clear piled-up temp files and expired cache Is the service alive? Alert if it died Yesterday’s visitors and errors on one page e.g. 04:30 e.g. 05:00 Stacked up: a server that takes care of itself
Figure 2. The five things our server does on its own every day. The two times come from the crontab example in Section 2; the post sets no time for the other three, so they are left blank.

4. The Three Traps Beginners Always Hit

① No PATH. A command that worked fine in your terminal dies under cron with “command not found.” cron runs in a minimal environment with a nearly empty PATH. Fix: use absolute paths (/usr/bin/python3), or set PATH at the top of your script.

② Silent failure. cron won’t show errors on screen. By default it only mails them, and nobody reads that. So, as in the example above, redirect with >> logfile 2>&1 to capture output and errors to a file — that’s how you trace a job that didn’t run.

③ Time zone. Check whether the server clock is UTC or your local time. Aim 30 4 * * * at “4:30 a.m.” and, if the server is on UTC, it may actually run in the early afternoon your time.

5. The Compounding of Small Automations

Each cron job is trivial — one line for backup, one for cache cleanup. But they stack, and the server reaches a state where it takes care of itself without you touching it daily. That’s the whole goal of self-hosting: build it, and let it keep running even after you forget about it.

This series comes full circle here too. We started with an empty computer (Part 1), put up a blog, attached a domain, locked it down, backed it up, and now made it run on its own. What’s left is to stand one up yourself.


In One Line

cron is the engine behind “at a set time, on its own.” One line: minute, hour, day, month, weekday + command. Watch just three things — use absolute paths, keep logs, and check the time zone. Stack up small automations and the server stops needing your hands.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *