Server

The server is a Linux box that holds your crons and runs them. It runs two small services behind Caddy: a sync API the local scripts upload to, and a scheduler that runs each cron when its schedule is due. You stand it up once.

The box

Any Linux box with systemd works. A small VPS is plenty. What matters is its public IP address. The local scripts point at that address to upload your crons, and Caddy issues a self-signed certificate for the IP so the sync API is reachable over HTTPS without a domain name. Note the IP down before you start.

Install the two dependencies first

The installer checks for Caddy and Node, and it stops if either is missing. It never installs them for you, so put both on the box first.

Caddy

Install it from a package so its systemd unit exists. Cronhoster configures Caddy through that unit to terminate TLS in front of the sync API.

Node v20+

Both services are Node applications. Version 20 or newer is required.

Run the bootstrap

With Caddy and Node in place, run the bootstrap as root:

curl -fsSL https://cronhoster.org/install.sh | sudo bash
Download the verified bundle and run the installer as root.

The script downloads a verified bundle and runs the installer. The installer writes an API token to /opt/localhoster/cronhoster/cronhoster-token and prints it once. Copy it now. The local config needs it to authenticate uploads.

The token is printed a single time during install. If you miss it, re-read it with sudo cat /opt/localhoster/cronhoster/cronhoster-token.

What the installer sets up

The installer leaves two systemd services running and Caddy configured in front of them.

ServiceWhat it does
cronhoster-api The sync API. It listens on localhost only, and Caddy fronts it for TLS by IP. The local scripts upload your crons here, authenticating with the token.
cronhoster-runner The scheduler. It watches the content root, discovers cron directories, and runs each one's cronhoster-cron-handler.js when the clock matches its settings.

The content root is /opt/localhoster/cronhoster/cronhoster-crons. Crons run as a dedicated non-root user, so a runaway cron cannot touch the rest of the box.

Managing the server

Both services are ordinary systemd units, so systemctl manages them:

systemctl status cronhoster-api
systemctl restart cronhoster-runner
Check the sync API, restart the scheduler.

Re-read the API token at any time:

sudo cat /opt/localhoster/cronhoster/cronhoster-token
Print the stored API token.

To upgrade, re-run the bootstrap. It preserves the token, your synced crons, and the logs.

Next steps