Usually you would run deck-chores in a container:
$ docker run --rm -v /var/run/docker.sock:/var/run/docker.sock funkyfuture/deck-chores
There’s a manifest on the Docker Hub that maps images to builds targeting
Thus you don’t need to specify any platform indicator, the Docker client will figure out which
one is the proper image to pull.
Likewise, docker-compose can be used with such configuration:
version: '2' services: officer: image: funkyfuture/deck-chores restart: unless-stopped environment: TIMEZONE: Asia/Tel Aviv volumes: - /var/run/docker.sock:/var/run/docker.sock
You could also install deck-chores from the Python Package Index with
$ pipsi install deck-chores
and then run it:
Now one instance of deck-chores is running and will handle all job definitions that it discovers on containers that run on the Docker host.
Caveats & Tips¶
There’s yet no way to distinguish container events that happen during an image build from others (#6 and #15211). Thus when an image is built, deck-chores will register and remove jobs on all intermediate containers following labels that define jobs. It would possibly trigger these jobs, which might lead to a corrupted build. You can avoid this risk by building images on a host that is not observed by deck-chores or by pausing it during image builds.
Containers without an enduring main process¶
If the container is supposed to only run the scheduled commands and not a main process, use a
non-stopping no-op command as main process like in this snippet of a
services: neverending: # … command: > tail -f /dev/null labels: deck-chores.short.command: daily_command … deck-chores.short.interval: daily
Job definitions are parsed from a container’s metadata aka labels. A label’s key must be in the
namespace defined by
deck-chores) to be considered. A job
has an own namespace that holds all its attributes. Thus an attribute’s key has this schema:
$LABEL_NAMESPACE.<job name>.<job attribute>
The job name
options cannot be used as it is reserved for setting Container-scoped configuration.
The following attributes are available:
|command||the command to run|
|cron||a cron definition|
|date||a date definition|
|interval||a interval definition|
|max||the maximum of simultaneously running command instances,
|timezone||the timezone that cron and date relate to,
|user||the user to run the command. See user for details regarding the defaults.|
command and one of
interval are required for each
Example snippet from a
services: web: # ... labels: deck-chores.clear-caches.command: drush cc all deck-chores.clear-caches.interval: daily deck-chores.clear-caches.user: www-data
Or baked into an image:
LABEL deck-chores.clear-caches.command="drush cc all" \ deck-chores.clear-caches.interval="daily" \ deck-chores.clear-caches.user="www-data"
cron triggers allow definitions for repeated run times like for the well-known cron daemon.
In contrast to the classic, the sequence of fields is flipped, starting with the greatest unit
on the left. The fields are separated by spaces, missing fields are filled up with
* on the
The fields from left to right define:
See APScheduler’s documentation for details on its versatile expressions.
* * * * * */3 0 0 # run on all hours dividable by 3 */3 0 0 # as shortened expression * * * * 6 1 0 0 # run every Sunday at 1:00 6 1 0 0 # as shortened expression sun 1 0 0 # as 'speaking' variant * * * * * 1-4 0 0 # run daily at 1:00, 2:00, 3:00 and 4:00 1-4 0 0 # as shortened expression
A one-time trigger that is formatted as
An omitted time is interpreted as
0:00:00. Note that times must include a seconds field.
This trigger defines a repetition by a fixed interval. The interval is added up by the fields
weeks, days, hours, minutes and seconds. Possible field separators are
/ and spaces. Missing fields are filled up with
0 on the left.
42:00:00 # run every fourty-two hours 100/00:00:00 # run every one hundred days
There are also the convenience shortcuts
every minute and
Though it uses the same units of measurement, an interval is different from a point in time, it describes the time between two events. Hence you should expect a job that is defined with this type of trigger to run the defined time after the job has been registered. To define a point in time, see cron.
A user that shall run all jobs for a container can be set with a label name of this form:
The option can also be defined for an image and is considered when the
flag is set.
If this option is not set, Docker uses the user that was specified with the
--user option on
container creation or falls back to the one defined in the underlying image.
Option flags control deck-chores’s behaviour with regard to the labeled container and override
the setting of
DEFAULT_FLAGS. The schema for a flags label name is:
Options are set as comma-separated list of flags. An option set by
be unset by prefixing with
These options are available:
Job definitions in the container’s basing image labels are also parsed while container label keys override these.
deck-chore’s behaviour is defined by these environment variables:
The timeout for responses from the Docker daemon in seconds without unit indicator. The default is imported from docker-py.
The URL of the Docker daemon to connect to.
Log debugging messages, enabled by
The default for a job’s
The label namespace to look for job definitions and container options.
A comma-separated list of container labels that identify a unique service with possibly multiple container instances. This has an impact on how the
The job scheduler’s timezone and the default for a job’s
TLS(selects the highest version supported by the client and the daemon)
For other options see the names provided by Python’s ssl library prefixed with
Authentication related files are expected to be available at