Use code for 20% launch discount. Lifetime licenses include complete source code.Copy code

Migration guide

Move EasyCron, cron-job.org, and GitHub Actions timers onto a scheduler you host

Most hosted cron is a crontab string and an HTTP ping. You can run that next to the app it calls, on a machine you already pay for.

Self-hosted NexusCron scheduler used as a cloud cron replacement

EasyCron, cron-job.org, and GitHub Actions scheduled workflows all sit outside the box that actually does the work. That path holds URLs, bearer tokens, and run history. When the bill is monthly, you are renting a timer. NexusCron is the same architecture on your host: schedule, HTTP fire, retry, SQLite logs.

Target architecture

  1. 01

    Host

    Docker on a VPS or home server. Same network as the job target when you can.

  2. 02

    Store

    SQLite volume for jobs and run history. Back it up with the rest of the disk.

  3. 03

    Fire

    Cron expression plus HTTP GET/POST. Timeouts and retries in config, not a plan tier.

  4. 04

    Observe

    Status codes, bodies, and retry counts on disk. Replay from the UI or API.

Hosted cron vs NexusCron

ConcernCloud cron SaaSNexusCron
Where the timer runsVendor account (EasyCron, cron-job.org, GitHub Actions cron)Container on a VPS or home box you already keep up
Job storeVendor dashboard, export if they still offer itSQLite on disk you back up with the rest of the host
HTTP pingsTheir egress to your URL, timeouts and concurrency by planLocal HTTP from the same network as the app it wakes
Secrets in headersStored in the hosted job definitionEnv file next to Compose. Never leaves the host
LogsLast N runs in a vendor UI, then goneRun history in SQLite you can query and retain
LimitsJob caps, request caps, minute granularity by tierYour CPU, disk, and network
Cost after year oneStill monthly, often $20–$50 for a real job listZero. License is one payment

Docker Compose

Put the data volume on the same disk you already back up. Secrets stay in cron.env, not in the image.

services:
  nexuscron:
    image: nexuscron:latest
    restart: unless-stopped
    ports:
      - "127.0.0.1:8787:8787"
    environment:
      TZ: Europe/Madrid
      NEXUSCRON_DATA: /data
      NEXUS_TELEMETRY: "off"
      CRON_ADMIN_TOKEN: \${CRON_ADMIN_TOKEN}
    volumes:
      - ./data:/data
      - ./jobs.json:/app/jobs.json:ro
      - ./cron.env:/run/secrets/env:ro

Production environment

Set TZ to the zone your cron expressions assume. Rotate CRON_ADMIN_TOKEN like any other admin secret.

# cron.env (chmod 600)
CRON_ADMIN_TOKEN=replace-me
TZ=Europe/Madrid
# Optional: HMAC on inbound health pings
CRON_PING_SECRET=replace-me
# Optional: default timeout for HTTP jobs
CRON_HTTP_TIMEOUT_MS=15000

jobs.json

One object per hosted timer. Keep the same cron string and URL so cutover is a pause on the vendor side, not an app change.

{
  "jobs": [
    {
      "id": "billing-reconcile",
      "cron": "15 3 * * *",
      "timezone": "Europe/Madrid",
      "http": {
        "url": "http://billing.internal/jobs/reconcile",
        "method": "POST",
        "headers": { "Authorization": "Bearer ${BILLING_TOKEN}" }
      },
      "retry": { "max": 3, "backoff_ms": 2000 }
    },
    {
      "id": "uptime-ping",
      "cron": "*/5 * * * *",
      "http": {
        "url": "https://app.yourdomain.com/internal/health",
        "method": "GET"
      }
    }
  ]
}

Cutover without missed pings

  1. Export every hosted job (expression, URL, headers).
  2. Bring NexusCron up. Confirm /health.
  3. Load jobs.json. Run one job immediately.
  4. Dual-run for one interval if the endpoint is idempotent.
  5. Pause EasyCron / cron-job.org. Keep the CSV until you trust SQLite.
# 1. Health
curl -sS -o /dev/null -w "%{http_code}\\n" http://127.0.0.1:8787/health

