Skip to content

Conversation

@Maximilian-Nesslauer
Copy link
Contributor

Improve registry lookup feature with full image path support

This builds on @manfred-martin 's original implementation from PR #454 (which was closed without merging).
His work introduced the wud.registry.lookup.url label to help users bypass Docker registry caches when checking for updates.

Closes #451


Background

Since PR #454 was created, the codebase has moved forward a few versions. This PR merges the original feature branch with version 8.1.1 to bring it up to date with the latest stable release.

However, while testing the original URL-based approach with my Harbor registry setup, I discovered a fundamental issue for my usecase: it doesn't work with registries that use project prefixes or nested paths.

The Problem

The original implementation accepted registry URLs like https://registry-1.docker.io and tried to extract the image name from them. This breaks with registries like Harbor, where images look like:

harbor.example.com/dockerhub-proxy/traefik:v3.5.3

The dockerhub-proxy/ part is a Harbor project name, not part of the actual image name.
The URL-based approach would incorrectly include it as part of the image path, causing registry matching to fail. This same problem affects other registries that use hierarchical project structures.

My Solution and Changes

Instead of accepting registry URLs and trying to parse them, accept full image paths directly. While this requires typing the full image path (which may be slightly longer than just a URL), it's more explicit and generic, works with any registry structure, and lets users specify exactly what upstream image WUD should check for updates.

What Changed

  • Renamed label from wud.registry.lookup.url to wud.registry.lookup.image
  • Now accepts full image paths (e.g., library/traefik or ghcr.io/user/image)
  • Automatically defaults to Docker Hub for short-form images without a registry
  • Fixed registry normalization to use the lookup image instead of the original
  • Updated documentation
  • Added Prometheus metric support for the lookup image field
  • Removed tests specific to URL-based parsing (no longer needed with generic image path approach)

Example Usage

services:
  traefik:
    image: harbor.example.com/dockerhub-proxy/traefik:v3.5.3
    labels:
      - wud.watch=true
      - wud.registry.lookup.image=library/traefik

This allows WUD to check registries like Docker Hub for traefik updates while the container continues pulling from the Harbor proxy cache, solving the original issue where proxy registries don't have up-to-date tag information.

Testing

  • I did test with Harbor proxy cache projects (Docker Hub, GHCR, Codeberg)
  • All 428 unit tests passing
  • Live deployment on my homelab

Breaking Changes

This changes the label name from wud.registry.lookup.url to wud.registry.lookup.image. However, since PR #454 was never merged into a release, this shouldn't affect any users that are not using the feature/#451_customizable_registry_url branch.

fmartinou and others added 2 commits October 10, 2025 23:07
This builds on Manfred Martin's <[email protected]> original implementation from PR getwud#454 (which
was closed without merging). His work introduced the `wud.registry.lookup.url`
label to help users bypass Docker registry caches when checking for updates.

This commit merges the original feature branch with version 8.1.1 to bring it up to
date with the latest stable release, ensuring compatibility with recent changes.

However, while testing the original URL-based approach with my Harbor registry
setup, I discovered a fundamental issue: it doesn't work with registries that
use project prefixes or nested paths.

The problem:
The original implementation accepted registry URLs like
"https://registry-1.docker.io" and tried to extract the image name from them.
This breaks with enterprise registries like Harbor, where images look like:
  harbor.example.com/dockerhub-proxy/traefik:v3.5.3

The "dockerhub-proxy/" part is a Harbor project name, not part of the actual
image name. The URL-based approach would incorrectly include it as part of
the image path, causing registry matching to fail. This same problem affects
other registries that use hierarchical project structures.

The solution:
Instead of accepting registry URLs and trying to parse them, accept full image
paths directly. While this requires typing the full image path (which may be
slightly longer than just a URL), it's more explicit and generic, works with any registry
structure, and lets users specify exactly what upstream image WUD should check
for updates.

What changed:
- Renamed label from `wud.registry.lookup.url` to `wud.registry.lookup.image`
- Now accepts full image paths (e.g., "library/traefik" or "ghcr.io/user/image")
- Automatically defaults to Docker Hub for short-form images without a registry
- Fixed registry normalization to use the lookup image instead of the original
- Updated documentation
- Added Prometheus metric support for the lookup image field
- Removed tests specific to URL-based parsing (no longer needed with generic image path approach)

Example usage:
  image: harbor.example.com/dockerhub-proxy/traefik:v3.5.3
  labels:
    - wud.watch=true
    - wud.registry.lookup.image=library/traefik

