Deployment guide

Crontab UI

Overview

Crontab UI is an open-source web interface for managing cron jobs. Instead of hand-editing crontab text over SSH, you create, edit, pause, resume, run, import, export, back up and restore scheduled jobs from a browser, with a clear view of every job's schedule and command. This guide covers deploying and configuring it on Ubuntu 24.04 on Azure with the SecureAnyCloud Azure Marketplace image.

Crontab UI ships upstream with no authentication, which would let anyone who can reach it schedule or run arbitrary commands on your server. This image turns authentication on and generates a unique administrator credential on each virtual machine's first boot. The credential is written to a root-only file. No shared or default credentials exist, and the service refuses to start without a credential, so the open mode can never ship.

Crontab UI manages the crontab of the dedicated crontabui service account rather than root's, so your scheduled jobs run without root privileges. Saving a job in the interface writes it straight to that real crontab (autosave is on).

What you get:

  • The latest stable Crontab UI release, installed from the npm registry with the exact version pinned in /opt/crontab-ui/VERSION. It runs on Node.js 22 LTS under systemd as the unprivileged crontabui system user.
  • Crontab UI bound to loopback only (127.0.0.1:8000), so it is never exposed to the network directly.
  • nginx as the sole network-facing surface. It terminates TLS on port 443 and reverse proxies to Crontab UI on 127.0.0.1:8000, with HSTS and sensible security headers. Port 80 redirects to HTTPS.
  • Port :80 returns a 301 redirect to HTTPS for every path except an unauthenticated /healthz endpoint (HTTP 200) for load balancer probes.
  • Authentication on by default with a unique admin credential generated per VM on first boot and written to a root-only file.
  • The system cron daemon, installed and enabled so that the jobs scheduled for the crontabui account run.
  • A self-signed TLS certificate regenerated per VM on first boot. Its Subject Alternative Names include the VM IP, hostname and 127.0.0.1. Replace it with your own CA-signed certificate for production.
  • A built-in self-test at /usr/local/bin/crontab-ui-selftest that proves the round trip from creating a job to writing it to the managed crontab, end to end over TLS.
  • An Ubuntu 24.04 LTS base with the latest security patches applied at build time.
  • The Azure Linux Agent for cloud integration and SSH key injection.
  • 24/7 SecureAnyCloud support with a guaranteed 24 hour response SLA.

Prerequisites

  • An Azure subscription with permission to deploy virtual machines.
  • An SSH key pair for administrative access to the VM as the azureuser account.
  • A Network Security Group that allows inbound TCP 443 (HTTPS) and 80 (redirect) from the networks that should reach the service, and 22 (SSH) from your management network only.
  • A recommended VM size of Standard_B2s or larger.
1

Deploy from the Azure Portal

  • Find the Crontab UI on Ubuntu 24.04 LTS image in the Azure Marketplace and select Create.
  • Choose your subscription, resource group and region.
  • Select a VM size (Standard_B2s or larger) and provide your SSH public key for the azureuser account.
  • On the Networking tab, allow inbound 443 and 80 from your users, and restrict 22 to your management network.
  • Select Review + create. When the VM is running, browse to https://<your-public-ip>/.
2

Deploy from the Azure CLI

Deploy the image from the command line and restrict SSH to your management network. Replace the example values with your own:

# Accept the Marketplace terms once per subscription (required before the first CLI deploy)
az vm image terms accept --urn sac1647283583153:crontab-ui-ubuntu-24-04:default:latest
az vm create \
  --resource-group my-resource-group \
  --name crontab-ui \
  --image sac1647283583153:crontab-ui-ubuntu-24-04:default:latest \
  --size Standard_B2s \
  --admin-username azureuser \
  --ssh-key-values ~/.ssh/id_rsa.pub \
  --public-ip-sku Standard
# Allow the web UI from your users and SSH from your management network only
az vm open-port --resource-group my-resource-group --name crontab-ui --port 443 --priority 1001
az network nsg rule create --resource-group my-resource-group --nsg-name crontab-uiNSG \
  --name allow-ssh --priority 1002 --destination-port-ranges 22 \
  --source-address-prefixes <your-mgmt-cidr> --access Allow --protocol Tcp

When the VM is running, browse to https://<public-ip>/.

3

Retrieve your per-instance admin credential

Authentication is on by default. Each VM generates its own admin username and password on first boot and writes them to a root-only file. Read the file over SSH:

ssh azureuser@<vm-ip> 'sudo cat /root/crontab-ui-credentials.txt'

The file contains the CRONTAB_UI_USER, CRONTAB_UI_PASS and CRONTAB_UI_URL for this VM. Keep it secret. The credential lives only in this root-only file and in the service environment file, and is never baked into the image.

4

Sign in to the web interface

Browse to https://<vm-ip>/. The certificate is self-signed per VM, so your browser shows a certificate warning the first time. Accept it to proceed, or install the per-VM certificate, or place a CA-signed certificate in front as described in Step 10. Sign in with the username and password from Step 3.

Crontab UI opens the Cronjobs dashboard. It is a table of every scheduled job with its name, command, schedule and last modified time. A toolbar lets you create jobs, back up, import, export, and write the jobs to the real crontab.

5

Create a cron job

Click New to open the job form. Give the job an optional name and enter the command to run. Set the schedule with a quick preset (Every Minute, Hourly, Daily, Weekly and so on), or enter the minute, hour, day, month and week of month fields directly. The Job preview at the bottom shows the exact crontab line that will be written.

Autosave is enabled on this image, so saving a job writes it straight to the crontabui user's real crontab. You do not need to click Save to crontab. Use that button only if you prefer to apply a batch of changes at once.