# 2. Load jobs and fire one now
curl -sS -X POST http://127.0.0.1:8787/api/jobs/uptime-ping/run \\
  -H "Authorization: Bearer $CRON_ADMIN_TOKEN"

# 3. After a clean day, pause EasyCron / cron-job.org entries
# Keep their export CSV next to jobs.json until you trust the table

Related setup page: Self-hosted cron alternative.

NexusCron

Own the scheduler

$94.99one-time

  • Source license for NexusCron
  • Docker Compose and jobs.json examples
  • HTTP jobs, retries, SQLite history
  • No monthly job or request caps
Buy NexusCron

Checkout stays on Whop. You get the source after payment.

Questions people ask before they switch

Do I still need crontab on the box?

No. NexusCron is the scheduler. Keep systemd or Compose restarting the container. crontab is optional for a single ping; this is for a dashboard, logs, and HTTP jobs you can edit without SSH.

Can I dual-run EasyCron during cutover?

Yes. Recreate jobs in NexusCron pointing at the same URLs. Let both fire for one interval if the endpoint is idempotent, then pause the cloud jobs.

What about GitHub Actions scheduled workflows?

If the workflow is only an HTTP ping or a script you already run on a VPS, move it here. Keep Actions for CI that needs GitHub’s runners.

Where do failed runs go?

The run table on disk. Open the job, read the status code and body, then retry from the UI or POST /api/jobs/{id}/run.

Keep reading

Guide

Self-hosted cron alternative

Stop paying a monthly bill to fire HTTP on a timer. NexusCron is a self-hosted cron alternative you deploy with Docker on machines you already own.

Guide

EasyCron and cron-job.org alternative

Compare EasyCron, cron-job.org, and other hosted cron products with NexusCron. Same job, no subscription, logs and secrets stay on your disk.

Guide

Migrate off EasyCron to a self-hosted runner

Step-by-step migration from EasyCron to a self-hosted cron runner. Export jobs, map cron expressions, Docker Compose, HTTP pings, and cutover without downtime.

Guide

Migrate cron jobs off cloud providers to self-hosted

Technical guide for migrating cron jobs off cloud providers to self-hosted NexusCron. Architecture, Docker Compose, job mapping, and cutover without missed pings.

Guide

Migrate EasyCron jobs to self-hosted NexusCron

Architecture, Docker Compose, and cost math for replacing $20–$50/month hosted cron with NexusCron on a VPS you already run. One lifetime payment.

Guide

Self-hosted webhook router

A self-hosted webhook router that receives, transforms, and forwards events on your infrastructure. One payment. No Zapier tax for simple routing.

Guide

Replace cloud webhook services with self-hosted Webhook Router

Architecture, Docker Compose, and config mapping to replace Hookdeck, Svix, Zapier, and Make with NexusCore Webhook Router on your VPS. One lifetime payment.

Guide

Replace cloud webhook queues with local SQLite routing

Technical architecture for replacing cloud webhook queues with local SQLite routing. Production Docker Compose, under 50MB RAM, WAL mode, retries, and dead-letter replay.

Guide

Self-hosted pipeline setup

NexusPipeline is a FastAPI Docker execution engine. Clone it, compose up, and keep job state on disk you control. One payment. No worker SaaS.

Guide

Self-hosted admin dashboard setup

NexusAdmin is the self-hosted dashboard that sits next to NexusPipeline. One payment, Docker Compose, no SaaS admin tenant.

Guide

Self-hosted log stream setup

LogStream is a single-binary Node.js collector. HTTP and UDP ingest, SQLite, live dashboard, webhook alerts. One payment. No observability SaaS.

Guide

Self-hosted env sync setup

EnvSync Agent syncs .env values across VPS hosts, laptops, and microservices. Encrypted key-value store. One payment. No secrets tenant.

Guide

Self-hosted API proxy setup

API Proxy Service sits between your code and upstream APIs. Retries, rate limits, fallbacks, circuit breakers. One payment. No gateway SaaS.