This allows WUD to check Docker Hub for traefik updates while the container
continues pulling from the Harbor proxy cache, solving the original issue where
proxy registries don't have up-to-date tag information.

Tested with:
- Harbor proxy cache (Docker Hub, GHCR, Codeberg)
- All 428 unit tests passing
- Live deployment on my homelab
@EdwinKM
Copy link

EdwinKM commented Oct 28, 2025

Can I download this feature as a Docker image somewhere to test it with my local Docker Registry (behind a reverse proxy)?
In the previous version, I could use image: fmartinou/whats-up-docker:feature__451_customizable_registry_url.
But this feature now seems to be from Maximilian’s repo.
I’d really like to have this feature available, since I’m currently pinned to the previously mentioned version.

@Maximilian-Nesslauer
Copy link
Contributor Author

Hi @EdwinKM ,

It seems like there are no automated workflows in this repository to build Docker images for feature branches, so you would either need to wait until

  1. an maintainer does review, merge and build the changes from this PR into a new image or you could
  2. checkout this PR and build the image yourself (i am doing that right now in my setup)

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

@Maximilian-Nesslauer

Does not seem to work. Probably a mistake on my side.
All containers with "wud.registry.lookup.url" in the compose are down.
It is commented in the started containers. But WUD does not want to boot.

Steps below:

edwin@linux-5q3o:~/TEMP/wud> git clone https://github.com/Maximilian-Nesslauer/wud.git
Cloning into 'wud'...
remote: Enumerating objects: 6754, done.
remote: Counting objects: 100% (1662/1662), done.
remote: Compressing objects: 100% (439/439), done.
remote: Total 6754 (delta 1370), reused 1276 (delta 1211), pack-reused 5092 (from 2)
Receiving objects: 100% (6754/6754), 10.40 MiB | 4.44 MiB/s, done.
Resolving deltas: 100% (4058/4058), done.


edwin@linux-5q3o:~/TEMP/wud> cd wud/
edwin@linux-5q3o:~/TEMP/wud/wud> git checkout -b feature/#451_customizable_registry_url origin/feature/#451_customizable_registry_url
branch 'feature/#451_customizable_registry_url' set up to track 'origin/feature/#451_customizable_registry_url'.
Switched to a new branch 'feature/#451_customizable_registry_url'

cd ~/TEMP/wud/wud/ui
npm install
npm run build

cd /home/edwin/TEMP/wud/wud
docker build -t registry-private.home.mydomain.com/wud_customizable_registry_url .
docker push registry-private.home.mydomain.com/wud_customizable_registry_url



wud compose changed: "image: registry-private.home.mydomain.com/wud_customizable_registry_url"


find . -name compose.yaml -exec grep -H "lookup" {} \;
./traefik/compose.yaml:      #- wud.registry.lookup.url=https://registry-1.docker.io




