Renovate

GitHub - renovatebot/renovate: Home of the Renovate CLI: Cross-platform Dependency Automation by Mend.io
Home of the Renovate CLI: Cross-platform Dependency Automation by Mend.io - renovatebot/renovate

While there are multiple solutions to keep dependencies and container images updated I wanted to try renovatebot for a while. I tested version 37-slim.

Source code: https://github.com/DorskFR/ghost.dorsk.dev/tree/main/overlays/renovate

tl;dr

Easy installation which took < 30min. The bot runs fine as a cronjob and requires up to 4GB memory.

Installation

Following the instructions at: https://docs.renovatebot.com/examples/self-hosting/#kubernetes makes for a very simple installation.

The bot runs as a cronjob and requires a config.json with general and / or per repository settings as well as a RENOVATE_TOKEN environment variable that gives the bot read write access to GitHub.

We can use the suggested yaml adding the limits to account for the memory usage. The bank-vaults annotations can be replaced with a kubernetes secret depending on how secrets are managed in the cluster.

apiVersion: batch/v1
kind: CronJob
metadata:
  name: renovate
spec:
  schedule: "@hourly"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      template:
        metadata:
          annotations:
            vault.security.banzaicloud.io/vault-role: "security-renovate"
            vault.security.banzaicloud.io/vault-env-from-path: "cyberia/data/security/renovate"
        spec:
          containers:
            - image: renovate/renovate:37-slim
              name: renovate
              envFrom:
                - configMapRef:
                    name: renovate
              resources:
                requests:
                  cpu: 10m
                  memory: 1Gi
                  ephemeral-storage: 1Gi
                limits:
                  cpu: 1
                  memory: 4Gi
                  ephemeral-storage: 4Gi
              volumeMounts:
                - name: renovate-files
                  mountPath: /opt/renovate/
                - name: work-volume
                  mountPath: /tmp/renovate/
          volumes:
            - name: renovate-files
              configMap:
                name: renovate-files
            - name: work-volume
              emptyDir: {}
          restartPolicy: Never
          serviceAccount: renovate

Using kustomize we can define the required configmaps via configMapGenerator:

configMapGenerator:
  - files:
      - files/config.json
    name: renovate-files
  - literals:
      - RENOVATE_BASE_DIR=/tmp/renovate/
      - RENOVATE_CONFIG_FILE=/opt/renovate/config.json
      - LOG_LEVEL=debug
    name: renovate

And finally we need a few secrets, starting with docker.com credentials, which are maybe not necessary but I was hitting the rate limit pretty quickly so decided to use them:

DOCKER_USERNAME=
DOCKER_PASSWORD=

Then my self-hosted registry which required activating the option detectHostRulesFromEnv and which follows a pattern described at https://docs.renovatebot.com/self-hosted-configuration/#detecthostrulesfromenv:

DOCKER_REGISTRY_EXAMPLE_COM_PASSWORD=
DOCKER_REGISTRY_EXAMPLE_COM_USERNAME=

Finally the GitHub personal access token used by renovatebot to read the repositories, open PRs, etc. I can't remember if the GITHUB_COM_TOKEN variable was required or not.

GITHUB_COM_TOKEN=github_pat_...
RENOVATE_TOKEN=github_pat_...

Since I wanted to focus renovatebot only on a few repositories I used a fine-grained personal access token. The required permissions are listed here: https://docs.renovatebot.com/modules/platform/github/#running-using-a-fine-grained-token

Configuration

It is possible to have a renovate.json or similar file (https://docs.renovatebot.com/configuration-options/) in each repository to control how each repository should behave but since we are self-hosting the bot we can also define the per repository configuration in config.json to keep the configuration in a single location.

To scope to only a few repositories I used autodiscover: false and defined each repository's settings in a separate block. The schema complains that repositories expects an array of strings but the configuration mentions that it can also be an array of objects and it works.

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "autodiscover": false,
  "detectHostRulesFromEnv": true,
  "extends": [
    "config:recommended"
  ],
  "gitAuthor": "MyGitHub <user@example.com>",
  "onboarding": false,
  "osvVulnerabilityAlerts": true,
  "platform": "github",
  "repositories": [
    {
      "enabledManagers": [
        "pip_requirements",
        "pip_setup",
        "poetry",
        "dockerfile"
      ],
      "packageRules": [
        {
          "enabled": true,
          "matchDatasources": [
            "pypi"
          ]
        }
      ],
      "repository": "MyGitHub/MyPythonRepository"
    },
    {
      "enabledManagers": [
        "gomod",
        "dockerfile"
      ],
      "packageRules": [
        {
          "enabled": true,
          "matchDatasources": [
            "go"
          ]
        }
      ],
      "repository": "MyGitHub/MyGoRepository"
    },
    {
      "enabledManagers": [
        "npm",
        "dockerfile"
      ],
      "packageRules": [
        {
          "enabled": true,
          "matchDatasources": [
            "npm"
          ]
        }
      ],
      "repository": "MyGitHub/MyNpmRepository"
    },
    {
      "enabledManagers": [
        "kubernetes",
        "kustomize"
      ],
      "kubernetes": {
        "fileMatch": [
          "overlays/.+\\.yaml$"
        ]
      },
      "kustomize": {
        "fileMatch": [
          "overlays/.+kustomization\\.ya?ml$"
        ]
      },
      "repository": "MyGitHub/MyInfraRepository"
    }
  ],
  "requireConfig": "optional",
  "vulnerabilityAlerts": {
    "enabled": true
  }
}

Conclusion

It took a few runs of the cronjob to populate all the PRs as it might have been hitting a few rate limits. Renovatebot opened PRs which I am reviewing and merging manually for now. I might switch to automatically merged PRs at some point.