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
    ```
Buy Me A CoffeeDigitalOcean Referral Badge
Loading...
Edward Beazer

Edward Beazer - I just like to build shit. Sometimes I get stuck for hours, even days while trying to figure out how to solve an issue or implement a new feature. Hope my tips and tutorials can save you some time.

DigitalOcean Referral Badge