whatsupdocker  | 19:05:36.527  INFO whats-up-docker: WUD is starting (version = unknown)
whatsupdocker  | 19:05:36.528  INFO whats-up-docker/store: Load store from (/store/wud.json)
whatsupdocker  | 19:05:36.533  INFO whats-up-docker/store: Migrate data from version feature__451_customizable_registry_url to version unknown
whatsupdocker  | 19:05:36.534  INFO whats-up-docker/prometheus: Init Prometheus module
whatsupdocker  | 19:05:36.537 DEBUG whats-up-docker: Start container metrics interval
whatsupdocker  | /home/node/app/model/container.js:302
whatsupdocker  |         throw new Error(
whatsupdocker  |               ^
whatsupdocker  | 
whatsupdocker  | Error: Error when validating container properties ValidationError: "image.registry.lookupUrl" is not allowed
whatsupdocker  |     at validate (/home/node/app/model/container.js:302:15)
whatsupdocker  |     at /home/node/app/store/container.js:78:24
whatsupdocker  |     at Array.map (<anonymous>)
whatsupdocker  |     at Object.getContainers (/home/node/app/store/container.js:78:10)
whatsupdocker  |     at populateGauge (/home/node/app/prometheus/container.js:13:20)
whatsupdocker  |     at Object.init (/home/node/app/prometheus/container.js:87:5)
whatsupdocker  |     at Object.init (/home/node/app/prometheus/index.js:15:15)
whatsupdocker  |     at main (/home/node/app/index.js:15:16)
whatsupdocker  | 
whatsupdocker  | Node.js v23.11.1
whatsupdocker exited with code 0







docker ps
CONTAINER ID   IMAGE                   COMMAND                  CREATED          STATUS                    PORTS                                                                                                                 NAMES
58042b34494d   traefik:3.3.4           "/entrypoint.sh --lo…"   2 minutes ago    Up 2 minutes              0.0.0.0:80->80/tcp, :::80->80/tcp, 0.0.0.0:443->443/tcp, :::443->443/tcp, 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp   traefik
03c2ef55b924   louislam/dockge:1.5.0   "/usr/bin/dumb-init …"   40 minutes ago   Up 40 minutes (healthy)   5001/tcp, 0.0.0.0:31014->31014/tcp, :::31014->31014/tcp                                                               ix-share-dockge-dockge-1

@Maximilian-Nesslauer
Copy link
Contributor Author

@EdwinKM

The issue is that this PR introduces a breaking change (only a breaking change incase you have used PR #454 before) in the label name:

Old: wud.registry.lookup.url
New: wud.registry.lookup.image

You'll need to update your compose files to use the new label name.
Please see the PR description above for details on why this changed and usage examples.

Sorry for the breaking change! Since PR #454 was never merged into a release, I figured no one in production would be affected. I should probably consider just renaming everything back into "wud.registry.lookup.url" to not confuse anyone.

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

no, i was expected the breaking change.
It should start with this config (or missing the "wud.registry.lookup.image" line)?
even if i disable WUD (wud.watch=true) for traefik and WUD itself it will crash

services:
  whatsupdocker:
    #image: getwud/wud:8.0.1
    #image: fmartinou/whats-up-docker:feature__451_customizable_registry_url
    #image: registry-dockerhub.home.mydomain.com/fmartinou/whats-up-docker:feature__451_customizable_registry_url
    image: registry-private.home.mydomain.com/wud_customizable_registry_url
    pull_policy: missing
    container_name: whatsupdocker
    hostname: whatsupdocker
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /mnt/tank/container_data/whatsupdocker:/store
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    networks:
      - traefik-net
    dns_search:
      - home.arpa
    labels:
      - wud.watch=true
      - wud.registry.lookup.image=docker.io/wud
      #- wud.registry.lookup.url=https://registry-1.docker.io

      
      
services:
  traefik:
    image: traefik:3.3.4
    pull_policy: missing
    container_name: traefik
    hostname: traefik
    restart: always
    ports:
      - 80:80 # proxy
      - 443:443 # proxy
      - 8080:8080 # dashboard
    networks:
      - traefik-net
    volumes:
      - /mnt/tank/container_data/traefik:/var/traefik/certs
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    environment:
      - TZ=Europe/Amsterdam
    labels:
      - wud.watch=true
      #- wud.registry.lookup.url=https://registry-1.docker.io

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

validated even with inspect:

docker inspect traefik --format '{{json .Config.Labels}}' |grep -i lookup

only "wud.registry.lookup.image" is present.
Also note. The new property is "wud.registry.lookup.image" but the error is "image.registry.lookupUrl". (maybe the internal function name but useful for enduser. And the error is really not helpful anyway. Where did it find it?)

@Maximilian-Nesslauer
Copy link
Contributor Author

Maximilian-Nesslauer commented Oct 29, 2025

I think i might have just found the issue and am trying to fix it :)
Please give me 10min.

Your store contains containers with the old image.registry.lookupUrl field from the previous version of PR #454, but the new schema only allows lookupImage. When the app starts and tries to validate containers from the store, it fails as there is no migration logic that handled the schema change.

It slipped past testing as i did not previously have containers with the old image.registry.lookupUrl field. The tests did not cover that. Sorry for the inconvenience :)

I will push a new commit soon that just renames wud.registry.lookup.image back into wud.registry.lookup.url to avoid breaking changes while migration from the old feature branch to the new one.

Changed the label from wud.registry.lookup.image back to
wud.registry.lookup.url to maintain backward compatibility with
users already using the previous PR getwud#454 implementation.

This prevents a breaking change for existing users like Edwin who
were using the old label name.

Changes:
- app/model/container.js: Updated schema to use lookupUrl instead of lookupImage
- app/watchers/providers/docker/Docker.js: Updated all references to use lookupUrl
- app/watchers/providers/docker/label.js: Changed constant from wudRegistryLookupImage to wudRegistryLookupUrl
- ui/src/components/ContainerImage.vue: Updated UI to display lookupUrl
- docs/configuration/watchers/README.md: Updated documentation and examples
@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

i am the only one running that feature. I would not suggest to use illogical label names for this one case.

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

