Files
renovate/lib/modules/manager/dockerfile
Marius b22f58045e fix(manager): Handle variables with default values in registry aliases (#36293)
* fix(manager): handle registryAliases with shell variable defaults

Allows `registryAliases` keys to contain shell-style variables with
empty (or other) defaults, e.g. `${DEPENDENCY_PROXY:-}` or
`${CI_REGISTRY:-}`. The same image string is then resolved both
online (variable expanded) and offline (variable empty).

Changes in `dockerfile/extract.ts` (used by `gitlabci` too):
* Match the alias key as either `${name}/...` (existing) or `${name}...`
  when `name` already ends in a non-identifier boundary character such
  as `}`. Bare-identifier keys like `$CI_REGISTRY` continue to require
  the slash boundary so they no longer overmatch keys that begin with
  the same prefix (e.g. `$CI_REGISTRY` vs `$CI_REGISTRY_IMAGE`).
* Use `ensureTrailingSlash` to handle alias values that already include
  a trailing slash.
* Preserve the original `name` and path structure in `dep.depName`
  instead of substringing only after the alias `value`. This keeps the
  variable in the depName so it survives a `splitImageParts` round-trip
  and the resulting branch name comes out clean.

Adds `sanitizeDepName` regex passes in
`lib/workers/repository/updates/flatten.ts` so any leftover
`${VAR}`/`${VAR:-...}` placeholder is stripped from the depName before
it becomes a branch name (otherwise we'd get
`renovate/${dependency_proxy}python-3.x` instead of
`renovate/python-3.x`).

Tests cover:
* `${VAR:-}/image` (with slash) and `${VAR:-}image` (no slash, requires
  the boundary form).
* Overlapping prefixes: `$CI_REGISTRY` vs `$CI_REGISTRY_IMAGE`.
* Registry alias with port (`localhost:5000/repo`).
* `sanitizeDepName` strips `${VAR}` / `${VAR:-}` / bare `$VAR`.

Reproducer: https://github.com/Wayneoween/renovate-36293-repro

* revert(manager/gitlabci): keep regex group name as 'prefix'

Reverting the unrelated `prefix` -> `rawPrefix` rename in `depProxyRe`.
Per review on #36293, this rename is out of scope for the registry-alias
fix and just adds review surface.

* refactor(manager/dockerfile): narrow alias boundary check to '}'

Per review on #36293. The previous regex `/[^A-Za-z0-9_]$/` matched any
non-word ending, which is broader than the documented case (alias keys
ending in `}` from `${VAR}` / `${VAR:-...}`). Replace with a plain
`name.endsWith('}')` check, which also avoids re-building a regex on
every iteration of the alias loop.

Existing tests (`'variables with default and slash'`,
`'variables with default no slash'`, `'alias with digest only'`)
continue to exercise the `}`-boundary path; the `'overlapping prefixes'`
case continues to exercise the slash-only path.

* chore(manager/dockerfile): trim comment and TODO library/ strip edge

Per review on #36293:
* Drop the verbose explanation block above the depName-restore branch;
  the spec rows already document the expected shape.
* Add a TODO above the `dep.depName?.startsWith(valueWithSlash)` guard
  noting a pre-existing edge case: when the inner `getDep` strips a
  `library/` prefix (or similar) the depName no longer starts with
  `valueWithSlash`, so the alias-rooted depName is not restored. Out of
  scope for this PR.

* fix(manager/dockerfile): handle empty registry alias value

- strip trailing slash after ${VAR} placeholders in sanitizeDepName
- treat an empty registry alias value as Docker Hub instead of '/'
- clarify registry alias docs wording

* refactor(manager/dockerfile): drop redundant alias boundary guard

- `matchedAtBoundary` is only read behind `!matchedWithSlash`
- add docker-compose test for `${VAR:-}` registry aliases

* test(manager/dockerfile): pin special-prefix registry alias behavior

`getDep` strips `library/`, `amd64/` and `arm64/` as special prefixes, so
an alias whose value is one of those loses its alias-rooted `depName`.
Both the slash form and the variable form behave this way on `main`.
2026-09-03 12:43:47 +00:00
..

Supported dependencies

This manager extracts image references in a Dockerfile and/or Containerfile and supports:

FROM support

Renovate can update images referenced in FROM directives. This even works for multi-stage builds with many FROM directives in one Dockerfile.

FROM node:20.9.0

Advanced FROM flags like --platform or AS <name> are also supported:

FROM --platform=linux/amd64 node:20.9.0 AS installer

Also, Renovate will automatically expand variables and ARG directives:

ARG TAG=3.19.4
FROM alpine:${TAG}

Renovate supports variables with default values (using the :- syntax) when they are configured with registry aliases:

FROM ${CI_REGISTRY:-}alpine:3.19.4
{
  "registryAliases": {
    "${CI_REGISTRY:-}": "my-registry.io"
  }
}

Both image reference formats work:

  • With a slash after the variable: ${CI_REGISTRY:-}/alpine:3.19.4
  • Without a slash after the variable: ${CI_REGISTRY:-}alpine:3.19.4

The alias value works with or without a trailing slash.

COPY --from support

Renovate can update images referenced in COPY --from directives.

FROM node:20.9.0
COPY --from alpine:3.19.4 /bin/sh /usr/local/sh

RUN --mount support

Images referenced in RUN --mount directives are also supported.

FROM python:3.12
RUN --mount=from=ghcr.io/astral-sh/uv:0.5,source=/uv,target=/bin/uv \
    uv venv

syntax support

Renovate can update syntax references.

# syntax=docker/dockerfile:1.9.0
FROM alpine:3.19.4

Versioning

Renovate's managers does not understand versioning, that's up to Renovate's versioning modules. The default docker versioning for container image datasources treats suffixes as "compatibility", for example: -alpine. Many container images are not SemVer compliant because they use such suffixes in their tags.

If Renovate does not update your container images correctly, you may need to tell Renovate what versioning it should use. For example, if you know that an image follows SemVer, you can tell Renovate to use "semver" versioning for that image:

{
  "packageRules": [
    {
      "matchDatasources": ["docker"],
      "matchPackageNames": ["whitesource/renovate"],
      "versioning": "semver"
    }
  ]
}

Read Renovate's Docker Versioning docs to learn more.