6

Edit, run, pause and manage jobs

Each row in the dashboard has controls to Edit the job, Run now (run it immediately), Disable (pause it without deleting it), Duplicate and delete. Edit reopens the job form pre-filled with the job's current name, command and schedule.

Tick Enable error logging to have Crontab UI capture each run's standard output and error to per-job log files. You can view them from the dashboard to see why a job failed.

7

Preview what reaches the real crontab

Click Preview crontab at any time to see exactly what Crontab UI will deploy to the system crontab, including the logging wrappers it adds around each command. This is the real crontab content for the crontabui service account.

You can confirm the same content from the shell. On the VM, list the crontabui user's crontab:

sudo crontab -u crontabui -l 2>/dev/null | head -20 || echo "(no jobs scheduled yet — add one in the web UI)"
8

Verify the deployment

SSH to the VM as azureuser and confirm that the services are running and Crontab UI is bound to loopback only:

systemctl is-active crontab-ui nginx cron
sudo ss -tlnp | grep -E ':8000|:443 |:80 ' | sed 's/users:.*//'

All three services report active, and Crontab UI listens on 127.0.0.1:8000 only. nginx is the only component exposed on :80 and :443.

Run the built-in self-test. It reads this VM's credential and proves the full round trip over TLS. An unauthenticated request is refused, an authenticated request succeeds, and a cron job is created through the API, written to the crontabui user's real crontab, then removed:

sudo /usr/local/bin/crontab-ui-selftest
9

Check TLS and the per-instance certificate

nginx terminates TLS on port 443 and redirects plain HTTP on port 80 to HTTPS. Confirm the redirect, confirm that an unauthenticated request is refused, and confirm that a request carrying this VM's credential succeeds:

curl -s -o /dev/null -w 'port 80 -> HTTP %{http_code}\n' http://127.0.0.1/
curl -sk -o /dev/null -w 'unauthenticated -> HTTP %{http_code}\n' https://127.0.0.1/
U=$(sudo grep '^CRONTAB_UI_USER=' /root/crontab-ui-credentials.txt | cut -d= -f2-)
P=$(sudo grep '^CRONTAB_UI_PASS=' /root/crontab-ui-credentials.txt | cut -d= -f2-)
curl -sk -o /dev/null -w 'authenticated -> HTTP %{http_code}\n' -u "$U:$P" https://127.0.0.1/

Port 80 returns 301, an unauthenticated request returns 401, and a request with this VM's credential returns 200. The self-signed certificate is regenerated per VM on first boot, with the VM IP and hostname in its Subject Alternative Names.

10

Check the version and credential summary

The pinned version and this VM's credential summary are recorded on the VM. The command below redacts the password line. Read the full value from the root-only file in Step 3:

cat /opt/crontab-ui/VERSION
sudo sed 's/^CRONTAB_UI_PASS=.*/CRONTAB_UI_PASS=<redacted per-VM secret>/' /root/crontab-ui-credentials.txt | grep -E '^CRONTAB_UI_'
11

Replace the certificate for production

The per-VM certificate is self-signed, so browsers warn on first use. For a public deployment, put a real certificate in front. The simplest approach is to point a DNS name at the VM and obtain a free certificate with Certbot:

# Point https://<your-domain> at this VM first, then:
sudo apt-get install -y certbot python3-certbot-nginx
sudo certbot --nginx -d <your-domain>

Alternatively, terminate TLS at an Azure Application Gateway or a load balancer in front of the VM, and forward to port 443.

12

Back up, restore and manage jobs

  • Back up and restore. Use the Backup button in the toolbar to snapshot your jobs, and the Backups menu to restore a previous snapshot, so a mistaken edit is never final. Export downloads the job database and Import uploads it, which is handy for moving jobs between servers.
  • Import an existing crontab. If you already have jobs in the crontabui user's crontab, click Get from crontab to import them into the interface.
  • Review the managed crontab. By default Crontab UI manages the crontab of the unprivileged crontabui service account, which is the least-privilege default. The service definition is at /etc/systemd/system/crontab-ui.service. Its environment (bind address, autosave, database path and the per-VM credential) is in /etc/crontab-ui/crontab-ui.env.
  • Rotate the credential. Edit BASIC_AUTH_USER and BASIC_AUTH_PWD in /etc/crontab-ui/crontab-ui.env and restart the service. Alternatively, place your own identity-aware proxy in front.

Security notes

  • No default login. Authentication is on by default. A unique admin credential is generated on each VM's first boot into a root-only file and the service environment file. The service refuses to start without one.
  • Loopback-only application. Crontab UI binds to 127.0.0.1:8000 and is reachable only through the nginx TLS reverse proxy on :443. Keep it that way, and let nginx (or a load balancer) be the sole network-facing surface.
  • Least-privilege scheduling. Jobs are managed in the crontab of the unprivileged crontabui account, not root's. A cron management tool grants command execution to anyone who signs in, so treat the credential as highly sensitive and restrict who can reach the service.
  • Restrict access. Allow 443 only from the networks that need it, keep 22 restricted to your management network, and replace the self-signed certificate with a CA-signed one for production.
  • Always use HTTPS. A cron management interface over plaintext HTTP would expose the login credentials and let anyone schedule commands. Always reach it over TLS.

Support

This image is backed by 24/7 SecureAnyCloud support with a guaranteed 24 hour response SLA. Contact sales@secureanycloud.com for assistance.

Crontab UI is open-source software distributed under the MIT License and is free. The SecureAnyCloud charge covers packaging, hardening, security patching, image maintenance and support.

Deploy on Azure

Launch Crontab UI on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure