Cron jobs with Docker Swarm
Prune images and update container images on a schedule with cron jobs in Docker Swarm
Wed, 21 Feb 2024
You got your docker swarm cluster up and its beautiful but now you want to add some background tasks to take it to the next level, lets talk about how we do that
Crazymax created a docker swarm cron job service. You run this container and then it will scan labels on all of your containers looking for the syntax that will tell it to queue up a job.
I included 2 cron jobs that most people will want. One is to clean up unused images since the Docker Swarm service does not do that for us and the second job is to update your containers
version: "3.9"
services:
cronjob:
image: crazymax/swarm-cronjob # Cron Orchestrator
volumes:
- /var/run/docker.sock:/var/run/docker.sock # Needs docker.sock to scan labels on deployments
environment:
TZ: America/New_York
LOG_LEVEL: info
LOG_JSON: 'false'
deploy:
placement:
constraints:
- node.role == manager # has to be a manager node to run this service
resources:
reservations:
memory: 512M
limits:
memory: 512M
# Prunes unused docker images to save space
prune-images:
image: docker
command: docker image prune -a -f
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
mode: global
labels:
- swarm.cronjob.enable=true # enables the cron service
- swarm.cronjob.schedule=0 0 2 * * 5 # Every Friday at 2am
- swarm.cronjob.skip-running=false
restart_policy: # make sure to set this else the container will restart once the job is done
condition: none
# Updates docker images to the latest image and restarts containers. Think watchtowerrr but for docker swarm (watchtowerr doesn't work with swarm)
update-containers:
image: shizunge/gantry
volumes:
- /var/run/docker.sock:/var/run/docker.sock
environment:
GANTRY_NODE_NAME: "{{.Node.Hostname}}"
GANTRY_SERVICES_SELF: "${STACK}_gantry"
GANTRY_SLEEP_SECONDS: 0
GANTRY_UPDATE_OPTIONS: --stop-grace-period 1m
GANTRY_CLEANUP_IMAGES: 'false'
GANTRY_SERVICES_FILTERS: label=autoupdate=true # only updates services where the deployment has a label of autoupdate=true. You can omit to target every container
GANTRY_LOG_LEVEL: DEBUG
deploy:
replicas: 0
placement: # has to run on a manager to be able to read labels and restart deployments
constraints:
- node.role == manager
restart_policy:
condition: none
labels:
- swarm.cronjob.enable=true
- swarm.cronjob.schedule=0 0 4 * * * # Daily at 4am
- swarm.cronjob.skip-running=true
```