A Docker cron alternative that also monitors Kubernetes CronJobs

Stop running cron daemons inside containers. Trigger your jobs from outside with SteadyCron, or keep your existing Docker/K8s cron and just monitor it with a heartbeat.

The problem

Cron inside a container is a recurring source of pain: the daemon needs its own process babysitting in an otherwise single-process image, logs get trapped inside the container's stdout instead of your aggregator, and the container's timezone silently drifts from what you expect. Kubernetes CronJobs fix the daemon problem but not the visibility one — a CronJob that silently stops creating Pods (a paused schedule, a bad image, an exhausted backoff limit) fails completely silently. Nothing in kubectl tells you a job *should* have run an hour ago.

How SteadyCron solves it

  1. 1 Option A — move the trigger outside the container entirely: expose a simple HTTP endpoint in your app and let SteadyCron call it on schedule, with retries and a timeout. No cron daemon, no extra process, no timezone surprises inside the image.
  2. 2 Option B — keep your existing Docker cron or Kubernetes CronJob, and add a heartbeat: the job pings SteadyCron's ping URL on success (or /fail on error) as its last step.
  3. 3 Either way, SteadyCron tracks expected vs. actual: if the ping (or HTTP call) doesn't arrive within the grace period you set, the check goes from on-time to missed.
  4. 4 You get alerted the moment a CronJob stops firing — not when someone notices the nightly report didn't show up.
# Add to an existing Kubernetes CronJob: ping on success, alert on missed/failed
command: ["/bin/sh", "-c"]
args:
  - >
    ./run-job.sh &&
    curl -fsS https://ping.steadycron.com/$PING_TOKEN ||
    curl -fsS https://ping.steadycron.com/$PING_TOKEN/fail
app.steadycron.com/jobs

Jobs

New job
Search jobs…
All HTTP Heartbeat
Status Group: env
env:prod 5 jobs 1 failing
weekly-digest-email HTTP 0 9 * * 1 in 2 days 3 days ago
nightly-db-backup Heartbeat 0 2 * * * in 19 h 5 h ago
stripe-reconciliation HTTP 0 */4 * * * in 38 min 3 h ago
cache-warmup HTTP */15 * * * * in 11 min now
search-index-sync Heartbeat */30 * * * * in 6 min 24 min ago
env:dev 3 jobs
seed-test-data HTTP 0 4 * * * in 14 h 10 h ago
preview-env-cleanup Heartbeat 0 */6 * * * in 2 h 4 h ago
trial-expiry-sweep HTTP 0 6 * * * yesterday

Every job's status, schedule, and last run — at a glance.

Two ways to fix container cron, depending on what you control

If you own the app code: drop the in-container cron entirely. Add an HTTP endpoint that runs the job’s logic, and let SteadyCron call it on a schedule from outside the container — with its own retry/backoff and a full request log. The container goes back to running one process, the way it’s supposed to, and the schedule lives in SteadyCron instead of in a crontab file that has to survive every image rebuild.

If you don’t want to touch the trigger (a Kubernetes CronJob someone else owns, a Docker entrypoint you’d rather not refactor right now): leave it running and add a heartbeat check. One curl at the end of the script, and SteadyCron knows whether the job ran — and pages you the moment it doesn’t, instead of you finding out from a downstream symptom.

Why container cron specifically breaks this way

  • Docker: a cron daemon inside a container is a second long-running process competing with the PID 1 your orchestrator actually supervises. If the daemon dies, the container looks healthy — docker ps shows it running — while nothing inside it is actually firing.
  • Kubernetes CronJobs: the schedule itself is reliable (the controller is part of the control plane), but failure is invisible by design. A CronJob that hits its backoffLimit, a startingDeadlineSeconds that’s too tight for a busy cluster, or a bad image tag all fail the same way: no Pod, no error in your dashboards, just a job that quietly stopped happening.

See the platform-specific breakdowns if you’re debugging right now: Docker cron not running · Kubernetes CronJob not running.

A good fit for

  • Nightly batch jobs, backups, and report generation currently triggered by a cron daemon baked into a Docker image.
  • Kubernetes CronJobs for cleanup, sync, or maintenance tasks where a missed run is easy to overlook until it compounds.
  • Teams moving toward a “schedule lives outside the container” model so scaling, redeploying, or migrating clusters doesn’t risk losing the schedule along with the Pod.

Related documentation

Stop finding out the hard way

Start on the free tier — no credit card required.

Start free