i moved wud.json out of the way.
I think nothing useful in that file? But configured WUD a long time ago. But i always try to use the compose to configure stuff.
Maybe add it to the exclamation mark.

It now starts, get some weird logging. But not sure if new anyway.


whatsupdocker  | 20:47:52.277  INFO whats-up-docker: WUD is starting (version = unknown)
whatsupdocker  | 20:47:52.278  INFO whats-up-docker/store: Load store from (/store/wud.json)
whatsupdocker  | 20:47:52.280  INFO whats-up-docker/store: Create Collection app
whatsupdocker  | 20:47:52.281  INFO whats-up-docker/store: Migrate data from version undefined to version unknown
whatsupdocker  | 20:47:52.281  INFO whats-up-docker/store: Create Collection containers
whatsupdocker  | 20:47:52.281  INFO whats-up-docker/prometheus: Init Prometheus module
whatsupdocker  | 20:47:52.284 DEBUG whats-up-docker: Start container metrics interval
whatsupdocker  | 20:47:52.285  INFO whats-up-docker/registry: Register all components of kind trigger for provider mqtt
whatsupdocker  | 20:47:52.339  INFO whats-up-docker/trigger.mqtt.mosquitto: Register with configuration {"url":"mqtt://homeassistant-en.home.arpa:1883","topic":"homeassistant/wud","clientid":"whatsupdocker_san-en","user":"mobiles","password":"j*****************e","hass":{"enabled":false,"prefix":"homeassistant","discovery":false},"tls":{"rejectunauthorized":true},"auto":true,"threshold":"all","mode":"simple","once":true,"simpletitle":"New ${container.updateKind.kind} found for container ${container.name}","simplebody":"Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? \"\\n\" + container.result.link : \"\"}","batchtitle":"${containers.length} updates available"}
whatsupdocker  | 20:47:52.366  INFO whats-up-docker/registry: Register all components of kind trigger for provider gotify
whatsupdocker  | 20:47:52.375  INFO whats-up-docker/trigger.gotify.local: Register with configuration {"url":"http://gotify.san-en.home.arpa","token":"A*************2","priority":0,"auto":true,"threshold":"all","mode":"simple","once":true,"simpletitle":"New ${container.updateKind.kind} found for container ${container.name}","simplebody":"Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? \"\\n\" + container.result.link : \"\"}","batchtitle":"${containers.length} updates available"}
whatsupdocker  | 20:47:52.375  INFO whats-up-docker/registry: Register all components of kind trigger for provider ntfy
whatsupdocker  | 20:47:52.486  INFO whats-up-docker/trigger.ntfy.local: Register with configuration {"topic":"whatsupdocker","priority":2,"url":"http://ntfy.san-en.home.arpa","auto":true,"threshold":"all","mode":"simple","once":true,"simpletitle":"New ${container.updateKind.kind} found for container ${container.name}","simplebody":"Container ${container.name} running with ${container.updateKind.kind} ${container.updateKind.localValue} can be updated to ${container.updateKind.kind} ${container.updateKind.remoteValue}${container.result && container.result.link ? \"\\n\" + container.result.link : \"\"}","batchtitle":"${containers.length} updates available"}
whatsupdocker  | 20:47:52.486  INFO whats-up-docker/trigger.gotify.local: Registering for auto execution
whatsupdocker  | 20:47:52.486  INFO whats-up-docker/trigger.ntfy.local: Registering for auto execution
whatsupdocker  | 20:47:52.497  INFO whats-up-docker/trigger.mqtt.mosquitto: Registering for auto execution
whatsupdocker  | 20:47:52.498  INFO whats-up-docker/registry: Register all components of kind registry for provider ecr
whatsupdocker  | 20:47:52.544  INFO whats-up-docker/registry.ecr.public: Register with configuration {}
whatsupdocker  | 20:47:52.544  INFO whats-up-docker/registry: Register all components of kind registry for provider gcr
whatsupdocker  | 20:47:52.544  INFO whats-up-docker/registry.gcr.public: Register with configuration {}
whatsupdocker  | 20:47:52.544  INFO whats-up-docker/registry: Register all components of kind registry for provider ghcr
whatsupdocker  | 20:47:52.545  INFO whats-up-docker/registry.ghcr.public: Register with configuration {}
whatsupdocker  | 20:47:52.545  INFO whats-up-docker/registry: Register all components of kind registry for provider hub
whatsupdocker  | 20:47:52.546  INFO whats-up-docker/registry.hub.public: Register with configuration {}
whatsupdocker  | 20:47:52.546  INFO whats-up-docker/registry: Register all components of kind registry for provider quay
whatsupdocker  | 20:47:52.547  INFO whats-up-docker/registry.quay.public: Register with configuration {}
whatsupdocker  | 20:47:52.715  INFO whats-up-docker/watcher.docker.local: Register with configuration {"watchbydefault":false,"watchevents":true,"cron":"0 1 * * *","watchall":true,"socket":"/var/run/docker.sock","port":2375,"jitter":60000,"watchatstart":true}
whatsupdocker  | 20:47:52.716  INFO whats-up-docker/watcher.docker.local: Cron scheduled (0 1 * * *)
whatsupdocker  | 20:47:52.741  INFO whats-up-docker/registry: No authentication configured => Allow anonymous access
whatsupdocker  | 20:47:52.742  INFO whats-up-docker/authentication.anonymous.anonymous: Register with configuration {}
whatsupdocker  | 20:47:52.742 DEBUG whats-up-docker/api: API/UI enabled => Start Http listener on port 3000
whatsupdocker  | 20:47:52.746  WARN whats-up-docker: Anonymous authentication is enabled; please make sure that the app is not exposed to unsecure networks
whatsupdocker  | 20:47:52.749  INFO whats-up-docker/api: Server listening on port 3000 (HTTP)
whatsupdocker  | 20:47:53.741  INFO whats-up-docker/watcher.docker.local: Cron started (0 1 * * *)
whatsupdocker  | 20:47:53.762  INFO whats-up-docker/watcher.docker.local: Listening to docker events
whatsupdocker  | 20:47:53.817  INFO whats-up-docker: [DEBUG] Available registries: ecr.public, gcr.public, ghcr.public, hub.public, quay.public
whatsupdocker  | 20:47:53.817  INFO whats-up-docker: [DEBUG] Matching against registry URL: registry-dockerhub.home.mydomain.com
whatsupdocker  | 20:47:53.819  WARN whats-up-docker: local_syncthing - No Registry Provider found
whatsupdocker  | 20:47:53.832  INFO whats-up-docker: [DEBUG] Available registries: ecr.public, gcr.public, ghcr.public, hub.public, quay.public
whatsupdocker  | 20:47:53.832  INFO whats-up-docker: [DEBUG] Matching against registry URL: undefined
whatsupdocker  | 20:47:53.832  INFO whats-up-docker: [DEBUG] Found registry provider: hub.public
whatsupdocker  | 20:47:53.841  INFO whats-up-docker: [DEBUG] Available registries: ecr.public, gcr.public, ghcr.public, hub.public, quay.public
whatsupdocker  | 20:47:53.841  INFO whats-up-docker: [DEBUG] Matching against registry URL: registry-dockerhub.home.mydomain.com
whatsupdocker  | 20:47:53.842  WARN whats-up-docker: local_share-gitea - No Registry Provider found
whatsupdocker  | 20:47:53.850  INFO whats-up-docker: [DEBUG] Available registries: ecr.public, gcr.public, ghcr.public, hub.public, quay.public
whatsupdocker  | 20:47:53.850  INFO whats-up-docker: [DEBUG] Matching against registry URL: registry-dockerhub.home.mydomain.com
whatsupdocker  | 20:47:53.850  WARN whats-up-docker: local_lms-en-media - No Registry Provider found
whatsupdocker  | 20:47:53.856  INFO whats-up-docker: [DEBUG] Available registries: ecr.public, gcr.public, ghcr.public, hub.public, quay.public
whatsupdocker  | 20:47:53.856  INFO whats-up-docker: [DEBUG] Matching against registry URL: registry-dockerhub.home.mydomain.com
whatsupdocker  | 20:47:53.856  WARN whats-up-docker: local_gitea - No Registry Provider found
whatsupdocker  | 20:47:53.859 DEBUG whats-up-docker/watcher.docker.local: Start watching (container=local_syncthing)
whatsupdocker  | 20:47:53.860 DEBUG whats-up-docker/watcher.docker.local: Start watching (container=local_share-gitea)
whatsupdocker  | 20:47:53.860 DEBUG whats-up-docker/watcher.docker.local: Start watching (container=local_gitea)
whatsupdocker  | 20:47:53.860 DEBUG whats-up-docker/watcher.docker.local: Start watching (container=local_lms-en-media)
whatsupdocker  | 20:47:53.860 DEBUG whats-up-docker/watcher.docker.local: Start watching (container=local_registry-private)
whatsupdocker  | 20:47:53.861 DEBUG whats-up-docker/registry.hub.public: Get library/registry tags
whatsupdocker  | 20:47:53.868  WARN whats-up-docker/watcher.docker.local: Error when processing (Unsupported Registry unknown) (container=local_syncthing)
whatsupdocker  | 20:47:53.868 DEBUG whats-up-docker/watcher.docker.local: Unsupported Registry unknown (container=local_syncthing)
whatsupdocker  |     Error: Unsupported Registry unknown
whatsupdocker  |         at getRegistry (/home/node/app/watchers/providers/docker/Docker.js:159:15)
whatsupdocker  |         at Docker.findNewVersion (/home/node/app/watchers/providers/docker/Docker.js:606:34)
whatsupdocker  |         at Docker.watchContainer (/home/node/app/watchers/providers/docker/Docker.js:520:53)
whatsupdocker  |         at /home/node/app/watchers/providers/docker/Docker.js:489:52
whatsupdocker  |         at Array.map (<anonymous>)
whatsupdocker  |         at Docker.watch (/home/node/app/watchers/providers/docker/Docker.js:489:28)
whatsupdocker  |         at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
whatsupdocker  |         at async Docker.watchFromCron (/home/node/app/watchers/providers/docker/Docker.js:449:34)
whatsupdocker  | 20:47:53.869 DEBUG whats-up-docker/watcher.docker.local: Container watched for the first time (container=local_syncthing)
whatsupdocker  | 20:47:53.870 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Publish container result to homeassistant/wud/local/syncthing
whatsupdocker  | 20:47:53.874  WARN whats-up-docker/watcher.docker.local: Error when processing (Unsupported Registry unknown) (container=local_share-gitea)
whatsupdocker  | 20:47:53.874 DEBUG whats-up-docker/watcher.docker.local: Unsupported Registry unknown (container=local_share-gitea)
whatsupdocker  |     Error: Unsupported Registry unknown
whatsupdocker  |         at getRegistry (/home/node/app/watchers/providers/docker/Docker.js:159:15)
whatsupdocker  |         at Docker.findNewVersion (/home/node/app/watchers/providers/docker/Docker.js:606:34)
whatsupdocker  |         at Docker.watchContainer (/home/node/app/watchers/providers/docker/Docker.js:520:53)
whatsupdocker  |         at /home/node/app/watchers/providers/docker/Docker.js:489:52
whatsupdocker  |         at Array.map (<anonymous>)
whatsupdocker  |         at Docker.watch (/home/node/app/watchers/providers/docker/Docker.js:489:28)
whatsupdocker  |         at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
whatsupdocker  |         at async Docker.watchFromCron (/home/node/app/watchers/providers/docker/Docker.js:449:34)
whatsupdocker  | 20:47:53.875 DEBUG whats-up-docker/watcher.docker.local: Container watched for the first time (container=local_share-gitea)
whatsupdocker  | 20:47:53.875 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Publish container result to homeassistant/wud/local/share-gitea
whatsupdocker  | 20:47:53.877  WARN whats-up-docker/watcher.docker.local: Error when processing (Unsupported Registry unknown) (container=local_gitea)
whatsupdocker  | 20:47:53.877 DEBUG whats-up-docker/watcher.docker.local: Unsupported Registry unknown (container=local_gitea)
whatsupdocker  |     Error: Unsupported Registry unknown
whatsupdocker  |         at getRegistry (/home/node/app/watchers/providers/docker/Docker.js:159:15)
whatsupdocker  |         at Docker.findNewVersion (/home/node/app/watchers/providers/docker/Docker.js:606:34)
whatsupdocker  |         at Docker.watchContainer (/home/node/app/watchers/providers/docker/Docker.js:520:53)
whatsupdocker  |         at /home/node/app/watchers/providers/docker/Docker.js:489:52
whatsupdocker  |         at Array.map (<anonymous>)
whatsupdocker  |         at Docker.watch (/home/node/app/watchers/providers/docker/Docker.js:489:28)
whatsupdocker  |         at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
whatsupdocker  |         at async Docker.watchFromCron (/home/node/app/watchers/providers/docker/Docker.js:449:34)
whatsupdocker  | 20:47:53.877 DEBUG whats-up-docker/watcher.docker.local: Container watched for the first time (container=local_gitea)
whatsupdocker  | 20:47:53.877 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Publish container result to homeassistant/wud/local/gitea
whatsupdocker  | 20:47:53.879  WARN whats-up-docker/watcher.docker.local: Error when processing (Unsupported Registry unknown) (container=local_lms-en-media)
whatsupdocker  | 20:47:53.879 DEBUG whats-up-docker/watcher.docker.local: Unsupported Registry unknown (container=local_lms-en-media)
whatsupdocker  |     Error: Unsupported Registry unknown
whatsupdocker  |         at getRegistry (/home/node/app/watchers/providers/docker/Docker.js:159:15)
whatsupdocker  |         at Docker.findNewVersion (/home/node/app/watchers/providers/docker/Docker.js:606:34)
whatsupdocker  |         at Docker.watchContainer (/home/node/app/watchers/providers/docker/Docker.js:520:53)
whatsupdocker  |         at /home/node/app/watchers/providers/docker/Docker.js:489:52
whatsupdocker  |         at Array.map (<anonymous>)
whatsupdocker  |         at Docker.watch (/home/node/app/watchers/providers/docker/Docker.js:489:28)
whatsupdocker  |         at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
whatsupdocker  |         at async Docker.watchFromCron (/home/node/app/watchers/providers/docker/Docker.js:449:34)
whatsupdocker  | 20:47:53.879 DEBUG whats-up-docker/watcher.docker.local: Container watched for the first time (container=local_lms-en-media)
whatsupdocker  | 20:47:53.879 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Publish container result to homeassistant/wud/local/lms-en-media
whatsupdocker  | 20:47:54.665 DEBUG whats-up-docker/watcher.docker.local: Container watched for the first time (container=local_registry-private)
whatsupdocker  | 20:47:54.667 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Publish container result to homeassistant/wud/local/registry-private
whatsupdocker  | 20:47:54.671 DEBUG whats-up-docker/trigger.gotify.local: Run (container=local_registry-private)
whatsupdocker  | 20:47:54.742 DEBUG whats-up-docker/trigger.ntfy.local: Run (container=local_registry-private)
whatsupdocker  | 20:47:54.743 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Run (container=local_registry-private)
whatsupdocker  | 20:47:54.743 DEBUG whats-up-docker/trigger.mqtt.mosquitto: Publish container result to homeassistant/wud/local/registry-private
whatsupdocker  | 20:47:54.745  INFO whats-up-docker/watcher.docker.local: Cron finished (5 containers watched, 4 errors, 1 available updates)
whatsupdocker  | 20:47:54.763  WARN whats-up-docker/trigger.ntfy.local: Error (308 - "Permanent Redirect") (container=local_registry-private)
whatsupdocker  | 20:47:54.763 DEBUG whats-up-docker/trigger.ntfy.local: 308 - "Permanent Redirect" (container=local_registry-private)
whatsupdocker  |     StatusCodeError: 308 - "Permanent Redirect"
whatsupdocker  |         at new StatusCodeError (/home/node/app/node_modules/request-promise-native/node_modules/request-promise-core/lib/errors.js:32:15)
whatsupdocker  |         at plumbing.callback (/home/node/app/node_modules/request-promise-native/node_modules/request-promise-core/lib/plumbing.js:104:33)
whatsupdocker  |         at Request.RP$callback [as _callback] (/home/node/app/node_modules/request-promise-native/node_modules/request-promise-core/lib/plumbing.js:46:31)
whatsupdocker  |         at self.callback (/home/node/app/node_modules/request/request.js:185:22)
whatsupdocker  |         at Request.emit (node:events:507:28)
whatsupdocker  |         at Request.emit (node:domain:489:12)
whatsupdocker  |         at Request.<anonymous> (/home/node/app/node_modules/request/request.js:1154:10)
whatsupdocker  |         at Request.emit (node:events:507:28)
whatsupdocker  |         at Request.emit (node:domain:489:12)
whatsupdocker  |         at IncomingMessage.<anonymous> (/home/node/app/node_modules/request/request.js:1076:12)
whatsupdocker  |         at Object.onceWrapper (node:events:621:28)
whatsupdocker  |         at IncomingMessage.emit (node:events:519:35)
whatsupdocker  |         at IncomingMessage.emit (node:domain:489:12)
whatsupdocker  |         at endReadableNT (node:internal/streams/readable:1696:12)
whatsupdocker  |         at process.processTicksAndRejections (node:internal/process/task_queues:90:21)
whatsupdocker  | 20:47:54.769  WARN whats-up-docker/trigger.gotify.local: Error (fetch failed) (container=local_registry-private)
whatsupdocker  | 20:47:54.770 DEBUG whats-up-docker/trigger.gotify.local: fetch failed (container=local_registry-private)
whatsupdocker  |     TypeError: fetch failed
whatsupdocker  |         at node:internal/deps/undici/undici:13510:13
whatsupdocker  |         at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
whatsupdocker  |         at async Gotify.handleContainerReport (/home/node/app/triggers/providers/Trigger.js:138:21)

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

