A lightweight, fast web interface for browsing and managing Docker Registry and OCI-compatible registries.
Docker image: quiq/registry-ui
- Browse repositories, tags, and nested repository trees at any depth
- View full image details: layers, config, and command history
- Support for Docker and OCI image formats, including multi-platform image indexes
- Event listener to capture registry notifications, stored in SQLite or MySQL
- Built-in CLI for tag retention: purge tags older than X days while keeping at least Y tags
- Auto-discovery of authentication methods (basic auth, token service, keychain, etc.)
- Repository list and tags are cached and refreshed in the background
Note: The UI does not handle TLS or authentication. Place it behind a reverse proxy such as nginx, oauth2_proxy, or similar.
Start a Docker registry on your host (if you don't already have one):
docker run -d --network host --name registry registry
Push any image to 127.0.0.1:5000/owner/name:
docker tag alpine:edge 127.0.0.1:5000/owner/name
docker push 127.0.0.1:5000/owner/name
Run Registry UI and open http://127.0.0.1:8000 in your browser:
docker run --rm --network host \
-e REGISTRY_HOSTNAME=127.0.0.1:5000 \
-e REGISTRY_INSECURE=true \
--name registry-ui quiq/registry-ui
Configuration is stored in config.yml with self-descriptive options. Any option can be
overridden via environment variables using SECTION_KEY_NAME syntax,
e.g. LISTEN_ADDR, PERFORMANCE_TAGS_ASYNC_REFRESH_INTERVAL, REGISTRY_HOSTNAME.
To pass a full config file:
docker run -d -p 8000:8000 -v /local/config.yml:/opt/config.yml:ro quiq/registry-ui
To use a custom root CA certificate:
-v /local/rootcacerts.crt:/etc/ssl/certs/ca-certificates.crt:ro
To persist the SQLite database for event data:
-v /local/data:/opt/data
Ensure /local/data is owned by nobody (uid 65534 on Alpine).
The container supports --read-only mode. If you use the event listener, mount the data folder
in read-write mode as shown above so the SQLite database remains writable.
To set a custom timezone:
-e TZ=America/Los_Angeles
To receive notification events, configure your Docker Registry:
notifications:
endpoints:
- name: registry-ui
url: http://registry-ui.local:8000/event-receiver
headers:
Authorization: [Bearer abcdefghijklmnopqrstuvwxyz1234567890]
timeout: 1s
threshold: 5
backoff: 10s
ignoredmediatypes:
- application/octet-stream
Adjust the URL and token as appropriate.
If you run the UI under a non-default base path (e.g. /ui), use /ui/event-receiver as the endpoint path.
To use MySQL, update event_database_driver and event_database_location in the config file.
Create the database referenced in the DSN beforehand. Required privileges: SELECT, INSERT, DELETE.
To create the table manually (avoids granting CREATE):
CREATE TABLE events (
id INTEGER PRIMARY KEY AUTO_INCREMENT,
action CHAR(4) NULL,
repository VARCHAR(100) NULL,
tag VARCHAR(100) NULL,
ip VARCHAR(45) NULL,
user VARCHAR(50) NULL,
created DATETIME NULL
);
First, enable tag deletion in your Docker Registry config:
storage:
delete:
enabled: true
Then schedule a cron job to purge old tags (assumes the container is already running):
10 3 * * * root docker exec -t registry-ui /opt/registry-ui -purge-tags
Preview what would be purged with dry-run mode:
docker exec -t registry-ui /opt/registry-ui -purge-tags -dry-run
Note: Purging tags only removes tag references. To reclaim disk space, run garbage collection on your registry afterwards.
Repository list:
Tag list:
Image Index info:
Image info:



