Ofelia Job Scheduler
repository·master·Indexed 26 days ago
https://github.com/mcuadros/ofeliaA modern, low-footprint job scheduler built in Go for Docker environments. Ofelia serves as a container-native replacement for cron, supporting four job types: job-exec (commands in running containers), job-run (commands in new containers), job-local (commands on the host), and job-service-run (run-once services for Docker Swarm). It supports configuration via INI files or Docker labels, featuring dynamic hot-reloading, Docker event listening, and logging drivers for mail, Slack, and local storage.
What's inside Ofelia
- The easiest way to deploy Ofelia is using Docker. You can also download the binary from the official releases page if you prefer not to use the Docker image.
Configure jobs using Docker labels
masterYou can configure jobs by adding labels to containers. The format is
ofelia.<JOB_TYPE>.<JOB_NAME>.<JOB_PARAMETER>=<PARAMETER_VALUE>.To use
job-execon a target container, the target container must have the labelofelia.enabled=true.Example: Running a local job via Docker CLI
docker run -it --rm \ -v /var/run/docker.sock:/var/run/docker.sock:ro \ --label ofelia.job-local.my-test-job.schedule="@every 5s" \ --label ofelia.job-local.my-test-job.command="date" \ mcuadros/ofelia:latest daemon --dockerExample: Docker Compose configuration
version: "3" services: ofelia: image: mcuadros/ofelia:latest depends_on: - nginx command: daemon --docker volumes: - /var/run/docker.sock:/var/run/docker.sock:ro labels: ofelia.job-local.my-test-job.schedule: "@every 5s" ofelia.job-local.my-test-job.command: "date" nginx: image: nginx labels: ofelia.enabled: "true" ofelia.job-exec.datecron.schedule: "@every 5s" ofelia.job-exec.datecron.command: "uname -a"Configure Ofelia jobs
masterOfelia supports four types of jobs using a scheduling format compatible with Go's
cronimplementation (e.g.,@every 10sor0 1 * * *).Job Types:
job-exec: Executes a command inside a running container.job-run: Runs a command inside a new container using a specific image.job-local: Runs the command inside the host running Ofelia.job-service-run: Runs the command inside a new "run-once" service (for Docker Swarm).
Note on version 0.3.x: For the current
0.3.xversion, seconds configuration in the cron spec is required. In newer versions (0.4.x+), seconds are optional.Configure Logging drivers
masterOfelia supports three logging drivers:
mail,save, andslack. These are configured in the[global]section of aconfig.inifile or via labels on theofeliacontainer.Mail options:
smtp-host: SMTP server address.smtp-port: SMTP server port.smtp-user: SMTP username.smtp-password: SMTP password.smtp-tls-skip-verify: Iftrue, ignores certificate errors.email-to: Recipient email address.email-from: Sender email address.mail-only-on-error: Iftrue, only sends mail on failure.
Save options:
save-folder: Directory for reports (must exist).save-only-on-error: Iftrue, only saves reports on failure.
Slack options:
slack-webhook: Slack webhook URL.slack-only-on-error: Iftrue, only sends Slack messages on failure.
Run Ofelia in Docker daemon mode
masterTo run Ofelia as a scheduler for Docker, use the
daemon --dockercommand. This requires mounting the Docker socket (/var/run/docker.sock) into the container with read-only permissions so Ofelia can interact with the Docker API.services: ofelia: command: daemon --docker volumes: - /var/run/docker.sock:/var/run/docker.sock:roConfigure Ofelia to use Docker labels for job definitions
masterOfelia can dynamically discover and manage jobs by reading Docker container labels. When enabled, Ofelia watches the Docker event stream for container lifecycle changes (create, start, stop, etc.) and hot-reloads its configuration automatically.
To use this feature, you must enable the
--dockerflag in your Ofelia command-line invocation. You can also provide specific Docker filters to limit which containers Ofelia inspects.Configure jobs using INI files
masterYou can define jobs in an INI-style configuration file and run Ofelia with the
--configflag.[job-exec "job-executed-on-running-container"] schedule = @hourly container = my-container command = touch /tmp/example [job-run "job-executed-on-new-container"] schedule = @hourly image = ubuntu:latest command = touch /tmp/example [job-local "job-executed-on-current-host"] schedule = @hourly command = touch /tmp/example [job-service-run "service-executed-on-new-container"] schedule = 0,20,40 * * * * image = ubuntu network = swarm_network command = touch /tmp/exampleConfigure `job-exec` to run commands in existing containers
masterUse
job-execto execute a command inside a currently running container, similar todocker exec.Required Parameters:
schedule: Cron expression or@everyformat (e.g.,@every 10sor0 0 1 * * *). Note that the format starts with seconds.command: The command to run.container: The name of the target container.
Optional Parameters:
user: User to execute the command as (default:root).tty: Allocate a pseudo-tty (default:false).environment: Environment variables (e.g.,FOO=bar).- In INI files, use
environmentmultiple times. - In Docker labels, use a JSON array:
["FOO=bar", "BAZ=qux"]. - Note:
environmentinjob-execrequires Docker API 1.25 or higher.
- In INI files, use
[job-exec "flush-nginx-logs"] schedule = @hourly container = nginx-proxy command = /bin/bash /flush-logs.sh user = www-data tty = falseConfigure `job-service-run` for Docker Swarm
masterUse
job-service-runto run a command inside a new "run-once" service, specifically designed for use within a Docker Swarm environment.Parameters:
schedule: Cron expression or@everyformat (Required).image: The image to use (Required).command: Command to run (defaults to container default).network: Connect to a specific network.delete: Delete the container after job finishes (default:true).user: User to execute as (default:root).tty: Allocate a pseudo-tty (default:false).
[job-service-run "service-executed-on-new-container"] schedule = 0,20,40 * * * * image = ubuntu network = swarm_network command = touch /tmp/exampleConfigure `job-local` to run commands on the host
masterUse
job-localto run commands directly on the host machine where Ofelia is running.Important Note: If Ofelia is running inside a container,
job-localexecutes the command inside the Ofelia container, not on the Docker host.Parameters:
schedule: Cron expression or@everyformat (Required).command: The command to execute (Required).dir: Base directory for execution (default: current directory).environment: Environment variables (e.g.,FOO=bar).- In INI files, use
environmentmultiple times. - In Docker labels, use a JSON array:
["FOO=bar", "BAZ=qux"].
- In INI files, use
[job-local "create-file"] schedule = @every 15s command = touch test.txt dir = /tmp/Configure `job-run` to start new containers or existing ones
masterUse
job-runfor two scenarios:- Run a new container: Specify an
imageandcommand(similar todocker run). - Start a stopped container: Specify a
containername (similar todocker start).
Key Parameters:
schedule: Cron expression or@everyformat (Required).image: The image to use (Required for scenario 1).container: The container name to start (Required for scenario 2).command: Command to run (defaults to container default).entrypoint: Override container default entrypoint.user: User to execute as (default:root).network: Connect to a specific network.hostname: Define the container hostname.delete: Delete container after job finishes (default:true).tty: Allocate a pseudo-tty (default:false).volume: Bind mount host directory (e.g.,/tmp/test:/tmp/test:rw).- In INI files, use
volumemultiple times. - In Docker labels, use a JSON array:
["/test/tmp:/test/tmp:ro", "/test/tmp:/test/tmp:rw"].
- In INI files, use
volumes-from: Use volumes from another container.- In INI files, use
volumes-frommultiple times. - In Docker labels, use a JSON array:
["container-foo", "bar-container"].
- In INI files, use
environment: Environment variables (e.g.,FOO=bar).- In INI files, use
environmentmultiple times. - In Docker labels, use a JSON array:
["FOO=bar", "BAZ=qux"].
- In INI files, use
[job-run "print-write-date"] schedule = @every 5s image = alpine:latest command = sh -c 'date | tee -a /tmp/test/date' volume = /tmp/test:/tmp/test:rw environment = FOO=bar environment = BAZ=qux- Run a new container: Specify an
Configure Docker Host connection
masterOfelia connects to the Docker daemon via
/var/run/docker.sockby default. You can override this using the following environment variables:DOCKER_HOST: The Docker host to connect to (e.g.,tcp://docker-proxy:2375,unix:///custom/docker.sock).DOCKER_TLS_VERIFY: Enable TLS verification (set to1to enable).DOCKER_CERT_PATH: Path to TLS certificates directory.DOCKER_API_VERSION: Docker API version to use.