please revert to "image". It is the logical name

@Maximilian-Nesslauer
Copy link
Contributor Author

@EdwinKM hmm you are probably right.

I just already pushed an commit that would fix any issues that users experience while migrating from PR #454 (It is an issue only specific to that scenario).

I believe that you have a good point and i therefore reverted my latest commit back to :

wud.registry.lookup.image is more logical than wud.registry.lookup.url because:

  1. The value is an IMAGE reference, not a URL:
    • Example: ghcr.io/traefik/traefik - this is an image path
    • Example: namespace/image - this is an image reference
    • A URL would be something like https://registry-1.docker.io
  2. Semantically accurate: We are telling WUD to lookup a different IMAGE for updates, not a different URL

If i had more time today i could maybe implement automatic migration in the WUD store so that there are no issues in that specific scenario, but i need to study for an exam so here is the solution in the meantime:

  1. Stop WUD
  2. Delete the wud.json store file
  3. Start WUD with the new image

@Maximilian-Nesslauer
Copy link
Contributor Author

oops you were faster than i could write my comment :)

@Maximilian-Nesslauer
Copy link
Contributor Author

Your ""No Registry Provider found" errors" in the logs seem to be fine as they should just be telling you that you did not add the wud.registry.lookup.image label to tell WUD where to check for updates yet and WUD is still looking at your local registry cache.

