Skip to content

Commit

Permalink
Add initial version
Browse files Browse the repository at this point in the history
  • Loading branch information
Martin Honermeyer committed May 11, 2017
0 parents commit 27b26fc
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 0 deletions.
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
FROM docker

COPY shepherd /usr/local/bin/shepherd

ENTRYPOINT ["/usr/local/bin/shepherd"]
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Shepherd

A Docker swarm service for automatically updating your services whenever their base image is refreshed.

## Usage

docker service create --name shepherd \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock,ro \
mazzolino/shepherd

Shepherd will try to update your services every 5 minutes.

## How does it work?

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 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).

Also, 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.
8 changes: 8 additions & 0 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
version: "3"

services:
app:
build: .
image: mazzolino/shepherd
volumes:
- /var/run/docker.sock:/var/run/docker.sock
24 changes: 24 additions & 0 deletions shepherd
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#!/bin/ash
# shellcheck shell=dash
set -euo pipefail

update_services() {
for service in $(IFS="\n" docker service ls --quiet); do
local name image
name="$(docker service inspect "$service" -f '{{.Spec.Name}}')"
image_with_digest="$(docker service inspect "$service" -f '{{.Spec.TaskTemplate.ContainerSpec.Image}}')"
image=$(echo "$image_with_digest" | cut -d@ -f1)

echo "Updating service $name with image $image"
docker service update "$service" --image "$image" > /dev/null
done
}

main() {
while true; do
update_services
sleep 5m
done
}

main "$@"

0 comments on commit 27b26fc

Please sign in to comment.