← All articles
photo of optical disc drive

Renovate: Automate Dependency Updates Across Your Self-Hosted Projects

DevOps 2026-02-28 · 4 min read renovate dependency-management automation docker devops security
By Selfhosted Guides Editorial TeamSelf-hosting practitioners covering open source software, home lab infrastructure, and data sovereignty.

Keeping dependencies up to date is one of those maintenance tasks that's easy to let slip. An npm package with a known CVE, a Docker image that's six months out of date, a Helm chart from before a breaking change — these accumulate until you have a significant security and maintenance debt.

Photo by Patrick Lindenberg on Unsplash

Renovate solves this by automatically detecting outdated dependencies across your projects and opening pull requests to update them. It's the same tool used by thousands of open-source projects, and it runs self-hosted for free.

Renovate pull request list showing automated dependency updates for Docker, npm, and GitHub Actions

What Renovate Supports

Renovate has remarkably wide ecosystem coverage:

Ecosystem Examples
Node.js package.json, npm, Yarn, pnpm, Bun
Container images Dockerfile, Docker Compose, docker-compose.yml
GitHub Actions .github/workflows/*.yml
Kubernetes Helm charts, Kustomize, raw YAML images
Python requirements.txt, pyproject.toml, Pipfile
Go go.mod, go.sum
Rust Cargo.toml
Terraform Provider versions, module versions
.NET NuGet packages
Ansible Galaxy roles and collections
Ruby Gemfile

This makes it useful not just for application code but for your entire infrastructure-as-code setup.

Architecture: How It Works

Renovate runs as a scheduled job (cron or CI/CD pipeline) that:

  1. Scans configured repositories for dependency files
  2. Checks registries (npm, Docker Hub, GitHub releases, etc.) for newer versions
  3. Groups updates intelligently (e.g., all patch versions together)
  4. Opens pull requests with the changelog and version diff
  5. Automerges if configured and tests pass

The self-hosted version (renovate npm package) gives you full control over configuration and doesn't require sharing repository access with a third-party service.

Deployment Options

Option 1: GitHub Actions (Simplest)

Run Renovate as a scheduled GitHub Actions workflow — no server needed.

Create .github/workflows/renovate.yml:

name: Renovate
on:
  schedule:
    - cron: '0 4 * * *'  # Daily at 4am UTC
  workflow_dispatch:      # Manual trigger

jobs:
  renovate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Self-hosted Renovate
        uses: renovatebot/github-action@v40
        with:
          token: ${{ secrets.RENOVATE_TOKEN }}
        env:
          LOG_LEVEL: debug

Create a GitHub personal access token with repo scope and add it as RENOVATE_TOKEN in repository secrets.

Option 2: Self-Hosted with Gitea/Forgejo

For self-hosted Git platforms, run Renovate directly:

# Install
npm install -g renovate

# Run against a Gitea instance
RENOVATE_TOKEN=your-gitea-token \
RENOVATE_PLATFORM=gitea \
RENOVATE_ENDPOINT=https://git.yourdomain.com \
renovate your-username/your-repo

Schedule this as a cron job or systemd timer.

Option 3: Docker Compose

For multi-repository setups, a containerized deployment is cleaner:

services:
  renovate:
    image: renovate/renovate:latest
    environment:
      - RENOVATE_TOKEN=${RENOVATE_TOKEN}
      - RENOVATE_PLATFORM=github
      - LOG_LEVEL=info
    volumes:
      - ./renovate-config.json:/usr/src/app/config.js
    restart: no  # Run as one-shot

Trigger via docker-compose run renovate in a cron job.

Like what you're reading? Subscribe to Self-Hosted Weekly — free weekly guides in your inbox.

Configuration

Renovate is configured via renovate.json (or renovate.json5) in each repository.

Minimal configuration

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": [
    "config:recommended"
  ]
}

This enables the recommended defaults: groups related updates, automerges patch versions for dev dependencies, and creates PRs during business hours.

Docker-focused homelab configuration

{
  "$schema": "https://docs.renovatebot.com/renovate-schema.json",
  "extends": ["config:recommended"],
  "timezone": "America/Los_Angeles",
  "schedule": ["after 10pm on saturday"],
  "prHourlyLimit": 5,
  "prConcurrentLimit": 10,
  "packageRules": [
    {
      "matchDatasources": ["docker"],
      "matchUpdateTypes": ["minor", "patch"],
      "automerge": true,
      "automergeType": "pr",
      "requiredStatusChecks": null
    },
    {
      "matchDatasources": ["docker"],
      "matchUpdateTypes": ["major"],
      "labels": ["major-update"],
      "reviewers": ["your-username"]
    }
  ]
}

This configuration:

Pinning vs. range updates

By default, Renovate updates dependencies to the latest version. For Docker images in production, you may want to pin to specific digests for reproducibility:

{
  "packageRules": [
    {
      "matchDatasources": ["docker"],
      "pinDigests": true
    }
  ]
}

This replaces image: postgres:16 with image: postgres:16@sha256:abc123... — guaranteed reproducible deployments. Renovate then opens PRs to update the digest when the underlying image changes.

Grouping Updates

Renovate can group related updates into a single PR to reduce noise:

{
  "packageRules": [
    {
      "groupName": "all non-major updates",
      "matchUpdateTypes": ["minor", "patch"],
      "groupSlug": "all-minor-patch"
    },
    {
      "groupName": "linting tools",
      "matchPackageNames": ["eslint", "biome", "prettier", "@types/eslint"],
      "groupSlug": "linting"
    }
  ]
}

Useful Presets

Renovate has a preset system for common configurations:

Preset Effect
config:recommended Sensible defaults for most projects
schedule:weekly Run updates once per week
:semanticCommits Conventional commit messages on PRs
:pinAllExceptPeerDependencies Pin everything except peer deps
docker:enableMajor Include major Docker image updates
helpers:pinGitHubActionDigests Pin GitHub Action versions to SHA
{
  "extends": [
    "config:recommended",
    "schedule:weekly",
    ":semanticCommits",
    "helpers:pinGitHubActionDigests"
  ]
}

Dependency Dashboard

When Renovate runs, it creates a Dependency Dashboard issue in your repository listing all detected updates, their status, and any pending PRs. This gives you a centralized view of your dependency state across all ecosystems.

The dashboard also lets you manually trigger updates by checking a checkbox in the issue — useful when you want to force a specific update outside the normal schedule.

Security Updates: Immediate Processing

For security vulnerabilities, you don't want to wait for the weekly schedule. Configure Renovate to handle OSV/GHSA security updates immediately:

{
  "vulnerabilityAlerts": {
    "labels": ["security"],
    "schedule": ["at any time"],
    "automerge": true
  }
}

This automerges security patches immediately when they're available, regardless of your normal schedule.

Monitoring Multiple Repositories

For homelabs with many repositories, configure Renovate's global config file to discover repositories automatically:

// config.js
module.exports = {
  platform: 'github',
  token: process.env.RENOVATE_TOKEN,
  autodiscover: true,  // Scan all accessible repos
  autodiscoverFilter: 'your-org/*',  // Limit to specific org
  onboarding: true,  // Auto-create renovate.json in repos without one
};

With autodiscover, Renovate finds all repositories you have access to and processes those that have a renovate.json file (or creates one if onboarding is enabled).

Alternatives

Tool Approach
Dependabot GitHub-native, free, less configurable, no self-hosting
Snyk Security-focused, paid for full features
Watchtower Updates running Docker containers directly (more aggressive)
Diun Docker image update notifications without PRs

Renovate is the most configurable and broadest in ecosystem coverage. Dependabot is simpler for pure GitHub use but can't match Renovate's customization. Watchtower/Diun are for update notifications rather than full automation with PR review.

Getting Started

  1. Create a bot account on your Git platform (GitHub/Gitea)
  2. Grant it read/write access to target repositories
  3. Add renovate.json to each repository with your desired configuration
  4. Deploy Renovate using one of the methods above
  5. Check the Dependency Dashboard issue for initial findings

Renovate's initial scan often reveals significant accumulated debt — dozens of outdated packages you didn't know about. Start with automerging minor/patch updates and manually reviewing major versions. Over time, you'll establish a rhythm where your dependencies stay current with minimal manual work.

Get free weekly tips in your inbox. Subscribe to Self-Hosted Weekly