The "DEBUG whats-up-docker/watcher.docker.local: Unsupported Registry unknown" logs belong to that too. I should probably remove those before the PR is merged since they're just for debugging.

@Maximilian-Nesslauer
Copy link
Contributor Author

Please also keep in mind that the PR #454 you were using is quite old. This PR merges the original feature branch with version 8.1.1 to bring it up to date with the latest stable release.

@Maximilian-Nesslauer
Copy link
Contributor Author

It now starts, get some weird logging.

concerning the other logs:

The "Unsupported Registry unknown" errors for syncthing, share-gitea, gitea, and lms-en-media are happening because these containers are pulled from your local registry cache and WUD doesn't know where to check for updates so this is exactly what we can solve :) .

You just need to add the wud.registry.lookup.image label to tell WUD the upstream image.

@Maximilian-Nesslauer
Copy link
Contributor Author

@EdwinKM sry for the debugging inconvenience :)
I did not have that specific migration scenario in mind.

Does it seem to work now after just letting WUD recreate a new wud.json store file?

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

@EdwinKM sry for the debugging inconvenience :) I did not have that specific migration scenario in mind.

Does it seem to work now after just letting WUD recreate a new wud.json store file?

i think so, thanks for all your work! I am toying a bit with WUD again. Did not touch it for a long time. Back to your studies! Will add my results in the next days...

