2020-03-28 21:05:59 +02:00
Watchtower supports private Docker image registries. In many cases, accessing a private registry
requires a valid username and password (i.e., _credentials_ ). In order to operate in such an
environment, watchtower needs to know the credentials to access the registry.
2019-12-25 22:58:19 +02:00
2020-03-28 21:05:59 +02:00
The credentials can be provided to watchtower in a configuration file called `config.json` .
There are two ways to generate this configuration file:
2019-12-25 22:58:19 +02:00
* The configuration file can be created manually.
2019-12-25 22:59:10 +02:00
* Call `docker login <REGISTRY_NAME>` and share the resulting configuration file.
2019-12-25 22:58:19 +02:00
### Create the configuration file manually
2020-03-28 21:05:59 +02:00
Create a new configuration file with the following syntax and a base64 encoded username and
password `auth` string:
2019-12-25 22:58:19 +02:00
```json
{
"auths": {
2019-12-25 22:59:10 +02:00
"< REGISTRY_NAME > ": {
2019-12-25 22:58:19 +02:00
"auth": "XXXXXXX"
}
}
}
```
2020-03-28 21:05:59 +02:00
`<REGISTRY_NAME>` needs to be replaced by the name of your private registry
(e.g., `my-private-registry.example.org` )
2019-12-25 22:58:19 +02:00
The required `auth` string can be generated as follows:
```bash
echo -n 'username:password' | base64
```
2020-03-28 21:05:59 +02:00
> ### ℹ️ Username and Password for GCloud
>
2020-07-15 19:56:01 +02:00
> For gcloud, we'll use `_json_key` as our username and the content
2020-03-28 21:05:59 +02:00
> of `gcloudauth.json` as the password.
2020-07-15 19:56:01 +02:00
>```bash
> echo -n "_json_key:$(cat gcloudauth.json)" | base64 -w0
>```
2020-03-28 21:05:59 +02:00
When the watchtower Docker container is started, the created configuration file
(`< PATH > /config.json` in this example) needs to be passed to the container:
2019-12-25 22:58:19 +02:00
```bash
docker run [...] -v < PATH > /config.json:/config.json containrrr/watchtower
```
### Share the Docker configuration file
2020-03-28 21:05:59 +02:00
To pull an image from a private registry, `docker login` needs to be called first, to get access
to the registry. The provided credentials are stored in a configuration file called `<PATH_TO_HOME_DIR>/.docker/config.json` .
This configuration file can be directly used by watchtower. In this case, the creation of an
additional configuration file is not necessary.
2019-12-25 22:58:19 +02:00
When the Docker container is started, pass the configuration file to watchtower:
2020-03-28 21:05:59 +02:00
2019-12-25 22:58:19 +02:00
```bash
docker run [...] -v < PATH_TO_HOME_DIR > /.docker/config.json:/config.json containrrr/watchtower
```
When creating the watchtower container via docker-compose, use the following lines:
2020-03-28 21:05:59 +02:00
2019-12-25 22:58:19 +02:00
```yaml
2020-10-03 22:07:42 +02:00
version: "3.4"
services:
watchtower:
image: index.docker.io/containrrr/watchtower:latest
volumes:
2019-12-25 22:58:19 +02:00
- /var/run/docker.sock:/var/run/docker.sock
- < PATH_TO_HOME_DIR > /.docker/config.json:/config.json
2020-10-03 22:07:42 +02:00
...
2019-12-25 22:58:19 +02:00
```
2020-07-16 11:35:59 +02:00
#### Docker Config path
By default, watchtower will look for the `config.json` file in `/` , but this can be changed by setting the `DOCKER_CONFIG` environment variable to the directory path where your config is located. This is useful for setups where the config.json file is changed while the watchtower instance is running, as the changes will not be picked up for a mounted file if the inode changes.
Example usage:
```yaml
2020-10-03 22:07:42 +02:00
version: "3.4"
services:
watchtower:
image: containrrr/watchtower
environment:
DOCKER_CONFIG: /config
2020-07-16 11:35:59 +02:00
volumes:
- /etc/watchtower/config/:/config/
- /var/run/docker.sock:/var/run/docker.sock
```
2019-12-25 22:58:19 +02:00
## Credential helpers
Some private Docker registries (the most prominent probably being AWS ECR) use non-standard ways of authentication.
2019-08-23 14:07:09 +02:00
To be able to use this together with watchtower, we need to use a credential helper.
To keep the image size small we've decided to not include any helpers in the watchtower image, instead we'll put the
helper in a separate container and mount it using volumes.
### Example
Example implementation for use with [amazon-ecr-credential-helper ](https://github.com/awslabs/amazon-ecr-credential-helper ):
2020-10-03 22:07:42 +02:00
Use the dockerfile below to build the [amazon-ecr-credential-helper ](https://github.com/awslabs/amazon-ecr-credential-helper ),
in a volume that may be mounted onto your watchtower container.
1. Create the Dockerfile (contents below):
2019-08-23 14:07:09 +02:00
```Dockerfile
FROM golang:latest
ENV CGO_ENABLED 0
ENV REPO github.com/awslabs/amazon-ecr-credential-helper/ecr-login/cli/docker-credential-ecr-login
RUN go get -u $REPO
RUN rm /go/bin/docker-credential-ecr-login
RUN go build \
-o /go/bin/docker-credential-ecr-login \
/go/src/$REPO
WORKDIR /go/bin/
```
2020-10-03 22:07:42 +02:00
2. Use the following commands to build the aws-ecr-dock-cred-helper and store it's output in a volume:
```shell script
# Create a volume to store the command (once built)
docker volume create helper
# Build the container
docker build -t aws-ecr-dock-cred-helper .
# Build the command and store it in the new volume in the /go/bin directory.
docker run -d --rm --name aws-cred-helper --volume helper:/go/bin aws-ecr-dock-cred-helper
```
3. Create a configuration file for docker, and store it in $HOME/.docker/config.json (replace the < AWS_ACCOUNT_ID >
placeholders with your AWS Account ID):
```json
{
"credsStore" : "ecr-login",
"HttpHeaders" : {
"User-Agent" : "Docker-Client/19.03.1 (XXXXXX)"
},
"auths" : {
"< AWS_ACCOUNT_ID > .dkr.ecr.us-west-1.amazonaws.com" : {}
},
"credHelpers": {
"< AWS_ACCOUNT_ID > .dkr.ecr.us-west-1.amazonaws.com" : "ecr-login"
}
}
```
4. Create a docker-compose file (as an example) to help launch the container:
2019-08-23 14:07:09 +02:00
and the docker-compose definition:
```yaml
2020-10-03 22:07:42 +02:00
version: "3.4"
2019-08-23 14:07:09 +02:00
services:
2020-10-03 22:07:42 +02:00
# Check for new images and restart things if a new image exists
# for any of our containers.
2019-08-23 14:07:09 +02:00
watchtower:
2020-10-03 22:07:42 +02:00
image: containrrr/watchtower:latest
2019-08-23 14:07:09 +02:00
volumes:
- /var/run/docker.sock:/var/run/docker.sock
2020-10-03 22:07:42 +02:00
- .docker/config.json:/config.json
2019-08-23 14:07:09 +02:00
- helper:/go/bin
environment:
- HOME=/
- PATH=$PATH:/go/bin
2020-10-03 22:07:42 +02:00
- AWS_REGION=us-west-1
2019-08-23 14:07:09 +02:00
volumes:
2020-10-03 22:07:42 +02:00
helper:
external: true
2019-08-23 14:07:09 +02:00
```
2020-10-03 22:07:42 +02:00
A few additional notes:
2019-12-25 14:32:39 +02:00
2020-10-03 22:07:42 +02:00
1. With docker-compose the volume (helper, in this case) MUST be set to `external: true` , otherwise docker-compose
will preface it with the directory name.
2. Note that "credsStore" : "ecr-login" is needed - and in theory if you have that you can remove the
credHelpers section
3. I have this running on an EC2 instance that has credentials assigned to it - so no keys are needed; however,
you may need to include the `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` environment variables as well.
4. An alternative to adding the various variables is to create a ~/.aws/config and ~/.aws/credentials files and
place the settings there, then mount the ~/.aws directory to / in the container.