Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

https://github.com/shizunge/gantry

Automatically update Docker swarm services.
https://github.com/shizunge/gantry

automation docker docker-swarm self-hosted shell updater

Last synced: 3 months ago
JSON representation

Automatically update Docker swarm services.

Lists

README

        

# Gantry - Docker service updater

[![Release](https://img.shields.io/github/release/shizunge/gantry.svg?label=Release)](https://github.com/shizunge/gantry/releases/latest)
[![License](https://img.shields.io/badge/License-GPLv3-blue)](https://github.com/shizunge/gantry/blob/main/LICENSE)
[![Image Size](https://img.shields.io/docker/image-size/shizunge/gantry/latest.svg?label=Image%20Size)](https://hub.docker.com/r/shizunge/gantry)
[![Docker Pulls](https://img.shields.io/docker/pulls/shizunge/gantry.svg?label=Docker%20Pulls&logo=Docker)](https://hub.docker.com/r/shizunge/gantry)
[![Build](https://img.shields.io/github/actions/workflow/status/shizunge/gantry/on-push.yml?label=Build&branch=main&logo=GitHub)](https://github.com/shizunge/gantry/actions/workflows/on-push.yml)
[![Coverage](https://img.shields.io/codecov/c/github/shizunge/gantry.svg?token=47MWUJOH4Q&label=Coverage&logo=Codecov)](https://codecov.io/gh/shizunge/gantry)
[![CodeFactor Grade](https://img.shields.io/codefactor/grade/github/shizunge/gantry?label=CodeFactor&logo=CodeFactor)](https://www.codefactor.io/repository/github/shizunge/gantry)

[*Gantry*](https://github.com/shizunge/gantry) automatically updates selected docker swarm services to newer images with the same tag. It is inspired by but [enhanced Shepherd](docs/migration.md).

## Usage

*Gantry* is released as a container [image](https://hub.docker.com/r/shizunge/gantry). You can create a docker service and run it on a swarm manager node.

```
docker service create \
--name gantry \
--mode replicated-job \
--constraint "node.role==manager" \
--mount type=bind,source=/var/run/docker.sock,target=/var/run/docker.sock \
shizunge/gantry
```

Or with docker compose, see the [example](examples/README.md).

You can also run *Gantry* as a script directly on the host outside the container
```
./src/entrypoint.sh
```

*Gantry* is written to work with `busybox ash` (v1.35+) as well as `bash`.

## Configurations

You can configure the most behaviors of *Gantry* via environment variables.

### Common ones

| Environment Variable | Default |Description |
|-----------------------|---------|------------|
| GANTRY_LOG_LEVEL | INFO | Control how many logs generated by *Gantry*. Valid values are `NONE`, `ERROR`, `WARN`, `INFO`, `DEBUG` (case sensitive). |
| GANTRY_NODE_NAME | | Add node name to logs. If not set, *Gantry* will use the host name of the Docker Swarm's manager, which is read from either the Docker daemon socket of current node or `DOCKER_HOST`. |
| GANTRY_POST_RUN_CMD | | Command(s) to `eval` after each updating iteration. |
| GANTRY_PRE_RUN_CMD | | Command(s) to `eval` before each updating iteration. |
| GANTRY_SLEEP_SECONDS | 0 | Interval between two updates. Set it to 0 to run *Gantry* once and then exit. When this is a non-zero value, after an updating, *Gantry* will sleep until the next scheduled update. The actual sleep time is this value minus time spent on updating services. |
| TZ | | Set timezone for time in logs. |

*Gantry* bases on Docker command line, [environment variables](https://docs.docker.com/engine/reference/commandline/cli/#environment-variables) for Docker command line also works for *Gantry*.

### To login to registries

| Environment Variable | Default | Description |
|-----------------------|---------|-------------|
| GANTRY_REGISTRY_CONFIG | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_CONFIG_FILE | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_CONFIGS_FILE | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_HOST | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_HOST_FILE | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_PASSWORD | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_PASSWORD_FILE | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_USER | | See [Authentication](#authentication). |
| GANTRY_REGISTRY_USER_FILE | | See [Authentication](#authentication). |

### To select services

| Environment Variable | Default | Description |
|-----------------------|---------|-------------|
| GANTRY_SERVICES_EXCLUDED | | A space separated list of services names that are excluded from updating. |
| GANTRY_SERVICES_EXCLUDED_FILTERS | | A space separated list of [filters](https://docs.docker.com/engine/reference/commandline/service_ls/#filter), e.g. `label=project=project-a`. Exclude services which match the given filters from updating. Note that multiple filters will be logical **ANDED**. |
| GANTRY_SERVICES_FILTERS | | A space separated list of [filters](https://docs.docker.com/engine/reference/commandline/service_ls/#filter) that are accepted by `docker service ls --filter` to select services to update, e.g. `label=project=project-a`. Note that multiple filters will be logical **ANDED**. |
| GANTRY_SERVICES_SELF | | This is optional. When running as a docker service, *Gantry* will try to find the service name of itself automatically, and update itself firstly. The manifest inspection will be always performed on the *Gantry* service to avoid an infinity loop of updating itself. This can be used to ask *Gantry* to update another service firstly. |

### To check if new images are available

| Environment Variable | Default | Description |
|-----------------------|---------|-------------|
| GANTRY_MANIFEST_CMD | buildx | Valid values are `buildx`, `manifest`, and `none`.
Set which command for manifest inspection. Also see FAQ section [when to set `GANTRY_MANIFEST_CMD`](docs/faq.md#when-to-set-gantry_manifest_cmd).


  • [`docker buildx imagetools inspect`](https://docs.docker.com/engine/reference/commandline/buildx_imagetools_inspect/)

  • [`docker manifest inspect`](https://docs.docker.com/engine/reference/commandline/manifest_inspect/)

Set to `none` to skip checking the manifest. As a result of skipping, `docker service update` always runs. In case you add `--force` to `GANTRY_UPDATE_OPTIONS`, you also want to disable the inspection. |
| GANTRY_MANIFEST_OPTIONS | | [Options](https://docs.docker.com/engine/reference/commandline/buildx_imagetools_inspect/#options) added to the `docker buildx imagetools inspect` or [options](https://docs.docker.com/engine/reference/commandline/manifest_inspect/#options) to `docker manifest inspect`, depending on `GANTRY_MANIFEST_CMD` value. |

### To add options to services update

| Environment Variable | Default | Description |
|-----------------------|---------|-------------|
| GANTRY_ROLLBACK_ON_FAILURE | true | Set to `true` to enable rollback when updating fails. Set to `false` to disable the rollback. |
| GANTRY_ROLLBACK_OPTIONS | | [Options](https://docs.docker.com/engine/reference/commandline/service_update/#options) added to the `docker service update --rollback` command. |
| GANTRY_UPDATE_JOBS | false | Set to `true` to update replicated-job or global-job. Set to `false` to disable updating jobs. |
| GANTRY_UPDATE_NUM_WORKERS | 1 | The maximum number of updates that can run in parallel. |
| GANTRY_UPDATE_OPTIONS | | [Options](https://docs.docker.com/engine/reference/commandline/service_update/#options) added to the `docker service update` command. |
| GANTRY_UPDATE_TIMEOUT_SECONDS | 300 | Error out if updating of a single service takes longer than the given time. |

### After updating

| Environment Variable | Default | Description |
|-----------------------|---------|-------------|
| GANTRY_CLEANUP_IMAGES | true | Set to `true` to clean up the updated images. Set to `false` to disable the cleanup. Before cleaning up, *Gantry* will try to remove any *exited* and *dead* containers that are using the images. |
| GANTRY_CLEANUP_IMAGES_OPTIONS | | [Options](https://docs.docker.com/engine/reference/commandline/service_create/#options) added to the `docker service create` command to create a global job for images removal. You can use this to add a label to the service or the containers. |
| GANTRY_NOTIFICATION_APPRISE_URL | | Enable notifications on service update with [apprise](https://github.com/caronc/apprise-api). This must point to the notification endpoint (e.g. `http://apprise:8000/notify`) |
| GANTRY_NOTIFICATION_TITLE | | Add an additional message to the notification title. |

## Authentication

If you only need to login to a single registry, you can use the environment variables `GANTRY_REGISTRY_USER`, `GANTRY_REGISTRY_PASSWORD`, `GANTRY_REGISTRY_HOST` and `GANTRY_REGISTRY_CONFIG` to provide the authentication information. You may also use the `*_FILE` variants to pass the information through files. The files can be added to the service via [docker secret](https://docs.docker.com/engine/swarm/secrets/). `GANTRY_REGISTRY_HOST` and `GANTRY_REGISTRY_CONFIG` are optional. Use `GANTRY_REGISTRY_HOST` when you are not using Docker Hub. Use `GANTRY_REGISTRY_CONFIG` when you want to enable authentication for only selected services.

If the images of services are hosted on multiple registries that are required authentication, you should provide a configuration file to the *Gantry* and set `GANTRY_REGISTRY_CONFIGS_FILE` correspondingly. You can use [docker secret](https://docs.docker.com/engine/swarm/secrets/) to provision the configuration file. The configuration file must be in the following format:

* Each line should contain 4 columns, which are either `` or `` separated. The columns are
```

```
> * config name: an identifier for the account.
> * host: the registry to authenticate against, e.g. docker.io.
> * user: the user name to authenticate as.
> * password: the password to authenticate with.
* Lines starting with `#` are comments.
* Empty lines, comment lines and invalid lines are ignored.

You need to tell *Gantry* to use a named config rather than the default one when updating a particular service. The named configurations are set via either `GANTRY_REGISTRY_CONFIG`, `GANTRY_REGISTRY_CONFIG_FILE` or `GANTRY_REGISTRY_CONFIGS_FILE`. This can be done by adding the following label to the service `gantry.auth.config=`. *Gantry* creates [Docker configuration files](https://docs.docker.com/engine/reference/commandline/cli/#configuration-files) and adds `--config ` to the Docker command line for the corresponding services.

> NOTE: You also want to manually add `--with-registry-auth` to `GANTRY_UPDATE_OPTIONS` and `GANTRY_ROLLBACK_OPTIONS` when you enable authentication.

> NOTE: You can use `GANTRY_REGISTRY_CONFIGS_FILE` together with other authentication environment variables.

> NOTE: *Gantry* uses `GANTRY_REGISTRY_PASSWORD` and `GANTRY_REGISTRY_USER` to obtain Docker Hub rate when `GANTRY_REGISTRY_HOST` is empty or `docker.io`. You can also use their `_FILE` variants. If either password or user is empty, *Gantry* reads the Docker Hub rate for anonymous users.

## FAQ

[FAQ](docs/faq.md)

[Migrate from *Shepherd*](docs/migration.md)

## Development

*Gantry* is written to work with `busybox ash` (v1.35+), thus it could run easily in an alpine-based container without additional packages installed. One exception is that the notification feature requires `curl`. *Gantry* is also tested in `bash`.

[shellcheck](https://github.com/koalaman/shellcheck) will run on push to enforce the best practices of writing shell scripts. Some checks are disabled thanks to `busybox ash` supports more features than POSIX `sh`. You can find the list of disabled checks in [.shellcheckrc](.shellcheckrc).

To run `shellcheck` locally:
```
shellcheck src/*.sh tests/*.sh
```

The [tests](./tests/README.md) [folder](./tests) contains end-to-end tests, which cover the majority of the configuration options.

## Contacts

If you have any problems or questions, please contact me through a [GitHub issue](https://github.com/shizunge/gantry/issues).