Using private container registries with #Renovate #Docker

When using Renovate to update your dependencies, you will come across container images that are hosted in a private container registry or in a private repository of a public container registry. In both cases, you will need to configure Renovate with credentials to authenticate when checking for new versions of your container image. This post demonstrates how to configure Renovate correctly.

Using private repositories of a public container registry

This example assumes that your dependency is hosted in a private repository on Docker Hub. Credentials are passed to Renovate using host rules. Host rules match the target host, e.g. docker.io and provide credentials consisting of username and password:

{
  "hostrules": [
    {
      "hostType": "docker",
      "username": "foo_user",
      "password": "bar_pass"
    }
  ]
}

Using private repositories of any registry

If your container registry is not Docker Hub, then you must provide Renovate with a string to match the hostname against:

{
  "hostrules": [
    {
      "matchHost": "https://registry.dille.io",
      "username": "foo_user",
      "password": "bar_pass"
    }
  ]
}

You can leave out the hostType if it is not ambiguous, i.e. the hostname is only used for the container registry.

If matchHost starts with http:// or https:// it must be a prefix of the target host. Otherwise matchHost must be a suffix of the target host.

Passing secrets to Renovate

It is a bad idea to include the plaintext password in your renovate.json. Fortunately, this can be prevented by adding a secret variable:

The tricky part is accessing the secret from the configuration file. The renovate.json does not support reading secrets from the environment.

If you are using config.js to configure Renovate, you can use the following code to the an environment variable using process.env.VARIABLE_NAME:

{
  "hostrules": [
    {
      "matchHost": "https://registry.dille.io",
      "username": "foo_user",
      "password": process.env.REGISTRY_DILLE_IO_PASS
    }
  ]
}

In a self-hosted environment, global host rules can also be specified using the command line parameter --host-rules:

renovate --host-rules='{"hostType": "docker", "username": "foo_uer", "password": "bar_pass"}' #...

When using the Renovate GitHub app, you do not get access to secret due to security considerations. Instead, go to the encryption page and create and encrypted value for your organization and optionally the repository. The page uses Renovate’s public key to encrypt in the browser. I recommended using the page when disconnected from the internet to avoid trust issues. The host rule must be changed to the following:

{
  "hostrules": [
    {
      "matchHost": "https://registry.dille.io",
      "username": "foo_user",
      "encrypted": {
        "password": "<encrypted_value>"
      }
    }
  ]
}

Renovate can also read configuration values for host rules from environent variables when detecthostrulesfromenv is set to true. For example, the following environment variables can be used to configure a host rule:

DOCKER_MY_REGISTRY_COMPANY_COM_USERNAME=foo_user
DOCKER_MY_REGISTRY_COMPANY_COM_PASSWORD=bar_pass

Providing the registry URL

If you are using a regex manager to update the version of a container image, you have two options.

You can set the lookupName in the regex manager to add the missing hostname:

FROM ubuntu:22.04
# renovate: datasource=docker depName=docker lookupName=registry.dille.io/library/docker
ARG DOCKER_VERSION=20.10.20
RUN echo $DOCKER_VERSION

You can also create packageRules to specify registryUrls for dependencies matching the package rule (see matchPackageNames):

{
  "packageRules": [
    {
      "matchDatasources": ["docker"],
      "registryUrls": ["https://registry.dille.io"]
    }
  ]
}

More about host types

One of the examples above contained the hostType directive. Valid values are supported platforms as well as supported datasources.

{
  "hostrules": [
    {
      "matchHost": "dille.io",
      "hostType": "npm",
      "username": "foo_user",
      "password": "bar_pass"
    }
  ]
}
Feedback is always welcome! If you'd like to get in touch with me concerning the contents of this article, please use Twitter.