Gantry is a tool to update docker swarm services, enhanced Shepherd.
We release Gantry as a container image. 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 \
--env "GANTRY_NODE_NAME={{.Node.Hostname}}" \
shizunge/gantry
Or with docker compose, see the example.
You can also run Gantry as a script outside the container source ./src/entrypoint.sh
. Gantry is written to work with busybox ash
. It should also work with bash
.
You can configure the most behaviors of Gantry via environment variables.
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. | |
GANTRY_SLEEP_SECONDS | 0 | Sleep time between two updates. Set it to 0 to run Gantry once and then exit. |
TZ | Set timezone for time in logs. |
Environment Variable | Default | Description |
---|---|---|
GANTRY_REGISTRY_CONFIG | See Authentication. | |
GANTRY_REGISTRY_CONFIG_FILE | See Authentication. | |
GANTRY_REGISTRY_CONFIGS_FILE | See Authentication. | |
GANTRY_REGISTRY_HOST | See Authentication. | |
GANTRY_REGISTRY_HOST_FILE | See Authentication. | |
GANTRY_REGISTRY_PASSWORD | See Authentication. | |
GANTRY_REGISTRY_PASSWORD_FILE | See Authentication. | |
GANTRY_REGISTRY_USER | See Authentication. | |
GANTRY_REGISTRY_USER_FILE | See Authentication. |
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. Exclude services which match the given filters from updating. | |
GANTRY_SERVICES_FILTERS | A space separated list of filters that are accepted by docker service ls --filter to select services to update. |
|
GANTRY_SERVICES_SELF | A service name to indicate whether a service is Gantry itself. Gantry will be the first service being updated. The manifest inspection will be always performed on the Gantry service to avoid an infinity loop of updating itself. |
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 .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 added to the docker buildx imagetools inspect or options to docker manifest inspect , depending on GANTRY_MANIFEST_CMD value. |
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 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_OPTIONS | 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. |
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_NOTIFICATION_APPRISE_URL | Enable notifications on service update with apprise. | |
GANTRY_NOTIFICATION_TITLE | Add an additional message to the notification title. |
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. 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 only want to enable authentication for 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 to provision the configuration file. The configuration file must be in the following format:
- Each line should contain 4 columns, which are either
<TAB>
or<SPACE>
separated. The columns are
<config name> <host> <user> <password>
- config name: an identifier for the account. This should be an acceptable Docker config name.
- 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=<config-name>
.
NOTE: You also want to manually add
--with-registry-auth
toGANTRY_UPDATE_OPTIONS
andGANTRY_ROLLBACK_OPTIONS
when you enable authentication.
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 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.
To run shellcheck
locally:
shellcheck src/*.sh tests/*.sh
Majority of the configuration options are covered by end-to-end tests. It would be a good enhancement to generate coverage metrics that are missing today.
You can also run the tests locally. During testing, the tests will generate some temporary images, create services and run Gantry to update the services. The tests need to push those temporary images to a registry. Therefore you need to prepare a container repository before starting a test, and login to the registry via docekr login
.
To test Gantry scripts, and run all the tests locally:
./tests/run_all_tests.sh <repository-name> [registry]
If you want to test a container image of Gantry, you need to specify the image of Gantry via the environment variable GANTRY_TEST_CONTAINER_REPO_TAG
.
export GANTRY_TEST_CONTAINER_REPO_TAG=<gantry image>:<tag>
./tests/run_all_tests.sh <repository-name> [registry]
NOTE:
GANTRY_TEST_CONTAINER_REPO_TAG
specifies the container image of Gantry under test. On the other hand, what is passed to therun_all_tests.sh
as CLI arguments is the repository that holds temporary images generated during the tests.
You can select tests by populating test names to environment variable GANTRY_TEST_ENABLE_TESTS
. The item in that space separated list could be a regexp that grep -P
accepts. For example:
# Optionally set GANTRY_TEST_CONTAINER_REPO_TAG
export GANTRY_TEST_ENABLE_TESTS="test_new_image$"
./tests/run_all_tests.sh <repository-name> [registry]
If you have any problems or questions, please contact me through a GitHub issue.