database contains the MySQL database structure.chronos is cron-job.org's cron job execution daemon and is responsible for fetching the jobs.protocol contains the interface definitions for interaction between system nodes.frontend contains the web interfacestatuspage contains the status page UIapi contains the server API used by web interface and status page UI.chronos checks the MySQL database every minute to collect all jobs to execute. For every minute, a thread is spawned which processes all the jobs. Actual HTTP fetching is done using the excellent curl multi library with libev as library used to provide the event loop. Together with the c-ares resolver this allows for thousands of parallel HTTP requests.
cron-job.org supports storing the job results for the user's convenience. This can quickly lead to I/O bottlenecks when storing the result data in a MySQL database. (Which also has the downside that cleaning up old entries is extremely expensive.) To solve this issue, chronos stores the results in per-user per-day SQLite databases. Cleaning up old entries is as easy as deleting the corresponding day's databases.
The whole software is optimized on performance rather than on data integrity, i.e. when your server crashes or you have a power outage / hardware defect, the job history is most likely lost. Since this is volatile data anyway, it's not considered a big issue.
chronos can now run on multiple nodes. Each node requires an own MySQL server/database and stores its own jobs. The host
running the web interface also manages the user database and an association between job and node. The web interface can
create, delete, update and fetch jobs and job logs from the particular node via a Thrift-based protocol defined in the
protocol folder.
In order to build chronos, you need development files of: * curl (preferably with c-ares as resolver and libidn2 for IDN support) * libev * mysqlclient * sqlite3 * thrift (compiler and libthrift)
To build, you need a C++14 compiler and cmake.
mkdir build && cd buildcmake -DCMAKE_BUILD_TYPE=Release ..makedatabase folderchronos.cfg according to your system (especially add your MySQL login)./chronos /path/to/chronos.cfgThe API is written in PHP and needs to be hosted on a webserver (cron-job.org uses nginx with php-fpm). It is used by the console and the status page UI.
api/ folder to your webserverconfig/config.inc.default.php as lib/config.inc.php and customize it according to your environmentlib/protocol/. When committing, include the updated PHP code. Currently, this is a manual step.The frontend is written in JavaScript using React and material-ui. You need npm to build it.
frontend/ foldernpm installsrc/utils/Config.default.js as src/utils/Config.js and customize it according to your environmentnpm startThe status page frontend is written in JavaScript using React and material-ui. You need npm to build it.
statuspage/ foldernpm installsrc/utils/Config.default.js as src/utils/Config.js and customize it according to your environmentnpm startTo quickly start an example environment of most of the cron-job.org system, you can use docker-compose:
* Initialize/update submodules: git submodule init && git submodule update
* Copy .env.example to .env and open it in a text editor
* Change the variables in .env as desired. As an absolute minimum, fill the *_SECRET variables with randomly generated secrets and specify a SMTP server in SMTP_SERVER. No authentication is used for the SMTP session, so ensure that the SMTP server is allowing relaying for your machine's IP address.
* Start via docker compose up and wait until all containers are built and all services have been started. This can take a while, especially on first run.
* Open http://localhost:8010/ in your browser (assuming you kept the default port and host name settings).
Important: The Docker environment contained in this repo is intended as an example / development environment and is not tailored for production usage, especially with regard to security.
The default docker compose up builds the frontend and statuspage as static
production bundles served by nginx, which is not convenient while actively
developing them. For development, a docker-compose.dev.yml override is provided
that runs the frontend and status page via the React development server
(npm start) with the source code live-mounted from the repository, so changes
are reflected immediately (including hot module reloading). The PHP API source
is live-mounted as well, so API changes take effect without rebuilding.
Start the development environment with:
docker compose -f docker-compose.yml -f docker-compose.dev.yml up --build
Or use the helper script: ./dev.sh
Then open http://localhost:8010/ as usual.
Notes:
* Dev mode uses separate Docker image tags (cron-joborg-frontend-dev,
cron-joborg-statuspage-dev) so it does not reuse the production nginx
images from a plain docker compose up.
* The first start installs the npm dependencies inside the container and runs an
initial build; this can take a while. Until the dev servers report
Compiled successfully! (visible in the frontend/statuspage logs), the
web server will respond with a "Bad Gateway" error. Subsequent starts reuse
the cached dependencies and are much faster.
* If you see npm: command not found in the frontend or statuspage logs,
the containers are running stale production images. Rebuild with
docker compose -f docker-compose.yml -f docker-compose.dev.yml build frontend statuspage
or add --build to your up command.
* src/utils/Config.js for the frontend and status page is generated
automatically inside the container from the .env settings (it is gitignored
and your working tree is not modified).
* All other services (databases, redis, chronos) behave exactly as in the
normal setup; only the frontend, statuspage, api and www services are
adjusted for development.
The following containers will be started:
* mysql-master for the master service database which also stores users, groups, job -> node associations etc.
* mysql-node for the node service database. Used to store per-executor information like job details with their schedules, etc.
* redis used as a cache for certain features like rate limiting.
* api for the PHP-based API backend used by the frontend. Uses php-fpm.
* frontend which hosts the built frontend code.
* wwww as the frontend nginx-powered HTTP server which connects to frontend (HTTP reverse proxy) and api (FastCGI).
* chronos which runs chronos in a combined master and node service mode.
ulimit -n 65536 or similar first.innodb_flush_log_at_trx_commit=0 and innodb_flush_method=O_DIRECT in your MySQL config for best performance. Otherwise the update thread (which is responsible for storing the job resuls) might lag behind the actual job executions quite soon.$ claude mcp add cron-job.org \
-- python -m otcore.mcp_server <graph>