Always-on Renovate in a Go scheduler wrapping the official image
50K+
Run Renovate as a resident, always-on container instead of a one-shot job, driven by a built-in interval scheduler or an external trigger. A tiny Go wrapper around the official renovate/renovate image; structured logs, no metrics, no open ports.
The Renovate CLI is designed to run once and exit; the usual self-hosted patterns schedule it with cron or a Kubernetes CronJob. If your stack schedules every other workload with always-on containers and external triggers (Ofelia, a webhook, a central orchestrator), an ephemeral docker run per cycle is the odd one out. This image keeps Renovate resident and lets you drive it the same way as everything else, while reusing the upstream image's runtime.
It deliberately has no built-in HTTP/webhook server; triggering is delegated to whatever already schedules your containers (docker exec, Ofelia, a webhook-driven action on a release, …).
Renovate is a Node.js application that shells out to git and, for lockfile maintenance, to language package managers; its default binarySource=install installs those toolchains at runtime via containerbase. There is no static, dependency-free form to drop on scratch. So this image builds on the official renovate/renovate image (the default image, which Renovate recommends for most users and which installs tools at runtime) and adds only the scheduler binary on top.
One deliberate trim: the bundled docker CLI is removed. Renovate invokes it only under binarySource=docker, which is deprecated upstream and not supported by this image; dropping the unused ~42 MB binary cuts attack surface and the CVE noise image scanners report against it.
renovate on a built-in interval (RUN_INTERVAL=6h): one run at startup when no successful run completed within the interval (the last-run record on /data survives restarts), then every interval. Or set RUN_INTERVAL=off and trigger each run externally (docker exec … run).run subcommand is a thin client that submits the request over an in-container unix socket, forwarding its repo arguments and its environment (a docker exec -e RENOVATE_X=… … run override reaches Renovate intact), and exits with that run's true result.github.com/cplieger/health: unhealthy when the last run failed, recovers on the next clean run.LOG_FORMAT=json) for collection by Alloy/Promtail/Loki, in both scheduling modes. The scheduler neither captures nor parses Renovate's output; it emits only its own lifecycle lines, with UTC timestamps regardless of the container's TZ.docker pull cplieger/docker-renovate-scheduler:latest
Also published to ghcr.io/cplieger/docker-renovate-scheduler with identical images and tags. Release versions are tagged vX.Y.Z alongside latest.
# Example compose for docker-renovate-scheduler. See the README for all configuration options and hardening.
services:
renovate:
image: ghcr.io/cplieger/docker-renovate-scheduler:latest
container_name: renovate
restart: unless-stopped
stop_grace_period: 10m # let an in-flight run drain on stop instead of exit 137; see README "Graceful shutdown"
environment:
RUN_INTERVAL: "6h" # built-in cadence (Go duration); "off" = external trigger; see README "Scheduling modes"
LOG_FORMAT: "json" # Renovate's own knob, not the scheduler's: structured logs for Alloy/Loki; see README "What it does"
# Renovate's own config (RENOVATE_*) is passed straight through:
RENOVATE_PLATFORM: "github"
RENOVATE_AUTODISCOVER: "true" # or set RENOVATE_REPOSITORIES
RENOVATE_TOKEN: "${RENOVATE_TOKEN}"
RENOVATE_GITHUB_COM_TOKEN: "${RENOVATE_GITHUB_COM_TOKEN}" # changelogs + dodge rate limits
RENOVATE_PERSIST_REPO_DATA: "true" # persist /data so runs git fetch, not clone
RENOVATE_REPOSITORY_CACHE: "enabled"
RENOVATE_X_SQLITE_PACKAGE_CACHE: "true" # bounded package cache for an always-on container; see README "Memory and the package cache"
volumes:
- "./data:/data" # persist clones, caches + the last-run record; create ./data owned by UID 12021 first (see README "Volumes")
Apache-2.0. See LICENSE. The image carries the license text of every bundled component under /usr/share/licenses/.
The runtime base is the official renovate/renovate image, which packages Renovate under AGPL-3.0. The version and digest that base is pinned to are in the Dockerfile's FROM line, and Renovate's license and the corresponding source for that version are in the upstream repository at the matching release tag (https://github.com/renovatebot/renovate/releases/tag/<version>). The build applies no patches to Renovate, so this repository's Dockerfile is the complete record of what it adds to that image (the scheduler binary and a Go toolchain) and what it removes from it (the unused docker CLI and TypeScript compiler binaries).
Content type
Image
Digest
sha256:d97b4bc94…
Size
501.9 MB
Last updated
about 1 hour ago
docker pull cplieger/docker-renovate-scheduler