{"id":13552303,"url":"https://github.com/containrrr/shepherd","last_synced_at":"2025-05-15T10:06:34.831Z","repository":{"id":20820434,"uuid":"91006256","full_name":"containrrr/shepherd","owner":"containrrr","description":"Docker swarm service for automatically updating your services whenever their image is refreshed","archived":false,"fork":false,"pushed_at":"2025-02-24T23:49:20.000Z","size":79,"stargazers_count":538,"open_issues_count":11,"forks_count":88,"subscribers_count":6,"default_branch":"master","last_synced_at":"2025-05-13T13:07:13.338Z","etag":null,"topics":["automation","docker","docker-swarm","docker-swarm-mode","hacktoberfest","shell","updater"],"latest_commit_sha":null,"homepage":"https://hub.docker.com/r/mazzolino/shepherd","language":"Shell","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/containrrr.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-05-11T17:29:56.000Z","updated_at":"2025-05-13T06:01:41.000Z","dependencies_parsed_at":"2023-02-18T23:30:49.892Z","dependency_job_id":"67eae340-0168-49cc-84b0-16c6f5574be1","html_url":"https://github.com/containrrr/shepherd","commit_stats":null,"previous_names":["containrrr/shepherd","djmaze/shepherd"],"tags_count":12,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containrrr%2Fshepherd","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containrrr%2Fshepherd/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containrrr%2Fshepherd/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/containrrr%2Fshepherd/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/containrrr","download_url":"https://codeload.github.com/containrrr/shepherd/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254319719,"owners_count":22051073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automation","docker","docker-swarm","docker-swarm-mode","hacktoberfest","shell","updater"],"created_at":"2024-08-01T12:02:01.997Z","updated_at":"2025-05-15T10:06:29.808Z","avatar_url":"https://github.com/containrrr.png","language":"Shell","funding_links":[],"categories":["Shell","docker"],"sub_categories":[],"readme":"# Shepherd\n\n[![Build](https://github.com/containrrr/shepherd/actions/workflows/build.yml/badge.svg)](https://github.com/containrrr/shepherd/actions/workflows/build.yml)\n[![Docker Stars](https://img.shields.io/docker/stars/containrrr/shepherd.svg)](https://hub.docker.com/r/containrrr/shepherd/) [![Docker Pulls](https://img.shields.io/docker/pulls/containrrr/shepherd.svg)](https://hub.docker.com/r/containrrr/shepherd/)\n\nA Docker swarm service for automatically updating your services whenever their base image is refreshed.\n\n## Usage\n\n```shell-script\ndocker service create --name shepherd \\\n                      --constraint \"node.role==manager\" \\\n                      --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,ro \\\n                      containrrr/shepherd\n```\n\n### Or with Docker Compose\n\n```yaml\nversion: \"3\"\nservices:\n  ...\n  shepherd:\n    build: .\n    image: containrrr/shepherd\n    volumes:\n      - /var/run/docker.sock:/var/run/docker.sock\n    deploy:\n      placement:\n        constraints:\n          - node.role == manager\n```\n\nSee the example [docker-compose.yml](docker-compose.yml) and some more compose configs in the [examples](examples) folder.\n\n## Configuration\n\nShepherd will try to update your services every 5 minutes by default. You can adjust this value using the `SLEEP_TIME` variable.\n\nYou can prevent services from being updated by appending them to the `IGNORELIST_SERVICES` variable. This should be a space-separated list of service names.\n\nAlternatively you can specify a filter for the services you want updated using the `FILTER_SERVICES` variable. This can be anything accepted by the filtering flag in `docker service ls`.\n\nYou can set Shepherd to roll back a service to the previous version if the update fails by setting the `ROLLBACK_ON_FAILURE` variable.\n\nYou can control additional parameters for the `docker service update` and `docker service update --rollback` calls using the variables `UPDATE_OPTIONS` and `ROLLBACK_OPTIONS`.\n\nIf the `docker service update` takes too long then it will be killed after 5 minutes by default. You can adjust this value using the `TIMEOUT` variable.\n\nYou can enable private registry authentication by setting the `WITH_REGISTRY_AUTH` variable.\n\nIf you need to authenticate to a registry (for example in order to get around the [Docker Hub rate limits](https://www.docker.com/increase-rate-limit)), you can set the variable `REGISTRY_USER` and store the password either in a [docker secret](https://docs.docker.com/engine/swarm/secrets/) named `shepherd_registry_password` or in the environment variable `REGISTRY_PASSWORD`. If you are not using Docker Hub but a private registry, set `REGISTRY_HOST` to the hostname of your registry.\n\nIt 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 `\u003cTAB\u003e` separated and has 4 columns:\n* id: an identifier for the account. This should be an acceptable [Docker config name](https://docs.docker.com/engine/swarm/configs/).\n* registry: the registry to authenticate against, eg `registry.gitlab.com`\n* login: the user to authenticate as\n* password: the password to authenticate with\n\nLines 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](https://stackoverflow.com/a/729795/1752287)).\nHere is an example:\n```\nblog\tregistry.gitlab.com\tgitlab+deploy-token-5123674\tssw2Nrd2\n\n```\nCreate and edit that file locally, eg at the location `private/shepherd-registries-auth`, and create the docker secret with\n```\ndocker secret create shepherd-registries-auth private/shepherd-registries-auth\n```\nYou need to make the secret available to shepherd with the `secrets` key, and pass the secret file to the `REGISTRIES_FILE` variable:\n```yaml\nservices:\n  app:\n    image: containrrr/shepherd\n    environment:\n      REGISTRIES_FILE: /var/run/secrets/shepherd-registries-auth\n    secrets:\n      - shepherd-registries-auth\nsecrets:\n    shepherd-registries-auth:\n      external: true\n```\nYou also need to add a label `shepherd.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 the `id` in the secret file:\n\n```yaml\n    deploy:\n        labels:\n            - shepherd.enable=true\n            - shepherd.auth.config=blog\n```\n\nYou can enable connection to insecure private registry by setting the `WITH_INSECURE_REGISTRY` variable to `true`.\n\nYou can prevent pulling images from the registry by setting the `WITH_NO_RESOLVE_IMAGE` variable to `true`.\n\nYou can enable notifications on service update with apprise, using the [apprise microservice](https://github.com/djmaze/apprise-microservice) and the `APPRISE_SIDECAR_URL` variable. See the file [docker-compose.apprise.yml](examples/docker-compose.apprise.yml) for an example.\n\nYou can enable old image autocleaning on service update by setting the `IMAGE_AUTOCLEAN_LIMIT` variable.\n\nYou can enable one shot running with `RUN_ONCE_AND_EXIT` variable.\n\nIf you care about log entries having the right timezone, you can set the `TZ` variable to the correct value (make sure to *not* include quotation marks in the variable value).\n\nExample:\n\n```shell-script\ndocker service create --name shepherd \\\n                      --constraint \"node.role==manager\" \\\n                      --env SLEEP_TIME=\"5m\" \\\n                      --env IGNORELIST_SERVICES=\"shepherd my-other-service\" \\\n                      --env WITH_REGISTRY_AUTH=\"true\" \\\n                      --env WITH_INSECURE_REGISTRY=\"true\" \\\n                      --env WITH_NO_RESOLVE_IMAGE=\"true\" \\\n                      --env FILTER_SERVICES=\"label=com.mydomain.autodeploy\" \\\n                      --env APPRISE_SIDECAR_URL=\"apprise-microservice:5000\" \\\n                      --env IMAGE_AUTOCLEAN_LIMIT=\"5\" \\\n                      --env RUN_ONCE_AND_EXIT=\"true\" \\\n                      --env ROLLBACK_ON_FAILURE=\"true\" \\\n                      --env UPDATE_OPTIONS=\"--update-delay=30s\" \\\n                      --env TZ=Europe/Berlin \\\n                      --mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,ro \\\n                      --mount type=bind,source=/root/.docker/config.json,target=/root/.docker/config.json,ro \\\n                      containrrr/shepherd\n```\n\n*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 in [docker-compose.yml](docker-compose.yml)!*\n\n## Running on a cron schedule\n\nWhen running shepherd as described with a `SLEEP_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 with [swarm-cronjob](https://github.com/crazy-max/swarm-cronjob):\n\n1. Create a *swarm-cronjob* service [as described in its documentation](https://crazymax.dev/swarm-cronjob/install/docker/#usage).\n2. Set `RUN_ONCE_AND_EXIT` to `true`, `replicas` to `0` and `restart_policy` to `condition: none`. Add docker labels for the schedule.\n\nSee [docker-compose.swarm-cronjob.yml](examples/docker-compose.swarm-cronjob.yml) for a full stack example which includes both shepherd as well as swarm-cronjob.\n\n## How does it work?\n\nShepherd just triggers updates by updating the image specification for each service, removing the current digest.\n\nMost of the work is thankfully done by Docker which [resolves the image tag, checks the registry for a newer version and updates running container tasks as needed](https://docs.docker.com/engine/swarm/services/#update-a-services-image-after-creation).\n\nAlso, Docker handles all the work of [applying rolling updates](https://docs.docker.com/engine/swarm/swarm-tutorial/rolling-update/). So at least with replicated services, there should be no noticeable downtime.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainrrr%2Fshepherd","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcontainrrr%2Fshepherd","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcontainrrr%2Fshepherd/lists"}