diff --git a/app/model/container.js b/app/model/container.js
index eb9f4679..a6190455 100644
--- a/app/model/container.js
+++ b/app/model/container.js
@@ -26,6 +26,7 @@ const schema = joi.object({
.object({
name: joi.string().min(1).required(),
url: joi.string().min(1).required(),
+ lookupImage: joi.string(),
})
.required(),
name: joi.string().min(1).required(),
diff --git a/app/prometheus/container.js b/app/prometheus/container.js
index 1badf12e..20c6ee29 100644
--- a/app/prometheus/container.js
+++ b/app/prometheus/container.js
@@ -55,6 +55,7 @@ function init() {
'image_id',
'image_name',
'image_os',
+ 'image_registry_lookup_image',
'image_registry_name',
'image_registry_url',
'image_tag_semver',
diff --git a/app/watchers/providers/docker/Docker.js b/app/watchers/providers/docker/Docker.js
index 4c154d05..43cef2c2 100644
--- a/app/watchers/providers/docker/Docker.js
+++ b/app/watchers/providers/docker/Docker.js
@@ -21,6 +21,7 @@ const {
wudDisplayIcon,
wudTriggerInclude,
wudTriggerExclude,
+ wudRegistryLookupImage,
} = require('./label');
const storeContainer = require('../../../store/container');
const log = require('../../../log');
@@ -112,15 +113,31 @@ function getTagCandidates(container, tags, logContainer) {
function normalizeContainer(container) {
const containerWithNormalizedImage = container;
- const registryProvider = Object.values(getRegistries()).find((provider) =>
- provider.match(container.image),
+ // Create a temporary image with parsed lookupImage if present for registry matching
+ let imageForMatching = container.image;
+ if (container.image.registry.lookupImage) {
+ const parsedLookupImage = parse(container.image.registry.lookupImage);
+ // If no domain specified, default to Docker Hub registry
+ const registryUrl = parsedLookupImage.domain || 'registry-1.docker.io';
+ imageForMatching = {
+ ...container.image,
+ registry: {
+ ...container.image.registry,
+ url: registryUrl,
+ },
+ name: parsedLookupImage.path,
+ };
+ }
+ const registries = getRegistries();
+ const registryProvider = Object.values(registries).find((provider) =>
+ provider.match(imageForMatching),
);
if (!registryProvider) {
log.warn(`${fullName(container)} - No Registry Provider found`);
containerWithNormalizedImage.image.registry.name = 'unknown';
} else {
containerWithNormalizedImage.image = registryProvider.normalizeImage(
- container.image,
+ imageForMatching,
);
containerWithNormalizedImage.image.registry.name =
registryProvider.getId();
@@ -545,6 +562,7 @@ class Docker extends Component {
container.Labels[wudDisplayIcon],
container.Labels[wudTriggerInclude],
container.Labels[wudTriggerExclude],
+ container.Labels[wudRegistryLookupImage],
),
);
const containersWithImage = await Promise.all(containerPromises);
@@ -670,6 +688,7 @@ class Docker extends Component {
displayIcon,
triggerInclude,
triggerExclude,
+ wudRegistryLookupImageValue,
) {
const containerId = container.Id;
@@ -738,6 +757,7 @@ class Docker extends Component {
id: imageId,
registry: {
url: parsedImage.domain,
+ lookupImage: wudRegistryLookupImageValue,
},
name: parsedImage.path,
tag: {
diff --git a/app/watchers/providers/docker/label.js b/app/watchers/providers/docker/label.js
index 77745450..5d91683e 100644
--- a/app/watchers/providers/docker/label.js
+++ b/app/watchers/providers/docker/label.js
@@ -51,4 +51,9 @@ module.exports = {
* Optional list of triggers to exclude
*/
wudTriggerExclude: 'wud.trigger.exclude',
+
+ /**
+ * Optional Lookup image (can be useful when pulling containers from a registry cache)
+ */
+ wudRegistryLookupImage: 'wud.registry.lookup.image',
};
diff --git a/docs/changelog/README.md b/docs/changelog/README.md
index fd0a6ba1..d824c64e 100644
--- a/docs/changelog/README.md
+++ b/docs/changelog/README.md
@@ -1,7 +1,13 @@
# Changelog
+<<<<<<< HEAD
## 8.1.1
- :fire: [TELEGRAM] - Fix markdown character escape
+=======
+# 6.7.0 (wip)
+- :star: [UI] - Add support for [Selfh.st](https://selfh.st/icons/) icons
+- :star: [WATCHER] - Add support for alternative lookup registry url (useful when pulling from registry cache)
+>>>>>>> ab7cf7c (:star: [WATCHER] - Add support for alternative lookup registry url (useful when pulling from registry cache))
## 8.1.0
- :star: Add 60s default jitter in docker watcher to avoid load spike on Docker Hub
diff --git a/docs/configuration/watchers/README.md b/docs/configuration/watchers/README.md
index 237b20c5..d3bd28ee 100644
--- a/docs/configuration/watchers/README.md
+++ b/docs/configuration/watchers/README.md
@@ -183,8 +183,9 @@ To fine-tune the behaviour of WUD _per container_, you can add labels on them.
|-----------------------|:--------------:|----------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------|
| `wud.display.icon` | :white_circle: | Custom display icon for the container | Valid [Material Design Icon](https://materialdesignicons.com/), [Fontawesome Icon](https://fontawesome.com/) or [Simple icon](https://simpleicons.org/) (see details below) | `mdi:docker` |
| `wud.display.name` | :white_circle: | Custom display name for the container | Valid String | Container name |
-| `wud.link.template` | :white_circle: | Browsable link associated to the container version | JS string template with vars `${container}`, `${original}`, `${transformed}`, `${major}`, `${minor}`, `${patch}`, `${prerelease}` | |
-| `wud.tag.exclude` | :white_circle: | Regex to exclude specific tags | Valid JavaScript Regex | |
+| `wud.link.template` | :white_circle: | Browsable link associated to the container version | JS string template with vars `${container}`, `${original}`, `${transformed}`, `${major}`, `${minor}`, `${patch}`, `${prerelease}` | |
+| `wud.registry.lookup.image` | :white_circle: | Alternative image to use for update lookups | Full image path (e.g., `namespace/image` or `registry.example.com/namespace/image`) | |
+| `wud.tag.exclude` | :white_circle: | Regex to exclude specific tags | Valid JavaScript Regex | |
| `wud.tag.include` | :white_circle: | Regex to include specific tags only | Valid JavaScript Regex | |
| `wud.tag.transform` | :white_circle: | Transform function to apply to the tag | `$valid_regex => $valid_string_with_placeholders` (see below) | |
| `wud.trigger.exclude` | :white_circle: | Optional list of triggers to exclude | `$trigger_1_id,$trigger_2_id:$threshold` | |
@@ -437,3 +438,30 @@ docker run -d --name my_important_service --label 'wud.trigger.include=smtp.gmai
?> Threshold `minor` means that the trigger will run only if this is a `minor` or `patch` semver change
?> Threshold `patch` means that the trigger will run only if this is a `patch` semver change
+
+### Use an alternative image for update lookups
+When using a Docker Registry cache (Harbor, Nexus, etc.), you need to specify the upstream image that WUD should check for updates.
+
+
+#### **Docker Compose**
+```yaml
+version: '3'
+
+services:
+
+ traefik:
+ image: harbor.example.com/ghcr-proxy/traefik/traefik:v3.5.3
+ labels:
+ - wud.watch=true
+ - wud.registry.lookup.image=ghcr.io/traefik/traefik
+```
+
+#### **Docker**
+```bash
+docker run -d \
+ --name traefik \
+ --label 'wud.watch=true' \
+ --label 'wud.registry.lookup.image=ghcr.io/traefik/traefik' \
+ harbor.example.com/ghcr-proxy/traefik/traefik:v3.5.3
+```
+
diff --git a/e2e/features/api-container.feature b/e2e/features/api-container.feature
index ae932f0b..2e3a7b67 100644
--- a/e2e/features/api-container.feature
+++ b/e2e/features/api-container.feature
@@ -86,6 +86,8 @@ Feature: WUD Container API Exposure
And response body should be valid json
And response body path $.link should be https://github.com/home-assistant/core/releases/tag/2021.6.1
And response body path $.result.link should be https://github.com/home-assistant/core/releases/tag/2025.7.1
+ And response body path $.result.link should be https://github.com/home-assistant/core/releases/tag/2024.10.2
+>>>>>>> ab7cf7c (:star: [WATCHER] - Add support for alternative lookup registry url (useful when pulling from registry cache))
Scenario: WUD must allow to trigger a watch on a container
Given I GET /api/containers
diff --git a/ui/src/components/ContainerImage.vue b/ui/src/components/ContainerImage.vue
index 36c5efb5..b5473e25 100644
--- a/ui/src/components/ContainerImage.vue
+++ b/ui/src/components/ContainerImage.vue
@@ -39,9 +39,14 @@
{{ registryIcon }}
- Registry
+ Registry name
{{ image.registry.name }}
+
+ Registry url
+ {{ image.registry.url }}
+ {{ image.registry.lookupImage }} (lookup)
+