fly-apps / cron-manager

Apache License 2.0
31 stars 1 forks source link

Cron Manager

Cron Manager is designed to enhance the way you manage Cron jobs on Fly.io.

Key Features and Benefits

Isolated execution

Each job runs in its own isolated machine, preventing issues such as configuration drift, accumulation of temporary files, or other residual effects that could impact subsequent job executions. This isolation ensures that the outcome of one job does not negatively influence another, maintaining the integrity and reliability of each job.

Centralized Scheduling

Manage all your Cron jobs centrally with a simple JSON configuration. This approach removes the need to embed cron dependencies within each production environment, streamlining setup and modifications. The use of a version-controlled configuration file enhances maintainability and auditability of scheduling changes.

Simplified updates

Machines dedicated to specific Cron jobs are ephemeral and do not require updates. Any modifications to the schedules.json file will automatically be applied the next time the machine is provisioned for a scheduled job. This eliminates the need for ongoing maintenance of job environments, resulting in a more efficient update process.

Enhanced Logs and Monitoring

Operating separate machines for each job greatly simplifies monitoring and auditing. This setup allows for straightforward tracking of the outcomes and logs of individual jobs, facilitating easier debugging and performance analysis.

Getting started

Follow these steps to get your Cron Manager application up and running on Fly.io:

Clone the project

git clone git@github.com:fly-apps/cron-manager.git && cd cron-manager

Create your app (Make sure the app name matches the fly.toml entry)

fly apps create <new app name>

Set your FLY_API_TOKEN as a secret

fly secrets set FLY_API_TOKEN=$(fly auth token)

Deploy your app

fly deploy .

Managing Schedules

Schedules are managed using the schedules.json file located within the projects root directory. Any new additions, updates, or deletions to this file are automatically reconciled on deploy.

JSON Fields

Example Schedule

[
    {
        "name": "uptime-check",
        "app_name": "my-app-name",
        "schedule": "* * * * *",
        "region": "iad",
        "command": "uptime",
        "command_timeout": 30,
        "enabled": true,
        "config": {
            "metadata": {
                "fly_process_group": "cron"
            },
            "auto_destroy": true,
            "disable_machine_autostart": true,
            "guest": {
                "cpu_kind": "shared",
                "cpus": 1,
                "memory_mb": 512
            },
            "image": "ghcr.io/livebook-dev/livebook:0.11.4",
            "restart": {
                "max_retries": 1,
                "policy": "no"
            }
        }
    }
]

Viewing Schedules

To view your registered schedules, you can use the cm schedules list command.

cm schedules list

Output example:

|----|------------------|-----------------------------------------------|-----------|--------|----------|---------|
| ID | TARGET APP       | IMAGE                                         | SCHEDULE  | REGION | COMMAND  | ENABLED |
|----|------------------|-----------------------------------------------|-----------|--------|----------|---------|
| 1  | my-example-app   | ghcr.io/livebook-dev/livebook:0.11.4          | * * * * * | iad    | sleep 10 | true    |
| 2  | my-example-app-2 | docker-hub-mirror.fly.io/library/nginx:latest | 0 * * * * | ord    | df -h    | false   |
|----|------------------|-----------------------------------------------|-----------|--------|----------|---------|

Viewing Scheduled Jobs

Each job execution is recorded within a local sqlite. To view the job history of a specific schedule, ssh into the Machine and run the following:

cm jobs list <schedule-id>

Output example:

|----|----------------|-----------|-----------|-------------------------|-------------------------|-------------------------|
| ID | MACHINE ID     | STATUS    | EXIT CODE | CREATED AT              | UPDATED AT              | FINISHED AT             |
|----|----------------|-----------|-----------|-------------------------|-------------------------|-------------------------|
| 30 | 185710da967398 | completed | 0         | 2024-04-11 20:03:01 UTC | 2024-04-11 20:03:03 UTC | 2024-04-11 20:03:03 UTC |
| 29 | 2865d32b356008 | completed | 0         | 2024-04-11 20:02:01 UTC | 2024-04-11 20:02:03 UTC | 2024-04-11 20:02:03 UTC |
| 28 | 683d67eb056e48 | completed | 0         | 2024-04-11 20:01:01 UTC | 2024-04-11 20:01:04 UTC | 2024-04-11 20:01:04 UTC |
| 27 | 080e07df930d08 | completed | 0         | 2024-04-11 20:00:01 UTC | 2024-04-11 20:00:06 UTC | 2024-04-11 20:00:06 UTC |
| 26 | 784e475f51d3e8 | completed | 0         | 2024-04-11 19:59:01 UTC | 2024-04-11 19:59:03 UTC | 2024-04-11 19:59:03 UTC |
| 25 | 28749e0bd51e68 | completed | 0         | 2024-04-11 19:58:01 UTC | 2024-04-11 19:58:03 UTC | 2024-04-11 19:58:03 UTC |
| 24 | e82de70b46ed78 | completed | 0         | 2024-04-11 19:57:01 UTC | 2024-04-11 19:57:03 UTC | 2024-04-11 19:57:03 UTC |
| 23 | d891745b3527d8 | completed | 0         | 2024-04-11 19:56:01 UTC | 2024-04-11 19:56:04 UTC | 2024-04-11 19:56:04 UTC |
| 22 | 7811372b1e2e68 | completed | 0         | 2024-04-11 19:55:01 UTC | 2024-04-11 19:55:03 UTC | 2024-04-11 19:55:03 UTC |
| 21 | 185710da967698 | completed | 0         | 2024-04-11 19:54:01 UTC | 2024-04-11 19:54:04 UTC | 2024-04-11 19:54:04 UTC |
|----|----------------|-----------|-----------|-------------------------|-------------------------|-------------------------|

Viewing a Specific Job

cm jobs show <job-id>

Output example:

Job Details
  ID          = 30
  Status      = completed
  Machine ID  = 2866e19a795908
  Exit Code   = 0
  Created At  = 2024-04-15 14:34:01 UTC
  Updated At  = 2024-04-15 14:34:03 UTC
  Finished At = 2024-04-15 14:34:03 UTC
  Stdout      = 
  Stderr      =

Triggering Off-schedule Jobs

In the event you would like to trigger a Job "off schedule" for testing, you can do so with the trigger command.

cm jobs trigger <schedule-id>