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. 🚀