A free, self-hosted, open source dashboard for managing your cron jobs.
During the installation process, telemetry is collected to help us anonymously count installs and detect issues with the installation process itself. These are GET requests that do not send any details about your server.
To opt-out, you can set an environment variable to disable telemetry:
curl https://crontab.guru/install | TELEMETRY=off sh
Complete instructions for installing and running the Crontab Guru Dashboard
The easiest way to install the Crontab Guru Dashboard is using our automated install script:
curl https://crontab.guru/install | sh
This script will download and install the latest version of CronitorCLI, which includes the dashboard functionality.
After installation, you'll be prompted to set a username and password for dashboard access. You can't use the dashboard without setting a username and password.
Security Warning: The dashboard should not be exposed directly to the public internet. Always use secure access methods.
The most secure way to access your dashboard remotely is through an SSH tunnel:
ssh -L 9000:localhost:9000 user@your-server
Then access the dashboard at http://localhost:9000
You can automate this by adding the following to your ~/.ssh/config
:
Host your-server LocalForward 9000 localhost:9000
For additional security, configure IP whitelisting to restrict access to specific addresses:
cronitor configure --allow-ips 192.168.1.0/24,10.0.0.1
Use IP whitelisting whenever possible to limit access to trusted networks and addresses.
The current user crontab will be loaded automatically, and if you follow these instructions that will be the "root" user. As an alternative, you can specify users with the cronitor configure
command. For example:
cronitor configure --users admin,user1,user2
Create a systemd service to run the dashboard automatically. Before you start, if you are running the dashboard in another tab, or in a tmux or screen, exit that first so the port is free to use here. Save this as /etc/systemd/system/crontab-guru-dashboard.service
:
[Unit] Description=Crontab Guru Dashboard After=network.target Wants=network.target [Service] Type=simple User=root ExecStart=cronitor dash --port 9000 Restart=on-failure RestartSec=5 StandardOutput=journal StandardError=journal [Install] WantedBy=multi-user.target
Enable and start the service:
sudo systemctl enable crontab-guru-dashboard sudo systemctl start crontab-guru-dashboard sudo systemctl --no-pager --lines=0 status crontab-guru-dashboard
Regular updates ensure you have the latest features and security improvements:
cronitor update
After updating, restart the dashboard service:
sudo systemctl restart crontab-guru-dashboard
The dashboard will show an "update" button when a new version is available, making it easy to stay current.
Run the Crontab Guru Dashboard in a containerized environment
Create a Dockerfile
to build your own image with cronitor installed:
FROM alpine:latest # Install dependencies RUN apk add --no-cache \ curl \ bash \ ca-certificates \ dcron # Install cronitor CLI RUN curl -sL https://cronitor.io/dl/linux_amd64/cronitor -o /usr/local/bin/cronitor && \ chmod +x /usr/local/bin/cronitor # Set up authentication - REPLACE THESE PLACEHOLDERS! RUN cronitor configure --auth-username <YOUR_USERNAME_HERE> --auth-password <YOUR_PASSWORD_HERE> # Expose dashboard port EXPOSE 9000 # Run the dashboard CMD ["cronitor", "dash", "--port", "9000"]
Build the Docker image:
docker build -t crontab-guru-dashboard .
Run the container:
docker run -d --name crontab-guru -p 9000:9000 crontab-guru-dashboard
For better security, use build arguments to set credentials:
FROM alpine:latest # Build arguments - MUST be provided during build ARG DASHBOARD_USERNAME ARG DASHBOARD_PASSWORD # Install dependencies RUN apk add --no-cache \ curl \ bash \ ca-certificates \ dcron # Install cronitor CLI RUN curl -sL https://cronitor.io/dl/linux_amd64/cronitor -o /usr/local/bin/cronitor && \ chmod +x /usr/local/bin/cronitor # Configure authentication RUN cronitor configure --auth-username ${DASHBOARD_USERNAME} --auth-password ${DASHBOARD_PASSWORD} EXPOSE 9000 CMD ["cronitor", "dash", "--port", "9000"]
Build with custom credentials:
docker build --build-arg DASHBOARD_USERNAME=<YOUR_USERNAME> --build-arg DASHBOARD_PASSWORD=<YOUR_PASSWORD> -t crontab-guru-dashboard .
Create a docker-compose.yml
file for easier management:
version: '3.8' services: crontab-guru: build: context: . args: DASHBOARD_USERNAME: ${CRONITOR_USERNAME} DASHBOARD_PASSWORD: ${CRONITOR_PASSWORD} container_name: crontab-guru-dashboard ports: - "9000:9000" volumes: - cronitor-data:/root/.config/cronitor - ./crontabs:/var/spool/cron/crontabs restart: unless-stopped volumes: cronitor-data:
Create a .env
file for credentials:
CRONITOR_USERNAME=<YOUR_USERNAME_HERE> CRONITOR_PASSWORD=<YOUR_PASSWORD_HERE>
Start the service:
docker-compose up -d
The dashboard will manage cron jobs within the container. To persist crontabs, mount a volume:
docker run -d --name crontab-guru \ -p 9000:9000 \ -v crontab-data:/var/spool/cron/crontabs \ crontab-guru-dashboard
To manage host system cron jobs from the container, mount the host's cron directories:
docker run -d --name crontab-guru \ -p 9000:9000 \ -v /etc/cron.d:/etc/cron.d \ -v /var/spool/cron:/var/spool/cron \ -v /etc/crontab:/etc/crontab \ crontab-guru-dashboard
Note: Managing host cron jobs requires appropriate permissions and may have security implications.
To run cron jobs that interact with other Docker containers, mount the Docker socket and create jobs using docker exec
:
docker run -d --name crontab-guru \ -p 9000:9000 \ -v /var/run/docker.sock:/var/run/docker.sock \ crontab-guru-dashboard
Example cron job to backup another container:
0 2 * * * docker exec my-app-container /app/backup.sh
Important: Mounting the Docker socket provides full control over the Docker daemon. Only do this in trusted environments.
For better security, run the dashboard on a custom Docker network:
docker network create crontab-network docker run -d --name crontab-guru \ --network crontab-network \ -p 127.0.0.1:9000:9000 \ cronitorio/cronitor:latest dash
This binds the port only to localhost, preventing external access.
For production deployments, read credentials from files instead of hardcoding:
FROM alpine:latest # Install dependencies RUN apk add --no-cache curl bash ca-certificates dcron # Install cronitor CLI RUN curl -sL https://cronitor.io/dl/linux_amd64/cronitor -o /usr/local/bin/cronitor && \ chmod +x /usr/local/bin/cronitor # Copy and run setup script COPY setup.sh /setup.sh RUN chmod +x /setup.sh EXPOSE 9000 # Run setup script then start dashboard CMD ["/bin/bash", "-c", "/setup.sh && cronitor dash --port 9000"]
Create a setup.sh
script:
#!/bin/bash # Read credentials from environment or files USERNAME=${CRONITOR_USERNAME} PASSWORD=${CRONITOR_PASSWORD} # Ensure credentials are provided if [ -z "$USERNAME" ] || [ -z "$PASSWORD" ]; then echo "ERROR: CRONITOR_USERNAME and CRONITOR_PASSWORD must be set" exit 1 fi # If password file exists, read from it if [ -f "/run/secrets/cronitor_password" ]; then PASSWORD=$(cat /run/secrets/cronitor_password) fi # Configure cronitor with credentials cronitor configure --auth-username "$USERNAME" --auth-password "$PASSWORD"