Pin traefik reverse-proxy image instead of floating :latest tag #11

Open
opened 2026-08-29 14:15:38 -07:00 by admin · 2 comments
Owner

Summary

traefik/traefik.yaml's reverse-proxy service uses:

image: public.ecr.aws/docker/library/traefik:latest

This is an unpinned floating tag. Over time, a docker service update (or any operation that re-resolves :latest) can silently move this service across Traefik major versions without any corresponding change being visible in Git history.

Why this matters

This is suspected as a contributing factor in a separate open issue (traefik-certs-dumper crash-looping) — traefik-certs-dumper is version-pinned (v2.11.4) and expects a specific acme.json schema shape; if reverse-proxy drifts to a newer/older Traefik major version independently, the two services' assumptions about acme.json's format can silently diverge with no error until the dumper panics trying to parse it.

Suggested fix

  1. Determine the actual currently-running Traefik version (docker exec <reverse-proxy-container> traefik version).
  2. Pin traefik/traefik.yaml's reverse-proxy image to that specific version tag (or digest) explicitly in Gitea.
  3. Going forward, bump this deliberately (via a reviewed commit) rather than relying on :latest to auto-resolve, consistent with this repo's general pinned-version convention for other stacks.
  4. Cross-reference with the traefik-certs-dumper crash-loop issue once resolved, to confirm which version pairing is actually compatible.
## Summary `traefik/traefik.yaml`'s `reverse-proxy` service uses: ```yaml image: public.ecr.aws/docker/library/traefik:latest ``` This is an unpinned floating tag. Over time, a `docker service update` (or any operation that re-resolves `:latest`) can silently move this service across Traefik major versions without any corresponding change being visible in Git history. ## Why this matters This is suspected as a contributing factor in a separate open issue (`traefik-certs-dumper crash-looping`) — `traefik-certs-dumper` is version-pinned (`v2.11.4`) and expects a specific `acme.json` schema shape; if `reverse-proxy` drifts to a newer/older Traefik major version independently, the two services' assumptions about `acme.json`'s format can silently diverge with no error until the dumper panics trying to parse it. ## Suggested fix 1. Determine the actual currently-running Traefik version (`docker exec <reverse-proxy-container> traefik version`). 2. Pin `traefik/traefik.yaml`'s `reverse-proxy` image to that specific version tag (or digest) explicitly in Gitea. 3. Going forward, bump this deliberately (via a reviewed commit) rather than relying on `:latest` to auto-resolve, consistent with this repo's general pinned-version convention for other stacks. 4. Cross-reference with the `traefik-certs-dumper` crash-loop issue once resolved, to confirm which version pairing is actually compatible.
Author
Owner

Status check — still open, not yet addressed

Confirmed via docker service inspect traefik_reverse-proxy:

Image: public.ecr.aws/docker/library/traefik:latest@sha256:9c2a54d87f76f5c2f5f2682c68394af92fb12c0a2686798d6462a3f84bd78eaf

