Zum Hauptinhalt springen
Background Image

Automatisierte Docker Updates mit Renovate, GitHub und Portainer GitOps

·608 Wörter·3 min
Inhaltsverzeichnis

Motivation
#

Wer Container-Umgebungen produktiv betreibt, kennt das Problem: Images aktualisieren sich schnell, Sicherheitsfixes kommen laufend, und manuell hinterherzuziehen ist mühsam und fehleranfällig.

Mit einer Kombination aus Renovate, GitHub Actions und Portainer GitOps lässt sich dieser Prozess vollständig automatisieren:

  • Renovate prüft regelmäßig die eingesetzten Container-Images und erstellt Pull Requests für Updates.
  • GitHub Actions übernimmt die Automatisierung der Renovate-Läufe.
  • Portainer rollt die Änderungen aus dem Git-Repository automatisch auf die Docker-Umgebung aus.

Damit erhält man einen sauberen GitOps-Workflow für Docker Updates.


Renovate konfigurieren
#

Renovate läuft über eine GitHub Action und prüft ein docker-compose Repository.
Dafür wird eine zentrale config.js benötigt, die so aussieht (anonymisierte Version):

module.exports = {
  platform: 'github',
  token: process.env.RENOVATE_TOKEN,
  gitAuthor: 'Max Mustermann <max@example.com>',
  username: 'username123',
  repositories: ['username123/docker-compose'],
  onboarding: false,
  hostRules: [
    {
      hostType: 'docker',
      matchHost: 'docker.io',
      username: 'dockeruser',
      password: String(process.env.DOCKER_HUB_PASSWORD || ''),
    },
    {
      hostType: 'docker',
      matchHost: 'ghcr.io',
      username: 'username123',
      password: String(process.env.GHCR_TOKEN || ''),
    }
  ],
};

👉 Wichtig: Zugangsdaten (z. B. Docker Hub oder GitHub Container Registry) kommen ausschließlich aus GitHub Secrets.


GitHub Workflow
#

Der zugehörige Workflow (.github/workflows/renovate.yml) steuert die Ausführung von Renovate:

name: renovate

on:
  workflow_dispatch: # manuell starten
  schedule:          # täglicher Lauf um 12:00 UTC
    - cron: '0 12 * * *'
  push:              # nach Push auf main
    branches:
      - main

jobs:
  renovate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
      - name: Run Renovate
        uses: renovatebot/github-action@v43
        with:
          configurationFile: ${{ github.workspace }}/config.js
          token: ${{ secrets.RENOVATE_TOKEN }}
        env:
          DOCKER_HUB_PASSWORD: ${{ secrets.DOCKER_HUB_PASSWORD }}

Optionale Benachrichtigung
#

Optional lässt sich ein Benachrichtigungsschritt ergänzen, z. B. per ntfy, sobald ein Pull Request von Renovate offen ist. Beispiel:

- name: Check Open PRs and Notify
  env:
    GITHUB_TOKEN: ${{ secrets.RENOVATE_TOKEN }}
    NTFY_URL: ${{ secrets.NTFY_URL }}
    NTFY_TOKEN: ${{ secrets.NTFY_TOKEN }}
  run: |
    echo "Fetching open pull requests..."
    OPEN_PRS=$(gh pr list \
      --repo "flohoss/docker-compose" \
      --state open \
      --assignee "flohoss" \
      --json number,title,url)

    if [ "$(echo "$OPEN_PRS" | jq length)" -gt 0 ]; then
      echo "Open PRs found, sending notifications..."
      echo "$OPEN_PRS" | jq -c '.[]' | while read -r pr; do
        NUMBER=$(echo "$pr" | jq -r '.number')
        TITLE=$(echo "$pr" | jq -r '.title')
        URL=$(echo "$pr" | jq -r '.url')

        curl -s -X POST "$NTFY_URL" \
          -H "Authorization: Bearer $NTFY_TOKEN" \
          -H "X-Tags: twisted_rightwards_arrows" \
          -H "X-Title: PR #${NUMBER} - ${TITLE}" \
          -H "X-Actions: view, Open PR, ${URL}" \
          -d "A Renovate PR needs your attention."
      done
    else
      echo "No open pull requests found."
    fi

Renovate Regeln für Docker Images
#

Über die renovate.json Datei lassen sich gezielt Regeln setzen, welche Images aktualisiert oder auf bestimmte Versionen begrenzt werden sollen:

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "assignees": ["username123"],
  "packageRules": [
    {
      "matchDatasources": ["docker"],
      "matchPackageNames": ["redis"],
      "allowedVersions": "7.x"
    },
    {
      "matchDatasources": ["docker"],
      "matchPackageNames": ["postgres"],
      "allowedVersions": "17.x"
    },
    {
      "matchDatasources": ["docker"],
      "pinDigests": true
    }
  ]
}

Beispiele:

  • Redis wird nur in der 7er Version aktualisiert.
  • Postgres nur in der 17er Serie.
  • Alle Images werden mit digest-Pinning versehen, um reproduzierbare Builds zu sichern.

GitOps mit Portainer
#

Portainer kann Stacks direkt aus einem Git-Repository beziehen.

Beispiel:

  • Stack basiert auf https://github.com/username123/docker-compose.
  • In Portainer ist “Redeploy from git repository” aktiviert.
  • Zusätzlich ist ein Polling-Intervall konfiguriert (z. B. alle 5 Minuten).

👉 Sobald Renovate einen PR merged und der compose.yml aktualisiert ist, zieht Portainer automatisch die Änderungen und startet den Stack neu.

Das Ergebnis:

  • Kein manuelles Eingreifen bei Container-Updates.
  • Alle Änderungen sind über Git versioniert und nachvollziehbar.
  • Portainer sorgt für die automatisierte Ausführung in der Docker-Umgebung.

Fazit
#

Mit der Kombination aus Renovate + GitHub + Portainer GitOps entsteht ein schlanker, zuverlässiger Workflow für automatisierte Docker Updates:

  • PR-basierte Updates mit voller Transparenz
  • Konfigurierbare Update-Regeln (z. B. nur bestimmte Major-Versionen)
  • Automatischer Rollout in der Laufzeitumgebung

So spart man Zeit, reduziert Risiken und behält trotzdem die volle Kontrolle. 🚀

Florian Hoss
Autor
Florian Hoss