Files
homelab-design/decisions/0036-renovate-dependency-updates.md

8.9 KiB

Automated Dependency Updates with Renovate

  • Status: accepted
  • Date: 2026-02-05
  • Deciders: Billy
  • Technical Story: Automate dependency updates across all homelab repositories

Context and Problem Statement

The homelab consists of 20+ repositories containing:

  • Kubernetes manifests with container image references
  • Helm chart versions
  • Python/Go dependencies
  • GitHub Actions / Gitea Actions workflow versions

Manually tracking and updating dependencies is:

  • Time-consuming
  • Error-prone
  • Often neglected until security issues arise

How do we automate dependency updates while maintaining control over what gets updated?

Decision Drivers

  • Automated detection of outdated dependencies
  • PR-based update workflow for review
  • Support for Kubernetes manifests, Helm, Python, Go, Docker
  • Self-hosted on existing infrastructure
  • Configurable grouping and scheduling
  • Security update prioritization

Considered Options

  1. Renovate (self-hosted)
  2. Dependabot (GitHub-native)
  3. Manual updates with version scripts
  4. Flux image automation

Decision Outcome

Chosen option: Option 1 - Renovate (self-hosted)

Renovate runs as a CronJob in the cluster, scanning all repositories in the Gitea organization and creating PRs for outdated dependencies. It supports more package managers than Dependabot and works with Gitea.

Positive Consequences

  • Comprehensive manager support (40+ package managers)
  • Works with self-hosted Gitea
  • Configurable grouping (batch minor updates)
  • Auto-merge for patch/minor updates
  • Dashboard for update overview
  • Reusable preset configurations

Negative Consequences

  • Additional CronJob to maintain
  • Configuration complexity
  • API token management for Gitea access

Architecture

┌───────────────────────────────────────────────────────────────────┐
│                      Renovate CronJob                              │
│                      (ci-cd namespace)                             │
│                                                                    │
│  Schedule: Every 8 hours (0 */8 * * *)                            │
│                                                                    │
│  ┌────────────────────────────────────────────────────────────┐   │
│  │                    Renovate Container                       │   │
│  │                                                             │   │
│  │  1. Fetch repositories from Gitea org                       │   │
│  │  2. Scan each repo for dependencies                         │   │
│  │  3. Compare versions with upstream registries               │   │
│  │  4. Create/update PRs for outdated deps                     │   │
│  │  5. Auto-merge approved patches                             │   │
│  └────────────────────────────────────────────────────────────┘   │
└───────────────────────────────────────────────────────────────────┘
                                  │
                                  ▼
┌───────────────────────────────────────────────────────────────────┐
│                         Gitea                                      │
│                                                                    │
│  ┌───────────────┐  ┌───────────────┐  ┌───────────────┐          │
│  │ homelab-k8s2  │  │ chat-handler  │  │ kuberay-images│          │
│  │               │  │               │  │               │          │
│  │ PR: Update    │  │ PR: Update    │  │ PR: Update    │          │
│  │ flux to 2.5.0 │  │ httpx to 0.28 │  │ ROCm to 6.4   │          │
│  └───────────────┘  └───────────────┘  └───────────────┘          │
└───────────────────────────────────────────────────────────────────┘

Configuration

CronJob

apiVersion: batch/v1
kind: CronJob
metadata:
  name: renovate
  namespace: ci-cd
spec:
  schedule: "0 */8 * * *"  # Every 8 hours
  jobTemplate:
    spec:
      template:
        spec:
          containers:
            - name: renovate
              image: renovate/renovate:39
              env:
                - name: RENOVATE_PLATFORM
                  value: "gitea"
                - name: RENOVATE_ENDPOINT
                  value: "https://git.daviestechlabs.io/api/v1"
                - name: RENOVATE_TOKEN
                  valueFrom:
                    secretKeyRef:
                      name: renovate-github-token
                      key: token
                - name: RENOVATE_AUTODISCOVER
                  value: "true"
                - name: RENOVATE_AUTODISCOVER_FILTER
                  value: "daviestechlabs/*"
          restartPolicy: OnFailure

Repository Config (renovate.json)

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended",
    "group:allNonMajor",
    ":automergeMinor",
    ":automergePatch"
  ],
  "kubernetes": {
    "fileMatch": ["\\.ya?ml$"]
  },
  "packageRules": [
    {
      "matchManagers": ["helm-values", "helmv3"],
      "groupName": "helm charts"
    },
    {
      "matchPackagePatterns": ["^ghcr.io/"],
      "groupName": "GHCR images"
    },
    {
      "matchUpdateTypes": ["major"],
      "automerge": false,
      "labels": ["major-update"]
    }
  ],
  "schedule": ["before 6am on monday"]
}

Supported Package Managers

Manager File Patterns Examples
kubernetes *.yaml, *.yml Container images in Deployments
helm Chart.yaml, values.yaml Helm chart dependencies
helmv3 HelmRelease CRDs Flux HelmReleases
flux Flux CRDs GitRepository, OCIRepository
pip requirements.txt, pyproject.toml Python packages
gomod go.mod Go modules
dockerfile Dockerfile* Base images
github-actions .github/workflows/*.yml Action versions
gitea-actions .gitea/workflows/*.yml Action versions

Update Strategy

Auto-merge Enabled

Update Type Auto-merge Delay
Patch (x.x.1 → x.x.2) Yes Immediate
Minor (x.1.x → x.2.x) Yes 3 days stabilization
Major (1.x.x → 2.x.x) No Manual review

Grouping Strategy

Group Contents Frequency
all-non-major All patch + minor updates Weekly (Monday)
helm-charts All Helm chart updates Weekly
container-images Docker image updates Weekly
security CVE fixes Immediate

Security Updates

Renovate prioritizes security updates:

{
  "vulnerabilityAlerts": {
    "enabled": true,
    "labels": ["security"]
  },
  "packageRules": [
    {
      "matchCategories": ["security"],
      "automerge": true,
      "schedule": ["at any time"],
      "prPriority": 10
    }
  ]
}

Dashboard

Renovate creates a "Dependency Dashboard" issue in each repository:

## Dependency Dashboard

### Open PRs
- [ ] Update httpx to 0.28.1 (#42)
- [x] Update pillow to 11.0.0 (#41) - merged

### Pending Approval
- [ ] Major: Update pydantic to v2 (#40)

### Rate Limited
- fastapi (waiting for next schedule window)

Secrets

Secret Source Purpose
renovate-github-token Vault Gitea API access
renovate-dockerhub Vault Docker Hub rate limits

Monitoring

# Renovate job success rate
sum(kube_job_status_succeeded{job_name=~"renovate-.*"}) 
/ 
sum(kube_job_status_succeeded{job_name=~"renovate-.*"} + kube_job_status_failed{job_name=~"renovate-.*"})