Still an unpinned floating tag — no change made here. Leaving open. The related crash-loop issue (#10) has been resolved by the recent traefik-certs-dumper version catching up to what was already pinned in Git, but that doesn't address the underlying risk this issue tracks (reverse-proxy itself drifting silently on a future :latest re-resolve). Recommend pinning to the digest currently running (above) as the next concrete step.

## Status check — still open, not yet addressed Confirmed via `docker service inspect traefik_reverse-proxy`: ``` Image: public.ecr.aws/docker/library/traefik:latest@sha256:9c2a54d87f76f5c2f5f2682c68394af92fb12c0a2686798d6462a3f84bd78eaf ``` Still an unpinned floating tag — no change made here. Leaving open. The related crash-loop issue (#10) has been resolved by the recent `traefik-certs-dumper` version catching up to what was already pinned in Git, but that doesn't address the underlying risk this issue tracks (reverse-proxy itself drifting silently on a future `:latest` re-resolve). Recommend pinning to the digest currently running (above) as the next concrete step.
Author
Owner

Plan update: implement via Renovate, not a one-off manual pin

Checked what's already in this repo — Renovate tooling exists but appears dormant:

  • renovate.json (repo root) — full config already present: schedule (2–6am weekdays PT), package rules for auto-merge (patch-only on low-risk stacks), digest auto-merge, and — relevant here — traefik.yaml/traefik.env are already listed under the "NEVER auto-merge bootstrap/critical stacks" rule. So once Renovate is live, a traefik version bump will still arrive as a PR requiring manual review/merge, not silently auto-merged. That matches the caution this stack needs.
  • .woodpecker/renovate.yml — a Woodpecker cron pipeline (when: event: cron, cron: renovate) that runs the renovate/renovate:latest image against RENOVATE_REPOSITORIES=homelab/compose-files, using a renovate_token Woodpecker secret.
  • renovate/renovate.yaml + renovate/renovate.env.example — a manual/reference compose service (replicas: 0) for running Renovate by hand if needed; not the normal execution path.

Why "I've never seen anything from it" is likely NOT a webhook problem in the way I initially assumed

.woodpecker/renovate.yml's own header comment states: "Teams notifications are delivered via Gitea webhook → Power Automate" — that webhook is for notifications only (PR-created → Teams ping), separate from what actually runs Renovate. Renovate's execution path here is a Woodpecker cron trigger, not a webhook at all. So there are two independent things that could be broken, and fixing the notification webhook won't make Renovate start running if the real problem is the cron side:

  1. Woodpecker cron job: .woodpecker/renovate.yml only fires if a cron schedule literally named renovate is configured in Woodpecker's UI (Repo → Settings → Cron) for homelab/compose-files. If that cron entry was never created (or was deleted/misnamed), this pipeline silently never runs — no error, no webhook involved, nothing to see. This is the most likely explanation for total silence.
  2. renovate_token secret: needs a valid Gitea PAT (ideally a dedicated renovate-bot account matching RENOVATE_GIT_AUTHOR) with write access to this repo, set as a Woodpecker secret. If missing/expired, the pipeline would run but fail early — that would show up in Woodpecker's run history, unlike (1).
  3. Teams notification webhook (Gitea → Power Automate): separate from both of the above — only affects whether you get pinged, not whether Renovate itself is working. Worth checking Gitea's PR list directly for homelab/compose-files for any renovate/* branches or bot-authored PRs — that would tell us definitively whether Renovate has been running invisibly (notification-only failure) vs. never running at all (cron/token failure).

I don't have tooling access to Woodpecker's cron configuration, its per-repo run history, or Gitea's webhook delivery logs — those need checking directly in each UI.

Additional work needed before this issue can close

  1. Confirm/create the Woodpecker cron job named renovate for this repo (likely root cause of "never seen anything").
  2. Confirm the renovate_token secret exists and is valid.
  3. Check Gitea PR history for homelab/compose-files for any existing renovate/* bot branches, to distinguish "never ran" from "ran but notification silently failed."
  4. Separately, verify/fix the Gitea webhook → Power Automate → Teams path for notifications.
  5. Prerequisite specific to this issue's original ask: Renovate's Docker datasource generally can't manage a floating :latest tag — it needs an explicit version string to diff against to propose bumps. So traefik/traefik.yaml's reverse-proxy image still needs the one-time manual pin (see original issue body, step 1–2: get the live version via docker exec ... traefik version, pin explicitly) before Renovate can take over keeping it current going forward via PRs.
  6. Once pinned, confirm the existing "never auto-merge" packageRule filename match still covers it correctly and decide if that's still the desired policy.

Leaving this open — re-scoping it as "pin traefik image + get Renovate actually running for it" rather than a pure manual one-off.

## Plan update: implement via Renovate, not a one-off manual pin Checked what's already in this repo — Renovate tooling exists but appears dormant: - `renovate.json` (repo root) — full config already present: schedule (2–6am weekdays PT), package rules for auto-merge (patch-only on low-risk stacks), digest auto-merge, and — relevant here — **`traefik.yaml`/`traefik.env` are already listed under the "NEVER auto-merge bootstrap/critical stacks" rule**. So once Renovate is live, a traefik version bump will still arrive as a PR requiring manual review/merge, not silently auto-merged. That matches the caution this stack needs. - `.woodpecker/renovate.yml` — a Woodpecker **cron** pipeline (`when: event: cron, cron: renovate`) that runs the `renovate/renovate:latest` image against `RENOVATE_REPOSITORIES=homelab/compose-files`, using a `renovate_token` Woodpecker secret. - `renovate/renovate.yaml` + `renovate/renovate.env.example` — a manual/reference compose service (`replicas: 0`) for running Renovate by hand if needed; not the normal execution path. ### Why "I've never seen anything from it" is likely NOT a webhook problem in the way I initially assumed `.woodpecker/renovate.yml`'s own header comment states: *"Teams notifications are delivered via Gitea webhook → Power Automate"* — that webhook is for **notifications only** (PR-created → Teams ping), separate from what actually **runs** Renovate. Renovate's execution path here is a **Woodpecker cron trigger**, not a webhook at all. So there are two independent things that could be broken, and fixing the notification webhook won't make Renovate start running if the real problem is the cron side: 1. **Woodpecker cron job**: `.woodpecker/renovate.yml` only fires if a cron schedule literally named `renovate` is configured in Woodpecker's UI (Repo → Settings → Cron) for `homelab/compose-files`. If that cron entry was never created (or was deleted/misnamed), this pipeline **silently never runs** — no error, no webhook involved, nothing to see. This is the most likely explanation for total silence. 2. **`renovate_token` secret**: needs a valid Gitea PAT (ideally a dedicated `renovate-bot` account matching `RENOVATE_GIT_AUTHOR`) with write access to this repo, set as a Woodpecker secret. If missing/expired, the pipeline would run but fail early — that *would* show up in Woodpecker's run history, unlike (1). 3. **Teams notification webhook** (Gitea → Power Automate): separate from both of the above — only affects whether you get pinged, not whether Renovate itself is working. Worth checking Gitea's PR list directly for `homelab/compose-files` for any `renovate/*` branches or bot-authored PRs — that would tell us definitively whether Renovate has been running invisibly (notification-only failure) vs. never running at all (cron/token failure). I don't have tooling access to Woodpecker's cron configuration, its per-repo run history, or Gitea's webhook delivery logs — those need checking directly in each UI. ### Additional work needed before this issue can close 1. Confirm/create the Woodpecker cron job named `renovate` for this repo (likely root cause of "never seen anything"). 2. Confirm the `renovate_token` secret exists and is valid. 3. Check Gitea PR history for `homelab/compose-files` for any existing `renovate/*` bot branches, to distinguish "never ran" from "ran but notification silently failed." 4. Separately, verify/fix the Gitea webhook → Power Automate → Teams path for notifications. 5. **Prerequisite specific to this issue's original ask**: Renovate's Docker datasource generally can't manage a floating `:latest` tag — it needs an explicit version string to diff against to propose bumps. So `traefik/traefik.yaml`'s `reverse-proxy` image still needs the one-time manual pin (see original issue body, step 1–2: get the live version via `docker exec ... traefik version`, pin explicitly) **before** Renovate can take over keeping it current going forward via PRs. 6. Once pinned, confirm the existing "never auto-merge" packageRule filename match still covers it correctly and decide if that's still the desired policy. Leaving this open — re-scoping it as "pin traefik image + get Renovate actually running for it" rather than a pure manual one-off.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: homelab/compose-files#11