diff --git a/README.md b/README.md index 941254f..3ca0b91 100644 --- a/README.md +++ b/README.md @@ -1,76 +1,69 @@ -## Registry UI +# Registry UI [![Go Report Card](https://goreportcard.com/badge/github.com/quiq/registry-ui)](https://goreportcard.com/report/github.com/quiq/registry-ui) -### Overview +A lightweight, fast web interface for browsing and managing Docker Registry and OCI-compatible registries. -* Web UI for Docker Registry or similar alternatives -* Fast, simple and small package -* Browse catalog of repositories and tags -* Show an arbitrary level of repository tree -* Support Docker and OCI image formats -* Support image and image index manifests (multi-platform images) -* Display full information about image index and links to the underlying sub-images -* Display full information about image, its layers and config file (command history) -* Event listener for notification events coming from Registry -* Store events in Sqlite or MySQL database -* CLI option to maintain the tag retention: purge tags older than X days keeping at least Y tags etc. -* Automatically discover an authentication method: basic auth, token service, keychain etc. -* The list of repositories and tag counts are cached and refreshed in background +Docker image: [quiq/registry-ui](https://hub.docker.com/r/quiq/registry-ui/tags/) -No TLS or authentication is implemented on the UI instance itself. -Assuming you will put it behind nginx, oauth2_proxy or similar. +### Features -Docker images [quiq/registry-ui](https://hub.docker.com/r/quiq/registry-ui/tags/) +- 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 tag counts 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. ### Quick start -Run a Docker registry in your host (if you don't already had one): +Start a Docker registry on your host (if you don't already have one): docker run -d --network host \ --name registry registry:2 -Run registry UI directly connected to it: +Then run Registry UI: docker run -d --network host \ -e REGISTRY_HOSTNAME=127.0.0.1:5000 \ -e REGISTRY_INSECURE=true \ --name registry-ui quiq/registry-ui -Push any Docker image to 127.0.0.1:5000/owner/name and go into http://127.0.0.1:8000 with -your web browser. +Push any image to `127.0.0.1:5000/owner/name` and open http://127.0.0.1:8000 in your browser. ### Configuration -The configuration is stored in `config.yml` and the options are self-descriptive. +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`. -You can override any config option via environment variables using SECTION_KEY_NAME syntax, -e.g. `LISTEN_ADDR`, `PERFORMANCE_TAGS_COUNT_REFRESH_INTERVAL`, `REGISTRY_HOSTNAME` etc. - -Passing the full config file through: +To pass a full config file: docker run -d -p 8000:8000 -v /local/config.yml:/opt/config.yml:ro quiq/registry-ui -To run with your own root CA certificate, add to the command: +To use a custom root CA certificate: -v /local/rootcacerts.crt:/etc/ssl/certs/ca-certificates.crt:ro -To preserve sqlite db file with event data, add to the command: +To persist the SQLite database for event data: -v /local/data:/opt/data -Ensure /local/data is owner by nobody (alpine user id is 65534). +Ensure `/local/data` is owned by `nobody` (uid 65534 on Alpine). -You can also run the container with `--read-only` option, however when using using event listener functionality -you need to ensure the sqlite db can be written, i.e. mount a folder as listed above (rw mode). +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 run with a custom TZ: +To set a custom timezone: -e TZ=America/Los_Angeles -## Configure event listener on Docker Registry +### Event listener -To receive events you need to configure Registry as follow: +To receive notification events, configure your Docker Registry: notifications: endpoints: @@ -84,15 +77,15 @@ To receive events you need to configure Registry as follow: ignoredmediatypes: - application/octet-stream -Adjust url and token as appropriate. -If you are running UI with non-default base path, e.g. /ui, the URL path for above will be `/ui/event-receiver` etc. +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. -## Using MySQL instead of sqlite3 for event listener +### Using MySQL instead of SQLite -To use MySQL as a storage you need to change `event_database_driver` and `event_database_location` -settings in the config file. It is expected you create a database mentioned in the location DSN. -Minimal privileges are `SELECT`, `INSERT`, `DELETE`. -You can create a table manually if you don't want to grant `CREATE` permission: +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, @@ -104,23 +97,24 @@ You can create a table manually if you don't want to grant `CREATE` permission: created DATETIME NULL ); -### Schedule a cron task for purging tags +### Tag purging -To delete tags you need to enable the corresponding option in Docker Registry config. For example: +First, enable tag deletion in your Docker Registry config: storage: delete: enabled: true -The following example shows how to run a cron task to purge tags older than X days but also keep -at least Y tags no matter how old. Assuming container has been already running. +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 -You can try to run in dry-run mode first to see what is going to be purged: +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. + ### Screenshots Repository list: