Cron has been scheduling Unix jobs since the 1970s, and it is not going anywhere. But the way we run cron jobs has shifted: from bare-metal servers to Docker containers, from crontab files to CI/CD YAML, and from cron.d to Kubernetes CronJobs. Here is what changed — and what has not.
1. Cron Inside Docker
Docker containers prefer a single foreground process, so running a cron daemon inside a container feels unnatural. Three modern approaches:
-
Host cron +
docker exec: Run cron on the host, and have each entry invokedocker exec container command. Zero container changes, works today. - supercronic: A drop-in crontab-compatible runner that logs to stdout/stderr. Perfect for containers whose log drivers expect stdout.
- ofelia: A Docker-native scheduler that reads job config from container labels instead of a crontab file.
2. CI/CD Cron: GitHub Actions & Friends
GitHub Actions, GitLab CI, and Jenkins all support cron-triggered pipelines. The syntax is identical to standard 5-field cron:
# GitHub Actions — runs every weekday at 9 AM UTC
on:
schedule:
- cron: "0 9 * * 1-5"
Key difference: CI/CD schedulers use UTC by default, not your local timezone. A 0 0 * * * job that reads "midnight" actually fires at midnight UTC — which may be 8 PM your time. Always verify the timezone offset.
3. The Classic Traps Have Not Changed
Some mistakes transcend the platform:
-
Weekday numbering:
0is Sunday (POSIX), but Quartz Scheduler and some libraries start at1for Sunday. Check your platform convention. - OR logic: When both day-of-month AND day-of-week are set, the job fires when EITHER matches — not both. This catches everyone at least once.
-
Minimal environment: Cron runs without your shell PATH, aliases, or environment variables. Use absolute paths and set
SHELL=/bin/bash.
Quick tip: I use a free visual cron generator to build expressions, see human-readable descriptions, and preview the next 5 execution times before pasting into production. Beats memorizing field order at 2 AM.
What is the worst cron bug you have deployed? Mine was a timezone mismatch that sent customer emails at 3 AM local time instead of 9 AM.
Top comments (0)