@EdwinKM
Copy link

EdwinKM commented Oct 29, 2025

Most containers converter. Docker images working fine. 1 ghcr.io image validated.
lscr.io is not working, but i assume is this bug

services:
  sabnzbd:
    image: registry-linuxserver.home.mydomain.com/linuxserver/sabnzbd:4.4.1
    pull_policy: missing
    container_name: sabnzbd
    hostname: sabnzbd
    volumes:
      - /mnt/tank/container_data/sabnzbd/host:/host
      - /mnt/tank/container_data/sabnzbd/config:/config
      - /etc/timezone:/etc/timezone:ro
      - /etc/localtime:/etc/localtime:ro
    networks:
      - traefik-net
    labels:
      - wud.watch=true
      - wud.registry.lookup.image=lscr.io/linuxserver/sabnzbd

@EdwinKM
Copy link

EdwinKM commented Oct 30, 2025

I think it is ready to merge.

User @Stitch10925 hoped for a easier solution. But i do not mind, for WUD we usually already need to add lines to the compose file anyway.

@Maximilian-Nesslauer
Copy link
Contributor Author

@EdwinKM @Stitch10925 That's true, but I couldn't think of a better solution yet 😅
I just added "configure WUD labels" to my usual todo list like configure traefik labels, authentik etc. anyway when setting up new docker compose files :)

I do not know what still needs to be done until this can be merged. I guess that we just need to wait until @fmartinou reviews the PR?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature Request] Replace parts of image path to bypass docker registry cache

3 participants