- Notifications
You must be signed in to change notification settings - Fork90
Docker swarm service for automatically updating your services whenever their image is refreshed
License
containrrr/shepherd
Folders and files
Name | Name | Last commit message | Last commit date | |
---|---|---|---|---|
Repository files navigation
A Docker swarm service for automatically updating your services whenever their base image is refreshed.
docker service create --name shepherd \ --constraint"node.role==manager" \ --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,ro \ containrrr/shepherd
version:"3"services:...shepherd:build:.image:containrrr/shepherdvolumes: -/var/run/docker.sock:/var/run/docker.sockdeploy:placement:constraints: -node.role == manager
See the exampledocker-compose.yml and some more compose configs in theexamples folder.
Shepherd will try to update your services every 5 minutes by default. You can adjust this value using theSLEEP_TIME
variable.
You can prevent services from being updated by appending them to theIGNORELIST_SERVICES
variable. This should be a space-separated list of service names.
Alternatively you can specify a filter for the services you want updated using theFILTER_SERVICES
variable. This can be anything accepted by the filtering flag indocker service ls
.
You can set Shepherd to roll back a service to the previous version if the update fails by setting theROLLBACK_ON_FAILURE
variable.
You can control additional parameters for thedocker service update
anddocker service update --rollback
calls using the variablesUPDATE_OPTIONS
andROLLBACK_OPTIONS
.
If thedocker service update
takes too long then it will be killed after 5 minutes by default. You can adjust this value using theTIMEOUT
variable.
You can enable private registry authentication by setting theWITH_REGISTRY_AUTH
variable.
If you need to authenticate to a registry (for example in order to get around theDocker Hub rate limits), you can set the variableREGISTRY_USER
and store the password either in adocker secret namedshepherd_registry_password
or in the environment variableREGISTRY_PASSWORD
. If you are not using Docker Hub but a private registry, setREGISTRY_HOST
to the hostname of your registry.
It is also possible to put all authentication information in a secret file. This approach is required if you need to authenticate with multiple accounts to the same registry (eg authenticate to the Gitlab registry for images from different projects). The content of the file is<TAB>
separated and has 4 columns:
- id: an identifier for the account. This should be an acceptableDocker config name.
- registry: the registry to authenticate against, eg
registry.gitlab.com
- login: the user to authenticate as
- password: the password to authenticate with
Lines starting with#
are comments, and are ignored, as are invalid lines. Make sure this file ends with a new line. Otherwise your last line in the file will be ignored (here is why).Here is an example:
blogregistry.gitlab.comgitlab+deploy-token-5123674ssw2Nrd2
Create and edit that file locally, eg at the locationprivate/shepherd-registries-auth
, and create the docker secret with
docker secret create shepherd-registries-auth private/shepherd-registries-auth
You need to make the secret available to shepherd with thesecrets
key, and pass the secret file to theREGISTRIES_FILE
variable:
services:app:image:containrrr/shepherdenvironment:REGISTRIES_FILE:/var/run/secrets/shepherd-registries-authsecrets: -shepherd-registries-authsecrets:shepherd-registries-auth:external:true
You also need to add a labelshepherd.auth.config
to the container to be updated specifying which line of the secret file should be used. The value of that label should be theid
in the secret file:
deploy:labels: -shepherd.enable=true -shepherd.auth.config=blog
You can enable connection to insecure private registry by setting theWITH_INSECURE_REGISTRY
variable totrue
.
You can prevent pulling images from the registry by setting theWITH_NO_RESOLVE_IMAGE
variable totrue
.
You can enable notifications on service update with apprise, using theapprise microservice and theAPPRISE_SIDECAR_URL
variable. See the filedocker-compose.apprise.yml for an example.
You can enable old image autocleaning on service update by setting theIMAGE_AUTOCLEAN_LIMIT
variable.
You can enable one shot running withRUN_ONCE_AND_EXIT
variable.
If you care about log entries having the right timezone, you can set theTZ
variable to the correct value (make sure tonot include quotation marks in the variable value).
Example:
docker service create --name shepherd \ --constraint"node.role==manager" \ --env SLEEP_TIME="5m" \ --env IGNORELIST_SERVICES="shepherd my-other-service" \ --env WITH_REGISTRY_AUTH="true" \ --env WITH_INSECURE_REGISTRY="true" \ --env WITH_NO_RESOLVE_IMAGE="true" \ --env FILTER_SERVICES="label=com.mydomain.autodeploy" \ --env APPRISE_SIDECAR_URL="apprise-microservice:5000" \ --env IMAGE_AUTOCLEAN_LIMIT="5" \ --env RUN_ONCE_AND_EXIT="true" \ --env ROLLBACK_ON_FAILURE="true" \ --env UPDATE_OPTIONS="--update-delay=30s" \ --env TZ=Europe/Berlin \ --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,ro \ --mount type=bind,source=/root/.docker/config.json,target=/root/.docker/config.json,ro \ containrrr/shepherd
Note that the quotes in the command above are evaluated by your shell and are not part of the environment variable value! - See also the note indocker-compose.yml!
When running shepherd as described with aSLEEP_TIME
, the de facto running times will drift the longer the container is running. If you want to run shepherd on a fixed schedule instead, it is recommended to pair it withswarm-cronjob:
- Create aswarm-cronjob serviceas described in its documentation.
- Set
RUN_ONCE_AND_EXIT
totrue
,replicas
to0
andrestart_policy
tocondition: none
. Add docker labels for the schedule.
Seedocker-compose.swarm-cronjob.yml for a full stack example which includes both shepherd as well as swarm-cronjob.
Shepherd just triggers updates by updating the image specification for each service, removing the current digest.
Most of the work is thankfully done by Docker whichresolves the image tag, checks the registry for a newer version and updates running container tasks as needed.
Also, Docker handles all the work ofapplying rolling updates. So at least with replicated services, there should be no noticeable downtime.
About
Docker swarm service for automatically updating your services whenever their image is refreshed