mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2026-02-17 21:19:51 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8bd1f31c9c | ||
|
|
7777ff28df | ||
|
|
4fee7b44d3 | ||
|
|
7716f8b44a | ||
|
|
1321d9b573 | ||
|
|
d7a19734ce | ||
|
|
32d0df1af9 | ||
|
|
5c1cb93a1c | ||
|
|
9d97c30914 | ||
|
|
cec469ab67 | ||
|
|
34200c1114 | ||
|
|
67c6cb1bee | ||
|
|
021cddfef7 | ||
|
|
c01b440ff2 | ||
|
|
63c310181b | ||
|
|
ab37bcfcef | ||
|
|
8e539be6ba | ||
|
|
5b0ffc8eab | ||
|
|
188cb80463 | ||
|
|
f1bff47468 | ||
|
|
df508cdef0 | ||
|
|
eadaaadadd |
3
.gitignore
vendored
3
.gitignore
vendored
@@ -2,4 +2,5 @@
|
||||
node_modules
|
||||
package-lock.json
|
||||
registry-data
|
||||
.idea
|
||||
.idea
|
||||
_site
|
||||
73
README.md
73
README.md
@@ -1,37 +1,51 @@
|
||||
---
|
||||
title: Project Page
|
||||
---
|
||||
|
||||
# Docker Registry UI
|
||||
|
||||

|
||||

|
||||
|
||||
## Overview
|
||||
|
||||
This project aims to provide a user interface for your private docker registry v2.
|
||||
There is no default registry on this UI, you should add your own with the UI.
|
||||
This project aims to provide a simple and complete user interface for your private docker registry.
|
||||
You have the choice between two versions, the **standard interface** and the **static interface**.
|
||||
|
||||
In the **standard interface**, there is no default registry, you need to add your own within the UI.
|
||||
You can manage more than one registry server.
|
||||
All registries will be stored in the [local storage](https://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage) of your browser.
|
||||
All registries will be stored in the [local storage](https://en.wikipedia.org/wiki/Web_storage#Local_and_session_storage) of your browser. No configuration is needed when you launch the UI.
|
||||
|
||||
In the **static interface**, it will connect to a single registry and will not change. The configuration is done at the start of the interface, when you use the docker images whose tags contain the `static` keyword.
|
||||
|
||||
This web user interface uses [Riot](https://github.com/Riot/riot) the react-like user interface micro-library and [riot-mui](https://github.com/kysonic/riot-mui) components.
|
||||
|
||||
## [GitHub Page](https://joxit.github.io/docker-registry-ui) and [Live Demo](https://joxit.github.io/docker-registry-ui/demo/)
|
||||
## [Project Page](https://joxit.dev/docker-registry-ui), [Live Demo](https://joxit.dev/docker-registry-ui/demo/) [Examples](https://github.com/Joxit/docker-registry-ui/tree/master/examples)
|
||||
|
||||

|
||||
|
||||
## Features
|
||||
|
||||
- List all your repositories/images.
|
||||
- List all tags for a repository/image
|
||||
- Sort the tag list
|
||||
- One interface for many registries
|
||||
- Use a secured docker registry
|
||||
- Share your docker registry with query parameter `url` (e.g. `https://joxit.github.io/docker-registry-ui/demo?url=https://registry.example.com`)
|
||||
- Use `joxit/docker-registry-ui:static` as reverse proxy to your docker registry (This will avoid CORS).
|
||||
- Display image size (see #30)
|
||||
- Add Title when using REGISTRY_URL (see #28)
|
||||
- Alpine and Debian based images with supports for arm32v7 and arm64v8
|
||||
- Copy `docker pull` command to clipbloard
|
||||
- Show sha256 for specific tag (hover image tag)
|
||||
- Display image creation date (see #49)
|
||||
- Display image history (see #58)
|
||||
- Display image/tag count
|
||||
- Image aggregation (see #56)
|
||||
- Customise docker pull command on static registry UI (see #71)
|
||||
- List all tags for a image.
|
||||
- Sort the tag list with number compatibility (see [#46](https://github.com/Joxit/docker-registry-ui/pull/46)).
|
||||
- Use a secured docker registry.
|
||||
- Display image size (see [#30](https://github.com/Joxit/docker-registry-ui/issues/30)).
|
||||
- Multi arch supports, Alpine and Debian based images with supports for arm32v7 and arm64v8.
|
||||
- Copy `docker pull` command to clipboard (see [#42](https://github.com/Joxit/docker-registry-ui/issues/42)).
|
||||
- Show sha256 for specific tag (hover image tag).
|
||||
- Display image creation date (see [#49](https://github.com/Joxit/docker-registry-ui/issues/49))
|
||||
- Display image history (see [#58](https://github.com/Joxit/docker-registry-ui/pull/58) & [#61](https://github.com/Joxit/docker-registry-ui/pull/61)).
|
||||
- Image aggregation (see [#56](https://github.com/Joxit/docker-registry-ui/issues/56)).
|
||||
- Display image/tag count (see [#56 issue comment](https://github.com/Joxit/docker-registry-ui/issues/56#issuecomment-449246524)).
|
||||
- Select multiple tags to delete (see [#29](https://github.com/Joxit/docker-registry-ui/issues/29)).
|
||||
- Select all tags with ALT + Click to delete (see [#80](https://github.com/Joxit/docker-registry-ui/issues/80)).
|
||||
- One interface for many registries **standard interface**.
|
||||
- Share your docker registry with query parameter `url` (e.g. `https://joxit.dev/docker-registry-ui/demo?url=https://registry.example.com`) **standard interface**.
|
||||
- Use `joxit/docker-registry-ui:static` as reverse proxy (with `REGISTRY_URL` environment variable) to your docker registry (This will avoid CORS) **static interface**.
|
||||
- Add Title when using `REGISTRY_URL` (see [#28](https://github.com/Joxit/docker-registry-ui/issues/28)) **static interface**.
|
||||
- Customise docker pull command on static registry UI (see [#71](https://github.com/Joxit/docker-registry-ui/issues/71)) **static interface**.
|
||||
- Add custom header via environment variable and file (see [#89](https://github.com/Joxit/docker-registry-ui/pull/89)) **static interface**
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -102,7 +116,7 @@ To run the docker and see the website on your 80 port, try this:
|
||||
docker run -d -p 80:80 joxit/docker-registry-ui
|
||||
```
|
||||
|
||||
#### Run the static docker
|
||||
#### Run the static interface
|
||||
|
||||
Some env options are available for use this interface for only one server.
|
||||
|
||||
@@ -119,7 +133,7 @@ docker run -d -p 80:80 -e URL=http://127.0.0.1:5000 -e DELETE_IMAGES=true joxit/
|
||||
```
|
||||
|
||||
Example with `REGISTRY_URL`, this will add a proxy to your registry.
|
||||
Your registry will be accessible here : `http://127.0.0.1/v2`, this will avoid CORS errors (see #25).
|
||||
Your registry will be accessible here : `http://127.0.0.1/v2`, this will avoid CORS errors (see [#25](https://github.com/Joxit/docker-registry-ui/issues/25#issuecomment-360522487)).
|
||||
Be careful, `joxit/docker-registry-ui` and `registry:2` will communicate, both containers should be in the same network or use your private IP.
|
||||
|
||||
```sh
|
||||
@@ -136,14 +150,14 @@ Your server should be configured to accept CORS.
|
||||
|
||||
If your docker registry does not need credentials, you will need to send this HEADER:
|
||||
|
||||
Access-Control-Allow-Origin: '*'
|
||||
Access-Control-Allow-Origin: ['*']
|
||||
|
||||
If your docker registry need credentials, you will need to send these HEADERS:
|
||||
|
||||
```yml
|
||||
http:
|
||||
headers:
|
||||
Access-Control-Allow-Origin: '<your docker-registry-ui url>'
|
||||
Access-Control-Allow-Origin: ['<your docker-registry-ui url>']
|
||||
Access-Control-Allow-Credentials: true
|
||||
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS'] # Optional
|
||||
```
|
||||
@@ -198,3 +212,14 @@ auth:
|
||||
realm: basic-realm
|
||||
path: /etc/docker/registry/htpasswd
|
||||
```
|
||||
|
||||
## All examples
|
||||
|
||||
- [Use docker-registry-ui as a proxy (use REGISTRY_URL)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/ui-as-proxy)
|
||||
- [Use docker-registry-ui as standalone (use URL)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/ui-as-standalone)
|
||||
- [Use docker-registry-ui with traefik](https://github.com/Joxit/docker-registry-ui/tree/master/examples/traefik)
|
||||
- [Use docker-registry-ui with docker registry and Amazon s3](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-75) ([#75](https://github.com/Joxit/docker-registry-ui/issues/88))
|
||||
- [FIX revproxy to registry does not work when published under non-root url](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-73) ([#73](https://github.com/Joxit/docker-registry-ui/issues/73))
|
||||
- [Use docker-registry-ui with HTTPS](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-20) ([#20](https://github.com/Joxit/docker-registry-ui/issues/20))
|
||||
- [Unable to push image when docker-registry-ui is used as a proxy on non 80 port](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-88) ([#88](https://github.com/Joxit/docker-registry-ui/issues/88))
|
||||
- [Add custom headers bases on environment variable and/or file when the ui is used as proxy](https://github.com/Joxit/docker-registry-ui/tree/master/examples/proxy-headers) ([#89](https://github.com/Joxit/docker-registry-ui/pull/89))
|
||||
14
_config.yml
14
_config.yml
@@ -1,3 +1,13 @@
|
||||
title: Docker Registry v2 User Interface
|
||||
title: Docker Registry User Interface
|
||||
description: The simplest and most complete UI for your private registry!
|
||||
url: https://joxit.dev/docker-registry-ui
|
||||
google_analytics: UA-99119327-1
|
||||
theme: jekyll-theme-cayman
|
||||
theme: jekyll-theme-cayman
|
||||
author: Jones Magloire
|
||||
twitter:
|
||||
username: Joxit
|
||||
defaults:
|
||||
- scope:
|
||||
path: ""
|
||||
values:
|
||||
image: /screenshot.png
|
||||
@@ -1,5 +1,5 @@
|
||||
#!/bin/sh
|
||||
$@
|
||||
|
||||
sed -i "s,\${URL},${URL}," scripts/docker-registry-ui.js
|
||||
sed -i "s,\${REGISTRY_TITLE},${REGISTRY_TITLE}," scripts/docker-registry-ui.js
|
||||
sed -i "s,\${PULL_URL},${PULL_URL}," scripts/docker-registry-ui.js
|
||||
@@ -8,13 +8,31 @@ if [ -z "${DELETE_IMAGES}" ] || [ "${DELETE_IMAGES}" = false ] ; then
|
||||
sed -i -r "s/(isImageRemoveActivated[:=])[^,;]*/\1false/" scripts/docker-registry-ui.js
|
||||
fi
|
||||
|
||||
get_nginx_proxy_headers() {
|
||||
(
|
||||
env &&
|
||||
if [ -f "/etc/nginx/.env" ]; then
|
||||
cat /etc/nginx/.env
|
||||
# Force new line
|
||||
echo ""
|
||||
fi
|
||||
) | while read e; do
|
||||
if [ -n "$(echo $e | grep -o '^NGINX_PROXY_HEADER_')" ]; then
|
||||
key=$(echo ${e%%=*} | sed 's/^NGINX_PROXY_HEADER_//' | sed 's/_/-/g')
|
||||
value=${e#*=}
|
||||
echo -n "proxy_set_header ${key} \"${value}\"; "
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
if [ -n "${REGISTRY_URL}" ] ; then
|
||||
sed -i "s,\${REGISTRY_URL},${REGISTRY_URL}," /etc/nginx/conf.d/default.conf
|
||||
sed -i "s^\${NGINX_PROXY_HEADERS}^$(get_nginx_proxy_headers)^" /etc/nginx/conf.d/default.conf
|
||||
sed -i "s,#!,," /etc/nginx/conf.d/default.conf
|
||||
fi
|
||||
|
||||
if [ -z "$@" ]; then
|
||||
nginx -g "daemon off;"
|
||||
exec nginx -g "daemon off;"
|
||||
else
|
||||
$@
|
||||
exec $@
|
||||
fi
|
||||
|
||||
@@ -22,7 +22,17 @@
|
||||
<link rel="stylesheet" href="../dist/vendor.css">
|
||||
<link rel="stylesheet" href="../dist/style.css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css">
|
||||
<title>Docker Registry UI</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta property="og:locale" content="en_US" />
|
||||
<meta name="description" content="This is the live demo for Docker Registry User Interface. Try it now! Sources : https://github.com/Joxit/docker-registry-ui" />
|
||||
<meta property="og:description" content="This is the live demo for Docker Registry User Interface. Try it now! Sources : https://github.com/Joxit/docker-registry-ui" />
|
||||
<link rel="canonical" href="https://joxit.dev/docker-registry-ui/demo/" />
|
||||
<meta property="og:url" content="https://joxit.dev/docker-registry-ui/demo/" />
|
||||
<meta property="og:site_name" content="Live Demo | Docker Registry User Interface" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@Joxit" />
|
||||
<meta name="twitter:creator" content="@Jones Magloire" />
|
||||
<title>Live Demo | Docker Registry User Interface</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
2
dist/index.html
vendored
2
dist/index.html
vendored
@@ -13,4 +13,4 @@
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--><!DOCTYPE html><html><head><meta charset="UTF-8"><link rel="stylesheet" href="vendor.css"><link rel="stylesheet" href="style.css"><link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css"><title>Docker Registry UI</title></head><body><app></app><script src="scripts/vendor.js"></script><script src="scripts/docker-registry-ui.js"></script></body></html>
|
||||
--><!DOCTYPE html><html><head><meta charset="UTF-8"><link rel="stylesheet" href="vendor.css"><link rel="stylesheet" href="style.css"><link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css"><meta name="viewport" content="width=device-width,initial-scale=1"><meta property="og:site_name" content="Docker Registry UI"><meta name="twitter:card" content="summary"><meta name="twitter:site" content="@Joxit"><meta name="twitter:creator" content="@Jones Magloire"><title>Docker Registry UI</title></head><body><app></app><script src="scripts/vendor.js"></script><script src="scripts/docker-registry-ui.js"></script></body></html>
|
||||
2
dist/scripts/docker-registry-ui-static.js
vendored
2
dist/scripts/docker-registry-ui-static.js
vendored
File diff suppressed because one or more lines are too long
2
dist/scripts/docker-registry-ui.js
vendored
2
dist/scripts/docker-registry-ui.js
vendored
File diff suppressed because one or more lines are too long
2
dist/style.css
vendored
2
dist/style.css
vendored
File diff suppressed because one or more lines are too long
10
examples/README.md
Normal file
10
examples/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## Examples
|
||||
|
||||
- [Use docker-registry-ui as a proxy (use REGISTRY_URL)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/ui-as-proxy)
|
||||
- [Use docker-registry-ui as standalone (use URL)](https://github.com/Joxit/docker-registry-ui/tree/master/examples/ui-as-standalone)
|
||||
- [Use docker-registry-ui with traefik](https://github.com/Joxit/docker-registry-ui/tree/master/examples/traefik)
|
||||
- [Use docker-registry-ui with docker registry and Amazon s3](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-75) ([#75](https://github.com/Joxit/docker-registry-ui/issues/88))
|
||||
- [FIX revproxy to registry does not work when published under non-root url](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-73) ([#73](https://github.com/Joxit/docker-registry-ui/issues/73))
|
||||
- [Use docker-registry-ui with HTTPS](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-20) ([#20](https://github.com/Joxit/docker-registry-ui/issues/20))
|
||||
- [Unable to push image when docker-registry-ui is used as a proxy on non 80 port](https://github.com/Joxit/docker-registry-ui/tree/master/examples/issue-88) ([#88](https://github.com/Joxit/docker-registry-ui/issues/88))
|
||||
- [Add custom headers bases on environment variable and/or file when the ui is used as proxy](https://github.com/Joxit/docker-registry-ui/tree/master/examples/proxy-headers) ([#89](https://github.com/Joxit/docker-registry-ui/pull/89))
|
||||
22
examples/helm/docker-registry-ui/.helmignore
Normal file
22
examples/helm/docker-registry-ui/.helmignore
Normal file
@@ -0,0 +1,22 @@
|
||||
# Patterns to ignore when building packages.
|
||||
# This supports shell glob matching, relative path matching, and
|
||||
# negation (prefixed with !). Only one pattern per line.
|
||||
.DS_Store
|
||||
# Common VCS dirs
|
||||
.git/
|
||||
.gitignore
|
||||
.bzr/
|
||||
.bzrignore
|
||||
.hg/
|
||||
.hgignore
|
||||
.svn/
|
||||
# Common backup files
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*~
|
||||
# Various IDEs
|
||||
.project
|
||||
.idea/
|
||||
*.tmproj
|
||||
.vscode/
|
||||
11
examples/helm/docker-registry-ui/Chart.yaml
Normal file
11
examples/helm/docker-registry-ui/Chart.yaml
Normal file
@@ -0,0 +1,11 @@
|
||||
apiVersion: v1
|
||||
appVersion: "1.2.1"
|
||||
description: The simplest and most complete UI for your private registry
|
||||
name: docker-registry-ui
|
||||
home: https://github.com/Joxit/docker-registry-ui
|
||||
keywords:
|
||||
- docker
|
||||
- registry
|
||||
sources:
|
||||
- https://github.com/Joxit/docker-registry-ui
|
||||
version: 0.1.0
|
||||
97
examples/helm/docker-registry-ui/README.md
Normal file
97
examples/helm/docker-registry-ui/README.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# docker-registry-ui
|
||||
|
||||
[docker-registry-ui](https://joxit.dev/docker-registry-ui/) is the simplest and most complete UI for your private registry!
|
||||
|
||||
|
||||
## TL;DR;
|
||||
|
||||
```bash
|
||||
$ helm install .
|
||||
```
|
||||
|
||||
## Introduction
|
||||
|
||||
This chart bootstraps a [docker-registry-ui](https://joxit.dev/docker-registry-ui/) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
|
||||
|
||||
It also may deploy the [docker registry](https://docs.docker.com/registry/) if you havent have one already.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Kubernetes 1.9+ with Beta APIs enabled
|
||||
- PV provisioner support in the underlying infrastructure
|
||||
|
||||
## Installing the Chart
|
||||
|
||||
To install the chart with the release name `my-release`:
|
||||
|
||||
```bash
|
||||
$ helm update --install my-release .
|
||||
```
|
||||
|
||||
The command deploys docker-registry-ui on the Kubernetes cluster in the default configuration. The [configuration](#configuration) section lists the parameters that can be configured during installation.
|
||||
|
||||
> **Tip**: List all releases using `helm list`
|
||||
|
||||
## Uninstalling the Chart
|
||||
|
||||
To uninstall/delete the `my-release` deployment:
|
||||
|
||||
```bash
|
||||
$ helm delete my-release
|
||||
```
|
||||
|
||||
The command removes all the Kubernetes components associated with the chart and deletes the release.
|
||||
|
||||
## Configuration
|
||||
|
||||
The following table lists the configurable parameters of the Redmine chart and their default values.
|
||||
|
||||
| Parameter | Description | Default |
|
||||
| --------------------------------- | ---------------------------------------- | ------------------------------------------------------- |
|
||||
| `ui.title` | Title of the managed repository | `Docker registry UI` |
|
||||
| `ui.delete_images` | Allow to delete image from the front-end | `false` |
|
||||
| `ui.proxy` | The UI service act as a proxy of the registry | `true` |
|
||||
| `ui.replicaCount` | Number of replicas to start | `1` |
|
||||
| `ui.image.registry` | registry to pull the docker-registry-ui image from | `docker.io` |
|
||||
| `ui.image.repository` | docker-registry-ui image name | `joxit/docker-registry-ui` |
|
||||
| `ui.image.tag` | docker-registry-ui image tag (change to latest to have multi registry support) | `static` |
|
||||
| `ui.image.pullPolicy` | docker-registry-ui image pull policy | `Always` |
|
||||
| `ui.probe.liveness` | Ask kubernetes to check the service port for liveness | `true` |
|
||||
| `ui.probe.readyness ` | Ask kubernetes to check the service port for readyness | `true` |
|
||||
| `ui.service.type` | Desired service type | `ClusterIP` |
|
||||
| `ui.service.port` | Service exposed port | `80` |
|
||||
| `ui.ingress.enabled` | Create an ingress for docker-regstry-ui | `false` |
|
||||
| `registry.external` | Use an already available registry | `false` |
|
||||
| `registry.url` | URL of the existing registry | `http://localhost:5000` |
|
||||
| `registry.replicaCount` | Number of replicas to start | `1` |
|
||||
| `registry.image.registry` | registry to pull the docker-registry image from | `docker.io` |
|
||||
| `registry.image.repository` | docker-registry-ui image name | `registry` |
|
||||
| `registry.image.tag` | docker-registry-ui image tag | `2.6.2` |
|
||||
| `registry.image.pullPolicy` | docker-registry-ui image pull policy | `Always` |
|
||||
| `registry.probe.liveness` | Ask kubernetes to check the service port for liveness | `true` |
|
||||
| `registry.probe.readyness ` | Ask kubernetes to check the service port for readyness | `true` |
|
||||
| `registry.persistence.enabled` | Enable persistence using PVC for the registry | `false` |
|
||||
| `registry.persistence.storageClass` | PVC Storage Class | `-` |
|
||||
| `registry.persistence.size` | PVC Storage Request size | `1Gi` |
|
||||
| `registry.service.type` | Desired service type | `ClusterIP` |
|
||||
| `registry.service.port` | Service exposed port | `5000` |
|
||||
| `registry.ingress.enabled` | Create an ingress for the regstry | `false` |
|
||||
|
||||
|
||||
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
|
||||
|
||||
```bash
|
||||
$ helm upgrade --install my-release \
|
||||
--set registry.external=true \
|
||||
--set registry.url=http://registry.example.com:5000 \
|
||||
.
|
||||
```
|
||||
|
||||
Alternatively, a YAML file that specifies the values for the above parameters can be provided while installing the chart. For example,
|
||||
|
||||
```bash
|
||||
$ helm upgrade --install my-release -f values.yaml .
|
||||
```
|
||||
|
||||
> **Tip**: You can use the default [values.yaml](values.yaml)
|
||||
|
||||
147
examples/helm/docker-registry-ui/templates/_helpers.tpl
Normal file
147
examples/helm/docker-registry-ui/templates/_helpers.tpl
Normal file
@@ -0,0 +1,147 @@
|
||||
{{/* vim: set filetype=mustache: */}}
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "docker-registry-ui.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "docker-registry-ui.fullname" -}}
|
||||
{{- if .Values.ui.fullnameOverride -}}
|
||||
{{- .Values.ui.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- printf "%s-ui" .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-ui-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry.fullname" -}}
|
||||
{{- if .Values.registry.fullnameOverride -}}
|
||||
{{- .Values.registry.fullnameOverride | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride -}}
|
||||
{{- if contains $name .Release.Name -}}
|
||||
{{- printf "%s-registry" .Release.Name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s-registry-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "docker-registry-ui.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end -}}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "docker-registry-ui.labels" -}}
|
||||
app: registry-ui
|
||||
chart: {{ include "docker-registry-ui.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry-ui.matchLabels" -}}
|
||||
app: registry-ui
|
||||
release: {{ .Release.Name }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry.labels" -}}
|
||||
app: registry
|
||||
chart: {{ include "docker-registry-ui.chart" . }}
|
||||
release: {{ .Release.Name }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry.matchLabels" -}}
|
||||
app: registry
|
||||
release: {{ .Release.Name }}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry-ui.probes" -}}
|
||||
{{- if and .Values.ui.probe.liveness (eq .Values.ui.probe.liveness true) -}}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
{{- end -}}
|
||||
{{- if and .Values.ui.probe.readiness (eq .Values.ui.probe.readiness true) }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry.probes" -}}
|
||||
{{- if and .Values.registry.probe.liveness (eq .Values.registry.probe.liveness true) -}}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /v2/
|
||||
port: registry
|
||||
{{- end -}}
|
||||
{{- if and .Values.registry.probe.readiness (eq .Values.registry.probe.readiness true) }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /v2/
|
||||
port: registry
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry-ui.url-name" -}}
|
||||
{{- if eq .Values.ui.proxy true -}}
|
||||
REGISTRY_URL
|
||||
{{- else -}}
|
||||
URL
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry-ui.url-value" -}}
|
||||
{{- if eq .Values.registry.external true -}}
|
||||
{{ .Values.registry.url }}
|
||||
{{- else -}}
|
||||
{{- $fullName := include "docker-registry.fullname" . -}}
|
||||
{{ printf "http://%s.%s:%.0f" $fullName .Release.Namespace .Values.registry.service.port }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
|
||||
{{- define "docker-registry-ui.pull" -}}
|
||||
{{- if eq .Values.registry.external true -}}
|
||||
{{ .Values.registry.url }}
|
||||
{{- else -}}
|
||||
{{- if eq .Values.ui.proxy true -}}
|
||||
{{- if eq .Values.ui.ingress.enabled true -}}
|
||||
{{- $host := index .Values.ui.ingress.hosts 0 -}}
|
||||
{{ $host.host }}
|
||||
{{- else -}}
|
||||
{{- $fullName := include "docker-registry-ui.fullname" . -}}
|
||||
{{ printf "%s.%s:%.0f" $fullName .Release.Namespace .Values.ui.service.port }}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- if eq .Values.registry.ingress.enabled true -}}
|
||||
{{- $host := index .Values.registry.ingress.hosts 0 -}}
|
||||
{{ $host.host }}
|
||||
{{- else -}}
|
||||
{{- $fullName := include "docker-registry.fullname" . -}}
|
||||
{{ printf "%s.%s:%.0f" $fullName .Release.Namespace .Values.registry.service.port }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,31 @@
|
||||
{{- if eq .Values.registry.external false -}}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "docker-registry.fullname" . }}
|
||||
labels:
|
||||
{{ include "docker-registry.labels" . | indent 4 }}
|
||||
data:
|
||||
config.yml: |-
|
||||
version: 0.1
|
||||
log:
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
delete:
|
||||
enabled: true
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
http:
|
||||
addr: :5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
Access-Control-Allow-Origin: ['*']
|
||||
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
|
||||
Access-Control-Allow-Headers: ['Authorization']
|
||||
Access-Control-Max-Age: [1728000]
|
||||
Access-Control-Allow-Credentials: [true]
|
||||
Access-Control-Expose-Headers: ['Docker-Content-Digest']
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,62 @@
|
||||
{{- if eq .Values.registry.external false -}}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "docker-registry.fullname" . }}
|
||||
labels:
|
||||
{{ include "docker-registry.labels" . | indent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.registry.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{ include "docker-registry.matchLabels" . | indent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{ include "docker-registry.matchLabels" . | indent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
defaultMode: 420
|
||||
name: {{ include "docker-registry.fullname" . }}
|
||||
- name: data
|
||||
{{- if .Values.registry.persistence.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "docker-registry.fullname" . }}
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: registry
|
||||
image: "{{ .Values.registry.image.registry }}/{{ .Values.registry.image.repository }}:{{ .Values.registry.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.registry.image.pullPolicy }}
|
||||
ports:
|
||||
- name: registry
|
||||
containerPort: 5000
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: "/var/lib/registry"
|
||||
name: "data"
|
||||
- mountPath: "/etc/docker/registry"
|
||||
name: "config"
|
||||
{{ include "docker-registry.probes" . | indent 10 }}
|
||||
resources:
|
||||
{{- toYaml .Values.registry.resources | nindent 12 }}
|
||||
{{- with .Values.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
34
examples/helm/docker-registry-ui/templates/reg-ingress.yaml
Normal file
34
examples/helm/docker-registry-ui/templates/reg-ingress.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
{{- if and (eq .Values.registry.external false) (and (eq .Values.ui.proxy false) .Values.registry.ingress.enabled) -}}
|
||||
{{- $fullName := include "docker-registry.fullname" . -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{ include "docker-registry.labels" . | indent 4 }}
|
||||
{{- with .Values.registry.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.registry.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.registry.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.registry.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: registry
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
23
examples/helm/docker-registry-ui/templates/reg-pvc.yaml
Normal file
23
examples/helm/docker-registry-ui/templates/reg-pvc.yaml
Normal file
@@ -0,0 +1,23 @@
|
||||
{{- if and (eq .Values.registry.external false) .Values.registry.persistence.enabled -}}
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
labels:
|
||||
{{ include "docker-registry.labels" . | indent 4 }}
|
||||
name: {{ include "docker-registry.fullname" . }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- range .Values.registry.persistence.accessModes }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.registry.persistence.size }}
|
||||
{{- if .Values.registry.persistence.storageClass }}
|
||||
{{- if (eq "-" .Values.registry.persistence.storageClass) }}
|
||||
storageClassName: ""
|
||||
{{- else }}
|
||||
storageClassName: {{ .Values.registry.persistence.storageClass | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end -}}
|
||||
17
examples/helm/docker-registry-ui/templates/reg-service.yaml
Normal file
17
examples/helm/docker-registry-ui/templates/reg-service.yaml
Normal file
@@ -0,0 +1,17 @@
|
||||
{{- if eq .Values.registry.external false -}}
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "docker-registry.fullname" . }}
|
||||
labels:
|
||||
{{ include "docker-registry.labels" . | indent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.registry.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.registry.service.port }}
|
||||
targetPort: registry
|
||||
protocol: TCP
|
||||
name: registry
|
||||
selector:
|
||||
{{ include "docker-registry.matchLabels" . | indent 6 }}
|
||||
{{- end -}}
|
||||
@@ -0,0 +1,52 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "docker-registry-ui.fullname" . }}
|
||||
labels:
|
||||
{{ include "docker-registry-ui.labels" . | indent 4 }}
|
||||
spec:
|
||||
replicas: {{ .Values.ui.replicaCount }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{ include "docker-registry-ui.matchLabels" . | indent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{ include "docker-registry-ui.matchLabels" . | indent 8 }}
|
||||
spec:
|
||||
{{- with .Values.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: registry-ui
|
||||
image: "{{ .Values.ui.image.registry }}/{{ .Values.ui.image.repository }}:{{ .Values.ui.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.ui.image.pullPolicy }}
|
||||
env:
|
||||
- name: REGISTRY_TITLE
|
||||
value: {{ .Values.ui.title| quote }}
|
||||
- name: DELETE_IMAGES
|
||||
value: {{ .Values.ui.delete_images| quote }}
|
||||
- name: {{ include "docker-registry-ui.url-name" . }}
|
||||
value: {{ include "docker-registry-ui.url-value" . | quote }}
|
||||
- name: PULL_URL
|
||||
value: {{ include "docker-registry-ui.pull" . | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
{{ include "docker-registry-ui.probes" . | indent 10 }}
|
||||
resources:
|
||||
{{- toYaml .Values.ui.resources | nindent 12 }}
|
||||
{{- with .Values.ui.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ui.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.ui.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
34
examples/helm/docker-registry-ui/templates/ui-ingress.yaml
Normal file
34
examples/helm/docker-registry-ui/templates/ui-ingress.yaml
Normal file
@@ -0,0 +1,34 @@
|
||||
{{- if .Values.ui.ingress.enabled -}}
|
||||
{{- $fullName := include "docker-registry-ui.fullname" . -}}
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}
|
||||
labels:
|
||||
{{ include "docker-registry-ui.labels" . | indent 4 }}
|
||||
{{- with .Values.ui.ingress.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- if .Values.ui.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.ui.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.ui.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
backend:
|
||||
serviceName: {{ $fullName }}
|
||||
servicePort: http
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
15
examples/helm/docker-registry-ui/templates/ui-service.yaml
Normal file
15
examples/helm/docker-registry-ui/templates/ui-service.yaml
Normal file
@@ -0,0 +1,15 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "docker-registry-ui.fullname" . }}
|
||||
labels:
|
||||
{{ include "docker-registry-ui.labels" . | indent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.ui.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.ui.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{ include "docker-registry-ui.matchLabels" . | indent 6 }}
|
||||
129
examples/helm/docker-registry-ui/values.yaml
Normal file
129
examples/helm/docker-registry-ui/values.yaml
Normal file
@@ -0,0 +1,129 @@
|
||||
# Default values for docker-registry-ui.
|
||||
# This is a YAML-formatted file.
|
||||
# Declare variables to be passed into your templates.
|
||||
|
||||
|
||||
ui:
|
||||
# title of the registry
|
||||
title: "Docker registry UI"
|
||||
# allow delete of images
|
||||
delete_images: false
|
||||
# UI behave as a proxy of the registry
|
||||
proxy: true
|
||||
|
||||
replicaCount: 1
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: joxit/docker-registry-ui
|
||||
tag: static
|
||||
pullPolicy: Always
|
||||
probe:
|
||||
liveness: true
|
||||
readiness: true
|
||||
|
||||
resources: {}
|
||||
# If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
fullnameOverride: ""
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: docker-registry-ui.local
|
||||
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
|
||||
registry:
|
||||
external: false
|
||||
# URL of the registry (requiered. Note: this wont work as localhost is inside the container. Only used if the registry is external)
|
||||
url: http://localhost:5000
|
||||
|
||||
replicaCount: 1
|
||||
# Image definition for the registry (Only used if the registry is not external)
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: registry
|
||||
tag: 2.6.2
|
||||
pullPolicy: Always
|
||||
probe:
|
||||
liveness: true
|
||||
readiness: true
|
||||
resources: {}
|
||||
# If you do want to specify resources, uncomment the following
|
||||
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
|
||||
# limits:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
# requests:
|
||||
# cpu: 100m
|
||||
# memory: 128Mi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
fullnameOverride: ""
|
||||
|
||||
|
||||
persistence:
|
||||
## If true, use a Persistent Volume Claim, If false, use emptyDir
|
||||
##
|
||||
enabled: false
|
||||
## Persistent Volume Storage Class
|
||||
## If defined, storageClassName: <storageClass>
|
||||
## If set to "-", storageClassName: "", which disables dynamic provisioning
|
||||
## If undefined (the default) or set to null, no storageClassName spec is
|
||||
## set, choosing the default provisioner. (gp2 on AWS, standard on
|
||||
## GKE, AWS & OpenStack)
|
||||
##
|
||||
# storageClass: "-"
|
||||
## Persistent Volume Claim annotations
|
||||
##
|
||||
annotations:
|
||||
## Persistent Volume Access Mode
|
||||
##
|
||||
accessModes:
|
||||
# This have to be ReadWriteMany if replicaCount>1
|
||||
- ReadWriteOnce
|
||||
## Persistent Volume size
|
||||
##
|
||||
size: 1Gi
|
||||
##
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 5000
|
||||
|
||||
ingress:
|
||||
enabled: false
|
||||
annotations: {}
|
||||
# kubernetes.io/ingress.class: nginx
|
||||
# kubernetes.io/tls-acme: "true"
|
||||
hosts:
|
||||
- host: docker-registry.local
|
||||
|
||||
tls: []
|
||||
# - secretName: chart-example-tls
|
||||
# hosts:
|
||||
# - chart-example.local
|
||||
|
||||
imagePullSecrets: []
|
||||
nameOverride: ""
|
||||
11
examples/issue-20/README.md
Normal file
11
examples/issue-20/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# Example for issue #20 (HTTPS supports)
|
||||
|
||||
This example will override the original nginx conf with one supporting HTTPS. You will need to rewrite all the project configuration (replaces `proxy_pass` with our value).
|
||||
|
||||
Generating a self signed certificate:
|
||||
|
||||
```
|
||||
openssl req -newkey rsa:2048 -nodes -keyout nginx/privkey.pem -x509 -days 3650 -out nginx/fullchain.pem
|
||||
```
|
||||
|
||||
The UI will be available here : https://localhost
|
||||
27
examples/issue-20/docker-compose.yml
Normal file
27
examples/issue-20/docker-compose.yml
Normal file
@@ -0,0 +1,27 @@
|
||||
version: '2.0'
|
||||
services:
|
||||
registry:
|
||||
image: registry:2.6.2
|
||||
volumes:
|
||||
- ./registry-data:/var/lib/registry
|
||||
networks:
|
||||
- registry-ui-net
|
||||
|
||||
ui:
|
||||
image: joxit/docker-registry-ui:static
|
||||
environment:
|
||||
- REGISTRY_TITLE=My Private Docker Registry
|
||||
volumes:
|
||||
- ./nginx/nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
- ./nginx/fullchain.pem:/etc/nginx/certs/fullchain.pem
|
||||
- ./nginx/privkey.pem:/etc/nginx/certs/privkey.pem
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
depends_on:
|
||||
- registry
|
||||
networks:
|
||||
- registry-ui-net
|
||||
|
||||
networks:
|
||||
registry-ui-net:
|
||||
21
examples/issue-20/nginx/fullchain.pem
Normal file
21
examples/issue-20/nginx/fullchain.pem
Normal file
@@ -0,0 +1,21 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDYDCCAkigAwIBAgIJAKNtVPbuycx+MA0GCSqGSIb3DQEBCwUAMEUxCzAJBgNV
|
||||
BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRlcm5ldCBX
|
||||
aWRnaXRzIFB0eSBMdGQwHhcNMTkwNDE2MDk1NzEzWhcNMjkwNDEzMDk1NzEzWjBF
|
||||
MQswCQYDVQQGEwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50
|
||||
ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
||||
CgKCAQEAuykmuGBPiNDWzxmqK7BQgJqDLWbAsf4769sI2gSMR0C6qd6WV6JJ+Rf+
|
||||
y1auT2fA38cvJUjdPBEQCTxpE3Ce3e9nXYTITzze6OUCwewbdR/Cm+dHyR+M2YNP
|
||||
SQrZI6p4NE1TwCHc0LVWfblAaWiylFPeWlFCVSg5hqKAkRh9PEcWBdN5vim3/8sC
|
||||
16YmXWCERGPdFKYBN52ERJ+9h51ktMdns0LJVn+DLVSNWsiH76IMulHU64d9nZoL
|
||||
kVhxohiOeP2ZuV7E+9RYDlaKObohclPz3RoOXUbr3zjjna+dqxI6mxCw5qms26RL
|
||||
eBcQQA/EoqaAv+y+jCKqbCCcEgy27QIDAQABo1MwUTAdBgNVHQ4EFgQUDKyOzsPn
|
||||
Tc6ZTTdnt8U59/j+3l8wHwYDVR0jBBgwFoAUDKyOzsPnTc6ZTTdnt8U59/j+3l8w
|
||||
DwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQsFAAOCAQEAmqHfSjO58FoJWJUM
|
||||
2i0rcql0Y24XjZ92RdBQGLkvAhi+QxWBXNKibvpen2miv3fAeYmiFtIHQCuOCqCj
|
||||
SSdQwb91D5WR9s21PILEWsOd1H0v4ZVHX2Z5Qv5f6Hk1DiTG/sZmzUqog74TtCpG
|
||||
4m56/JYd4Mkk9raiWT9RKVTVnSHjM8h2zIMio14Nil4zO67G68jp1K0C1AM9npsf
|
||||
cvQ2+2XAOEcQ7e3nCF4ppA3HdnCm8qbr8DM12KTs+nkncps/7u+3C5vv5TxI+BEz
|
||||
b5Cs+HbLwPAphYp0CSK+sXiCUMA//mUAcMeYKq2/V4wufJlZEpBxogdttW7J4KJm
|
||||
Num0pw==
|
||||
-----END CERTIFICATE-----
|
||||
24
examples/issue-20/nginx/nginx.conf
Normal file
24
examples/issue-20/nginx/nginx.conf
Normal file
@@ -0,0 +1,24 @@
|
||||
server {
|
||||
listen 443 ssl;
|
||||
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
|
||||
ssl_ciphers HIGH:!aNULL:!MD5;
|
||||
ssl_certificate /etc/nginx/certs/fullchain.pem;
|
||||
ssl_certificate_key /etc/nginx/certs/privkey.pem;
|
||||
root /usr/share/nginx/html;
|
||||
|
||||
location /v2 {
|
||||
# Do not allow connections from docker 1.5 and earlier
|
||||
# docker pre-1.6.0 did not properly set the user agent on ping, catch "Go *" user agents
|
||||
if ($http_user_agent ~ "^(docker\/1\.(3|4|5(.[0-9]-dev))|Go ).*$" ) {
|
||||
return 404;
|
||||
}
|
||||
proxy_pass http://registry:5000;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
location / {
|
||||
return 301 https://$host$request_uri;
|
||||
}
|
||||
}
|
||||
28
examples/issue-20/nginx/privkey.pem
Normal file
28
examples/issue-20/nginx/privkey.pem
Normal file
@@ -0,0 +1,28 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC7KSa4YE+I0NbP
|
||||
GaorsFCAmoMtZsCx/jvr2wjaBIxHQLqp3pZXokn5F/7LVq5PZ8Dfxy8lSN08ERAJ
|
||||
PGkTcJ7d72ddhMhPPN7o5QLB7Bt1H8Kb50fJH4zZg09JCtkjqng0TVPAIdzQtVZ9
|
||||
uUBpaLKUU95aUUJVKDmGooCRGH08RxYF03m+Kbf/ywLXpiZdYIREY90UpgE3nYRE
|
||||
n72HnWS0x2ezQslWf4MtVI1ayIfvogy6UdTrh32dmguRWHGiGI54/Zm5XsT71FgO
|
||||
Voo5uiFyU/PdGg5dRuvfOOOdr52rEjqbELDmqazbpEt4FxBAD8SipoC/7L6MIqps
|
||||
IJwSDLbtAgMBAAECggEBAK7E+KFHXj22NkDiCGQPmrzcjA4DW4FalH3j5Vog0RVg
|
||||
Pm6NqfpfU5BFdepPISqJCjRs/XtllSGYFU9ql/xNOCyqd+1+JsbHYqg74d1QKzut
|
||||
0r5etEv9KDudQJZGiQmjD+hXJRPPCzHhg8iXCqzj1Y5o2sOgCb8XdtBgQoo7Qgbc
|
||||
CG+3tytGPo33dotiFBUknrQRexTwgSWYXI89lI6fRSJlc8NyK7zp+mGbSopqGWHm
|
||||
X6V8AI+XNuliIhTvOxGhw0maNEnds39SYHCYfLATjp9x6XVVp5mG7BJLkifC8Cob
|
||||
IYQGfBwmEYbOTiNJ6oEgRZOZFPsLbqsPfPgTpHvIwUECgYEA7WfYek3DWkC7Ex3r
|
||||
7hcZjBa8JMxPhgSMho/5F8zHGAf8MdEmXPYKi9tvhLeMJQwzzlN4RtX9zg0FJ5eL
|
||||
tSgGHT/aRc2/9ZAvuG7gypNZlaAd+/SloYfKsGJQxFqLTfm288qyrRoOtBjhRMCI
|
||||
lRmw5uYVV775cK741+lyD5xj/DkCgYEAydHb8mIt/IvCloVGzP8z4veIarEecYk3
|
||||
UPw/wneZFZwGegGTsCwxox1uWVcO5CoNLhRo7622kZ6Mhsd83ySj8eQWpR1qoeMJ
|
||||
8ti9c2FniZdtUwdFgu7GPgJq3DWTVQ0c0MTnyk/UbsfD/AKG0YK9T2sReteaPOUg
|
||||
nohVutYZuFUCgYEAorXau7BSZKgaz3ZhfjQc0VO/rWTOWCcD/THt4i76gXDvm2Ei
|
||||
bvI+ti42V3rJNZcQZqf0tm/x3Og1kTYfjZCZ6DAcNF1Y5D/nRPvRW2X0L0WnZ0j8
|
||||
wCHmfE9V1c3MziuJBbv2DAfg7fRjaJCgy7fo88fb9uCv61gwuyKHh0WDjZkCgYB3
|
||||
R89lLF3dm4TAjbjQxCyYgpBf7pr9o4nMFaphd2pE+Vhil7gAMb6Ml4J2zxuAAtKT
|
||||
X4C917/FxR1tM048XF2BQ7uWjxJM5/EjVLJ0FSeqjJMStYOB5TnJwIgD6q5PYFad
|
||||
lSMh0ZjOeMb+lUe1YD4fSDqmjfMc9pcW26E/sfa1mQKBgQDMRKH/R+yw6Nemu837
|
||||
mwNVTiKtQoWS8jl8Gwox6o3cgrV/6szQaQz8oF9x829jFehYEMGYMX/8zPToyBCU
|
||||
gRod6bcMmdLB8EQd7VI5L9/CeoZQmpVVZ1STNjUqscE/Gb98nCPNXTkVeAgtE1WS
|
||||
AVhAAc+34wOxlAcjcXweBK69kg==
|
||||
-----END PRIVATE KEY-----
|
||||
31
examples/issue-73/docker-compose.yml
Normal file
31
examples/issue-73/docker-compose.yml
Normal file
@@ -0,0 +1,31 @@
|
||||
version: '2.0'
|
||||
services:
|
||||
registry:
|
||||
image: registry:2.6.2
|
||||
volumes:
|
||||
- ./registry-data:/var/lib/registry
|
||||
networks:
|
||||
- registry-ui-net
|
||||
|
||||
ui:
|
||||
image: joxit/docker-registry-ui:static
|
||||
environment:
|
||||
- REGISTRY_TITLE=My Private Docker Registry
|
||||
- REGISTRY_URL=http://registry:5000
|
||||
depends_on:
|
||||
- registry
|
||||
networks:
|
||||
- registry-ui-net
|
||||
|
||||
proxy:
|
||||
image: nginx:alpine
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/conf.d/default.conf
|
||||
ports:
|
||||
- 80:80
|
||||
depends_on:
|
||||
- ui
|
||||
networks:
|
||||
- registry-ui-net
|
||||
networks:
|
||||
registry-ui-net:
|
||||
35
examples/issue-73/nginx.conf
Normal file
35
examples/issue-73/nginx.conf
Normal file
@@ -0,0 +1,35 @@
|
||||
server {
|
||||
listen 80;
|
||||
server_name localhost;
|
||||
resolver 127.0.0.11; # This is for docker container name resolver
|
||||
#charset koi8-r;
|
||||
#access_log /var/log/nginx/host.access.log main;
|
||||
|
||||
# disable any limits to avoid HTTP 413 for large image uploads
|
||||
client_max_body_size 0;
|
||||
|
||||
# required to avoid HTTP 411: see Issue #1486 (https://github.com/moby/moby/issues/1486)
|
||||
chunked_transfer_encoding on;
|
||||
# required for strict SNI checking: see Issue #70 (https://github.com/Joxit/docker-registry-ui/issues/70)
|
||||
proxy_ssl_server_name on;
|
||||
|
||||
location /ui/ {
|
||||
proxy_pass http://ui/;
|
||||
}
|
||||
|
||||
#error_page 404 /404.html;
|
||||
|
||||
# redirect server error pages to the static page /50x.html
|
||||
#
|
||||
error_page 500 502 503 504 /50x.html;
|
||||
location = /50x.html {
|
||||
root /usr/share/nginx/html;
|
||||
}
|
||||
|
||||
# deny access to .htaccess files, if Apache's document root
|
||||
# concurs with nginx's one
|
||||
#
|
||||
#location ~ /\.ht {
|
||||
# deny all;
|
||||
#}
|
||||
}
|
||||
7
examples/issue-75/README.md
Normal file
7
examples/issue-75/README.md
Normal file
@@ -0,0 +1,7 @@
|
||||
# Example for issue #75
|
||||
|
||||
Run this command `docker-compose up -d`, then you can push your images (e.g localhost:5000/alpine).
|
||||
|
||||
Be careful, the docker registry is using status codes 307 for each requests, that means you must configure your s3 to accept same requests as your private registry (that means `DELETE`, `Access-Control-Allow-Origin` and others). To avoid this, we need the option `storage.redirect.disable: true`, with this you will use your registry credentials (if you are using it).
|
||||
|
||||
This s3 server allow all requests.
|
||||
32
examples/issue-75/docker-compose.yml
Normal file
32
examples/issue-75/docker-compose.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
version: '2.0'
|
||||
services:
|
||||
registry:
|
||||
image: registry:2.7
|
||||
volumes:
|
||||
- ./registry-data:/var/lib/registry
|
||||
- ./registry-config/config.yml:/etc/docker/registry/config.yml
|
||||
depends_on:
|
||||
- s3-server
|
||||
network_mode: host
|
||||
|
||||
ui:
|
||||
image: joxit/docker-registry-ui:static
|
||||
ports:
|
||||
- 80:80
|
||||
environment:
|
||||
- URL=http://127.0.0.1:5000
|
||||
- DELETE_IMAGES=true
|
||||
depends_on:
|
||||
- registry
|
||||
network_mode: host
|
||||
|
||||
s3-server:
|
||||
image: minio/minio:RELEASE.2019-04-09T01-22-30Z
|
||||
volumes:
|
||||
- ./s3-server-cmd:/bin/s3-server-cmd:ro
|
||||
environment:
|
||||
- MINIO_ACCESS_KEY=accessKey1
|
||||
- MINIO_SECRET_KEY=verySecretKey1
|
||||
- MINIO_REGION=us-east-1
|
||||
network_mode: host
|
||||
entrypoint: /bin/s3-server-cmd
|
||||
39
examples/issue-75/registry-config/config.yml
Normal file
39
examples/issue-75/registry-config/config.yml
Normal file
@@ -0,0 +1,39 @@
|
||||
version: 0.1
|
||||
|
||||
log:
|
||||
level: debug
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
delete:
|
||||
enabled: true
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
s3:
|
||||
accesskey: accessKey1
|
||||
secretkey: verySecretKey1
|
||||
region: us-east-1
|
||||
regionendpoint: http://127.0.0.1:9000
|
||||
bucket: registry
|
||||
encrypt: false
|
||||
secure: false
|
||||
v4auth: true
|
||||
chunksize: 5242880
|
||||
rootdirectory: /
|
||||
redirect:
|
||||
disable: true
|
||||
http:
|
||||
addr: 0.0.0.0:5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
Access-Control-Allow-Origin: ['http://127.0.0.1']
|
||||
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
|
||||
Access-Control-Allow-Headers: ['Authorization']
|
||||
Access-Control-Max-Age: [1728000]
|
||||
Access-Control-Allow-Credentials: [true]
|
||||
Access-Control-Expose-Headers: ['Docker-Content-Digest']
|
||||
health:
|
||||
storagedriver:
|
||||
enabled: true
|
||||
interval: 10s
|
||||
threshold: 3
|
||||
6
examples/issue-75/s3-server-cmd
Executable file
6
examples/issue-75/s3-server-cmd
Executable file
@@ -0,0 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
set -e
|
||||
|
||||
mkdir -p /data/registry
|
||||
minio server /data
|
||||
4
examples/issue-88/README.md
Normal file
4
examples/issue-88/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
# Example for issue #88
|
||||
|
||||
When the docker registry ui is used as a proxy and its port is not 80, we can't push images.
|
||||
To fix that, I added the correct Host header in the proxy_set_header.
|
||||
23
examples/issue-88/config.yml
Normal file
23
examples/issue-88/config.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
version: 0.1
|
||||
log:
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
delete:
|
||||
enabled: true
|
||||
http:
|
||||
addr: :5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
Access-Control-Allow-Origin: ['*']
|
||||
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
|
||||
Access-Control-Expose-Headers: ['Docker-Content-Digest']
|
||||
health:
|
||||
storagedriver:
|
||||
enabled: true
|
||||
interval: 10s
|
||||
threshold: 3
|
||||
34
examples/issue-88/docker-compose.yml
Normal file
34
examples/issue-88/docker-compose.yml
Normal file
@@ -0,0 +1,34 @@
|
||||
version: '2'
|
||||
|
||||
services:
|
||||
registry-srv:
|
||||
image: registry:latest
|
||||
restart: always
|
||||
volumes:
|
||||
- storage:/var/lib/registry
|
||||
- ./config.yml:/etc/docker/registry/config.yml:ro
|
||||
networks:
|
||||
- registry-ui-net
|
||||
container_name: registry-srv
|
||||
|
||||
registry-ui:
|
||||
image: joxit/docker-registry-ui:static
|
||||
restart: always
|
||||
ports:
|
||||
- 8080:80
|
||||
environment:
|
||||
- REGISTRY_TITLE=Private Docker Registry
|
||||
- REGISTRY_URL=http://registry-srv:5000
|
||||
- DELETE_IMAGES=true
|
||||
depends_on:
|
||||
- debugproxy
|
||||
networks:
|
||||
- registry-ui-net
|
||||
container_name: registry-ui
|
||||
|
||||
networks:
|
||||
registry-ui-net:
|
||||
|
||||
volumes:
|
||||
storage:
|
||||
driver: local
|
||||
19
examples/kubernetes/README.md
Normal file
19
examples/kubernetes/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Kubernetes installation of Docker Registry UI
|
||||
|
||||
## Full installation
|
||||
Install a registry and docker-registry-ui as frontend of this registry to kubernetes.
|
||||
|
||||
```sh
|
||||
kubectl apply -f *.yaml
|
||||
```
|
||||
|
||||
Please note that you'll need a PV provisionner to be able to store the uploaded images.
|
||||
|
||||
## Dynamic installation
|
||||
Edit the image tag in the ui-deployement.yaml file and set it to `latest`, then :
|
||||
|
||||
```sh
|
||||
kubectl apply -f ui*.yaml
|
||||
```
|
||||
|
||||
You'll get a docker-registry-ui pod installed inside kubernetes and you'll be able to configure it to act as a frontend to your existing registry(ies).
|
||||
31
examples/kubernetes/registry-configmap.yaml
Normal file
31
examples/kubernetes/registry-configmap.yaml
Normal file
@@ -0,0 +1,31 @@
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: docker-registry
|
||||
labels:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
app/version: "1.2.1"
|
||||
data:
|
||||
config.yml: |-
|
||||
version: 0.1
|
||||
log:
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
delete:
|
||||
enabled: true
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
http:
|
||||
addr: :5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
Access-Control-Allow-Origin: ['*']
|
||||
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
|
||||
Access-Control-Allow-Headers: ['Authorization']
|
||||
Access-Control-Max-Age: [1728000]
|
||||
Access-Control-Allow-Credentials: [true]
|
||||
Access-Control-Expose-Headers: ['Docker-Content-Digest']
|
||||
51
examples/kubernetes/registry-deployment.yaml
Normal file
51
examples/kubernetes/registry-deployment.yaml
Normal file
@@ -0,0 +1,51 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: docker-registry
|
||||
labels:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
app/version: "1.2.1"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
spec:
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
defaultMode: 420
|
||||
name: docker-registry
|
||||
- name: data
|
||||
persistentVolumeClaim:
|
||||
claimName: docker-registry
|
||||
containers:
|
||||
- name: registry
|
||||
image: "docker.io/registry:2.6.2"
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- name: registry
|
||||
containerPort: 5000
|
||||
protocol: TCP
|
||||
volumeMounts:
|
||||
- mountPath: "/var/lib/registry"
|
||||
name: "data"
|
||||
- mountPath: "/etc/docker/registry"
|
||||
name: "config"
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /v2/
|
||||
port: registry
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /v2/
|
||||
port: registry
|
||||
resources:
|
||||
{}
|
||||
14
examples/kubernetes/registry-pvc.yaml
Normal file
14
examples/kubernetes/registry-pvc.yaml
Normal file
@@ -0,0 +1,14 @@
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
labels:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
app/version: "1.2.1"
|
||||
name: docker-registry
|
||||
spec:
|
||||
accessModes:
|
||||
- "ReadWriteOnce"
|
||||
resources:
|
||||
requests:
|
||||
storage: 1Gi
|
||||
18
examples/kubernetes/registry-service.yaml
Normal file
18
examples/kubernetes/registry-service.yaml
Normal file
@@ -0,0 +1,18 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: docker-registry
|
||||
labels:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
app/version: "1.2.1"
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 5000
|
||||
targetPort: registry
|
||||
protocol: TCP
|
||||
name: registry
|
||||
selector:
|
||||
app: registry
|
||||
release: docker-registry-ui
|
||||
48
examples/kubernetes/ui-deployment.yaml
Normal file
48
examples/kubernetes/ui-deployment.yaml
Normal file
@@ -0,0 +1,48 @@
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: docker-registry-ui
|
||||
labels:
|
||||
app: registry-ui
|
||||
release: docker-registry-ui
|
||||
app/version: "1.2.1"
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: registry-ui
|
||||
release: docker-registry-ui
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: registry-ui
|
||||
release: docker-registry-ui
|
||||
spec:
|
||||
containers:
|
||||
- name: registry-ui
|
||||
image: "docker.io/joxit/docker-registry-ui:static"
|
||||
imagePullPolicy: Always
|
||||
env:
|
||||
- name: REGISTRY_TITLE
|
||||
value: "Docker registry UI"
|
||||
- name: DELETE_IMAGES
|
||||
value: "false"
|
||||
- name: REGISTRY_URL
|
||||
value: "http://docker-registry.default:5000"
|
||||
- name: PULL_URL
|
||||
value: "docker-registry-ui.default:80"
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
resources:
|
||||
{}
|
||||
|
||||
19
examples/kubernetes/ui-service.yaml
Normal file
19
examples/kubernetes/ui-service.yaml
Normal file
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: docker-registry-ui
|
||||
labels:
|
||||
app: registry-ui
|
||||
release: docker-registry-ui
|
||||
app/version: "1.2.1"
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
ports:
|
||||
- port: 80
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: registry-ui
|
||||
release: docker-registry-ui
|
||||
|
||||
19
examples/proxy-headers/README.md
Normal file
19
examples/proxy-headers/README.md
Normal file
@@ -0,0 +1,19 @@
|
||||
# Set custom headers to the registry example
|
||||
|
||||
The interface and the docker registry will be accessible with <http://localhost>.
|
||||
|
||||
This example highlight the usage of custom headers when the UI is used as a proxy. When you wants to use a header name with hyphens, replace them by underscores in the variable. You can put headers in environment variable or in config file `/etc/nginx/.env`. They have the same writing style.
|
||||
|
||||
Headers can be useful in some cases such as avoid sending credentials when you are on the UI. Or give to the registry server other properties such as X-Forward-For header.
|
||||
|
||||
I will set these two headers in this example. X-Forward-For by environment variable and Authorization by file.
|
||||
|
||||
In order to set your credentials in the header, you need to know how [Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Authorization) header works. Here we use the `Basic` authentication scheme, the credentials are constructed like this:
|
||||
- The username and the password are combined with a colon (`registry:ui`).
|
||||
- The resulting string is base64 encoded (`cmVnaXN0cnk6dWk=`). You can simply run `echo -n "registry:ui" | base64`.
|
||||
- In your header, put this value `Basic cmVnaXN0cnk6dWk=`
|
||||
- In your `/etc/nginx/.env`, the file will contains `NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk=`
|
||||
|
||||
For X-Forward-For, replace all hyphens by underscores, and the value will be a nginx variable which is `$proxy_add_x_forwarded_for`. In your docker compose you will need to duplicate the `$` character. In your docker-compose, your environment will look like `NGINX_PROXY_HEADER_X_Forwarded_For=$$proxy_add_x_forwarded_for`
|
||||
|
||||
As usual, run the project with `docker-compose up -d` (for background mode)
|
||||
28
examples/proxy-headers/docker-compose.yml
Normal file
28
examples/proxy-headers/docker-compose.yml
Normal file
@@ -0,0 +1,28 @@
|
||||
version: '2.0'
|
||||
services:
|
||||
registry:
|
||||
image: registry:2.7
|
||||
volumes:
|
||||
- ./registry-data:/var/lib/registry
|
||||
- ./registry-config/credentials.yml:/etc/docker/registry/config.yml
|
||||
- ./registry-config/htpasswd:/etc/docker/registry/htpasswd
|
||||
networks:
|
||||
- registry-ui-net
|
||||
|
||||
ui:
|
||||
image: joxit/docker-registry-ui:static
|
||||
ports:
|
||||
- 80:80
|
||||
environment:
|
||||
- REGISTRY_TITLE=My Private Docker Registry
|
||||
- REGISTRY_URL=http://registry:5000
|
||||
- NGINX_PROXY_HEADER_X_Forwarded_For=$$proxy_add_x_forwarded_for
|
||||
volumes:
|
||||
- ./nginx.env:/etc/nginx/.env
|
||||
depends_on:
|
||||
- registry
|
||||
networks:
|
||||
- registry-ui-net
|
||||
|
||||
networks:
|
||||
registry-ui-net:
|
||||
1
examples/proxy-headers/nginx.env
Normal file
1
examples/proxy-headers/nginx.env
Normal file
@@ -0,0 +1 @@
|
||||
NGINX_PROXY_HEADER_Authorization=Basic cmVnaXN0cnk6dWk=
|
||||
25
examples/proxy-headers/registry-config/credentials.yml
Normal file
25
examples/proxy-headers/registry-config/credentials.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
version: 0.1
|
||||
log:
|
||||
fields:
|
||||
service: registry
|
||||
storage:
|
||||
delete:
|
||||
enabled: true
|
||||
cache:
|
||||
blobdescriptor: inmemory
|
||||
filesystem:
|
||||
rootdirectory: /var/lib/registry
|
||||
http:
|
||||
addr: :5000
|
||||
headers:
|
||||
X-Content-Type-Options: [nosniff]
|
||||
Access-Control-Allow-Origin: ['http://localhost']
|
||||
Access-Control-Allow-Methods: ['HEAD', 'GET', 'OPTIONS', 'DELETE']
|
||||
Access-Control-Allow-Headers: ['Authorization']
|
||||
Access-Control-Max-Age: [1728000]
|
||||
Access-Control-Allow-Credentials: [true]
|
||||
Access-Control-Expose-Headers: ['Docker-Content-Digest']
|
||||
auth:
|
||||
htpasswd:
|
||||
realm: basic-realm
|
||||
path: /etc/docker/registry/htpasswd
|
||||
1
examples/proxy-headers/registry-config/htpasswd
Normal file
1
examples/proxy-headers/registry-config/htpasswd
Normal file
@@ -0,0 +1 @@
|
||||
registry:$2y$11$1bmuJLK8HrQl5ACS/WeqRuJLUArUZfUcP2R23asmozEpfN76.pCHy
|
||||
@@ -5,7 +5,7 @@ services:
|
||||
volumes:
|
||||
- ./registry-data:/var/lib/registry
|
||||
networks:
|
||||
- docker-registry-ui
|
||||
- registry-ui-net
|
||||
|
||||
ui:
|
||||
image: joxit/docker-registry-ui:static
|
||||
@@ -17,7 +17,7 @@ services:
|
||||
depends_on:
|
||||
- registry
|
||||
networks:
|
||||
- docker-registry-ui
|
||||
- registry-ui-net
|
||||
|
||||
networks:
|
||||
registry-ui-net:
|
||||
registry-ui-net:
|
||||
|
||||
@@ -20,14 +20,16 @@ const allTags = ['src/tags/*.tag', 'src/tags/dialogs/*.tag'];
|
||||
|
||||
const allScripts = [
|
||||
'src/scripts/http.js',
|
||||
'src/scripts/script.js'
|
||||
'src/scripts/script.js',
|
||||
'src/scripts/utils.js'
|
||||
];
|
||||
|
||||
const staticTags = ['src/tags/*.tag'];
|
||||
|
||||
const staticScripts = [
|
||||
'src/scripts/http.js',
|
||||
'src/scripts/static.js'
|
||||
'src/scripts/static.js',
|
||||
'src/scripts/utils.js'
|
||||
];
|
||||
|
||||
function html() {
|
||||
|
||||
@@ -24,6 +24,8 @@ server {
|
||||
#! if ($http_user_agent ~ "^(docker\/1\.(3|4|5(?!\.[0-9]-dev))|Go ).*$" ) {
|
||||
#! return 404;
|
||||
#! }
|
||||
#! proxy_set_header Host $http_host;
|
||||
#! ${NGINX_PROXY_HEADERS}
|
||||
#! proxy_pass ${REGISTRY_URL};
|
||||
#! }
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docker-registry-ui",
|
||||
"version": "1.1.0",
|
||||
"version": "1.2.3",
|
||||
"scripts": {
|
||||
"build": "./node_modules/gulp/bin/gulp.js build"
|
||||
},
|
||||
@@ -14,8 +14,8 @@
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"del": "^3.0.0",
|
||||
"gulp": "^4.0",
|
||||
"gulp-clean-css": "^4.0.0",
|
||||
"gulp": "^4.0.2",
|
||||
"gulp-clean-css": "^4.2.0",
|
||||
"gulp-concat": "^2.6.0",
|
||||
"gulp-filter": "^5.1.0",
|
||||
"gulp-htmlmin": "^5.0.1",
|
||||
@@ -23,7 +23,7 @@
|
||||
"gulp-inject-version": "^1.0.1",
|
||||
"gulp-license": "^1.1.0",
|
||||
"gulp-riot": "^1.1.5",
|
||||
"gulp-uglify": "^3.0.1",
|
||||
"gulp-uglify": "^3.0.2",
|
||||
"gulp-useref": "^3.1.6",
|
||||
"riot": "^3.13.2",
|
||||
"riot-mui": "^0.1.1",
|
||||
|
||||
@@ -20,13 +20,18 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<!-- build:css vendor.css -->
|
||||
<LINK href="../node_modules/riot-mui/build/styles/riot-mui.min.css" rel="stylesheet" type="text/css">
|
||||
<link href="../node_modules/riot-mui/build/styles/riot-mui.min.css" rel="stylesheet" type="text/css">
|
||||
<!-- endbuild -->
|
||||
<!-- build:css style.css -->
|
||||
<LINK href="style.css" rel="stylesheet" type="text/css">
|
||||
<LINK href="material-icons.css" rel="stylesheet" type="text/css">
|
||||
<link href="style.css" rel="stylesheet" type="text/css">
|
||||
<link href="material-icons.css" rel="stylesheet" type="text/css">
|
||||
<!-- endbuild -->
|
||||
<LINK href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css">
|
||||
<link href="https://fonts.googleapis.com/css?family=Roboto:regular,bold,italic,thin,light,bolditalic,black,medium&lang=en" rel="stylesheet" type="text/css">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta property="og:site_name" content="Docker Registry UI" />
|
||||
<meta name="twitter:card" content="summary" />
|
||||
<meta name="twitter:site" content="@Joxit" />
|
||||
<meta name="twitter:creator" content="@Jones Magloire" />
|
||||
<title>Docker Registry UI</title>
|
||||
</head>
|
||||
|
||||
@@ -56,6 +61,7 @@
|
||||
<script src="tags/app.tag" type="riot/tag"></script>
|
||||
<script src="scripts/http.js"></script>
|
||||
<script src="scripts/script.js"></script>
|
||||
<script src="scripts/utils.js"></script>
|
||||
<!-- endbuild -->
|
||||
</body>
|
||||
|
||||
|
||||
@@ -3,9 +3,9 @@
|
||||
font-family: 'Material Icons';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
src: url(MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||
src: local('fonts/Material Icons'),
|
||||
local('fonts/MaterialIcons-Regular'),
|
||||
src: url(fonts/MaterialIcons-Regular.eot); /* For IE6-8 */
|
||||
src: local('Material Icons'),
|
||||
local('MaterialIcons-Regular'),
|
||||
url(fonts/MaterialIcons-Regular.woff2) format('woff2'),
|
||||
url(fonts/MaterialIcons-Regular.woff) format('woff'),
|
||||
url(fonts/MaterialIcons-Regular.ttf) format('truetype');
|
||||
|
||||
@@ -16,7 +16,12 @@
|
||||
*/
|
||||
var registryUI = {}
|
||||
registryUI.url = function() {
|
||||
return '${URL}';
|
||||
var url = '${URL}';
|
||||
if (!url) {
|
||||
url = window.location.origin + window.location.pathname;
|
||||
return url.endsWith('/') ? url.substr(0, url.length - 1) : url;
|
||||
}
|
||||
return url;
|
||||
};
|
||||
registryUI.name = function() {
|
||||
return '${REGISTRY_TITLE}' || registryUI.url();
|
||||
|
||||
68
src/scripts/utils.js
Normal file
68
src/scripts/utils.js
Normal file
@@ -0,0 +1,68 @@
|
||||
|
||||
registryUI.bytesToSize = function (bytes) {
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
||||
if (bytes == undefined || isNaN(bytes)) {
|
||||
return '?';
|
||||
} else if (bytes == 0) {
|
||||
return '0 Byte';
|
||||
}
|
||||
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
||||
return Math.ceil(bytes / Math.pow(1024, i)) + ' ' + sizes[i];
|
||||
};
|
||||
|
||||
registryUI.dateFormat = function(date) {
|
||||
if (date === undefined) {
|
||||
return '';
|
||||
}
|
||||
const labels = ['a second', 'seconds', 'a minute', 'minutes', 'an hour', 'hours', 'a day', 'days', 'a month', 'months', 'a year', 'years'];
|
||||
const maxSeconds = [1, 60, 3600, 86400, 2592000, 31104000, Infinity];
|
||||
const diff = (new Date() - date) / 1000;
|
||||
for (var i = 0; i < maxSeconds.length - 1; i++) {
|
||||
if (maxSeconds[i] * 2 >= diff) {
|
||||
return labels[i * 2];
|
||||
} else if (maxSeconds[i + 1] > diff) {
|
||||
return Math.floor(diff / maxSeconds[i]) + ' ' + labels[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
registryUI.getHistoryIcon = function(attribute) {
|
||||
switch (attribute) {
|
||||
case 'architecture':
|
||||
return 'memory';
|
||||
case 'created':
|
||||
return 'event';
|
||||
case 'docker_version':
|
||||
return '';
|
||||
case 'os':
|
||||
return 'developer_board';
|
||||
case 'Cmd':
|
||||
return 'launch';
|
||||
case 'Entrypoint':
|
||||
return 'input';
|
||||
case 'Env':
|
||||
return 'notes';
|
||||
case 'Labels':
|
||||
return 'label';
|
||||
case 'User':
|
||||
return 'face';
|
||||
case 'Volumes':
|
||||
return 'storage';
|
||||
case 'WorkingDir':
|
||||
return 'home';
|
||||
case 'author':
|
||||
return 'account_circle';
|
||||
case 'id':
|
||||
case 'digest':
|
||||
return 'settings_ethernet';
|
||||
case 'created_by':
|
||||
return 'build';
|
||||
case 'size':
|
||||
return 'get_app';
|
||||
case 'ExposedPorts':
|
||||
return 'router';
|
||||
default:
|
||||
''
|
||||
}
|
||||
}
|
||||
@@ -56,6 +56,13 @@ material-card {
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 950px){
|
||||
material-card {
|
||||
width: 95%;
|
||||
max-width: 750px;
|
||||
}
|
||||
}
|
||||
|
||||
material-spinner {
|
||||
align-self: center;
|
||||
}
|
||||
@@ -330,6 +337,7 @@ material-popup material-button:hover material-waves {
|
||||
|
||||
material-popup .popup {
|
||||
max-width: 450px;
|
||||
top: 2em;
|
||||
}
|
||||
|
||||
footer {
|
||||
@@ -339,6 +347,22 @@ footer {
|
||||
bottom: 0;
|
||||
}
|
||||
|
||||
@media screen and (max-height: 750px) {
|
||||
main {
|
||||
min-height: calc(100% - 164px - 2.5em);
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
footer {
|
||||
position: relative;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (min-width: 760px) and (max-height: 750px) {
|
||||
main {
|
||||
min-height: calc(100% - 144px - 2.5em);
|
||||
}
|
||||
}
|
||||
|
||||
.select-padding {
|
||||
padding: 20px 0;
|
||||
}
|
||||
@@ -371,10 +395,14 @@ select {
|
||||
|
||||
.remove-tag {
|
||||
padding: 12px 5px;
|
||||
width: 30px;
|
||||
width: 66px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.remove-tag.delete {
|
||||
padding: 7px 5px;
|
||||
}
|
||||
|
||||
catalog material-card,
|
||||
tag-history material-card {
|
||||
min-height: auto;
|
||||
@@ -445,4 +473,37 @@ catalog-element catalog-element.showing material-card,
|
||||
catalog-element catalog-element.hide material-card {
|
||||
margin-top: -50px;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
remove-image {
|
||||
width: 30px;
|
||||
}
|
||||
|
||||
material-checkbox .label {
|
||||
display: none;
|
||||
}
|
||||
|
||||
taglist material-checkbox {
|
||||
margin: auto;
|
||||
width: 18px;
|
||||
}
|
||||
|
||||
material-checkbox.indeterminate .checkbox .checkmark {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
material-checkbox.indeterminate .checkbox.checked .checkmark {
|
||||
transform: rotate(90deg) scale(1);
|
||||
-webkit-transform: rotate(90deg) scale(1);
|
||||
-ms-transform: rotate(90deg) scale(1);
|
||||
-moz-transform: rotate(90deg) scale(1);
|
||||
-o-transform: rotate(90deg) scale(1);
|
||||
}
|
||||
|
||||
material-checkbox .checkbox {
|
||||
border-color: #777;
|
||||
}
|
||||
|
||||
material-checkbox .checkbox.checked {
|
||||
background-color: #777;
|
||||
}
|
||||
@@ -221,17 +221,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
oReq.send();
|
||||
};
|
||||
|
||||
registryUI.bytesToSize = function (bytes) {
|
||||
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
||||
if (bytes == undefined || isNaN(bytes)) {
|
||||
return '?';
|
||||
} else if (bytes == 0) {
|
||||
return '0 Byte';
|
||||
}
|
||||
const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
||||
return Math.ceil(bytes / Math.pow(1024, i)) + ' ' + sizes[i];
|
||||
};
|
||||
|
||||
registryUI.taglist.go = function(image) {
|
||||
route('taglist/' + image);
|
||||
};
|
||||
|
||||
@@ -15,29 +15,14 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<image-date>
|
||||
<div title="Creation date { this.localDate }">{ this.dateFormat(this.date) } ago</div>
|
||||
<div title="Creation date { this.localDate }">{ registryUI.dateFormat(this.date) } ago</div>
|
||||
<script type="text/javascript">
|
||||
const self = this;
|
||||
this.dateFormat = function(date) {
|
||||
if (date === undefined) {
|
||||
return '';
|
||||
}
|
||||
const labels = ['a second', 'seconds', 'a minute', 'minutes', 'an hour', 'hours', 'a day', 'days', 'a month', 'months', 'a year', 'years'];
|
||||
const maxSeconds = [1, 60, 3600, 86400, 2592000, 31104000, Infinity];
|
||||
const diff = (new Date() - date) / 1000;
|
||||
for (var i = 0; i < maxSeconds.length - 1; i++) {
|
||||
if (maxSeconds[i] * 2 >= diff) {
|
||||
return labels[i * 2];
|
||||
} else if (maxSeconds[i + 1] > diff) {
|
||||
return Math.floor(diff / maxSeconds[i]) + ' ' + labels[i * 2 + 1];
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
opts.image.on('creation-date', function(date) {
|
||||
self.date = date;
|
||||
self.localDate = date.toLocaleString()
|
||||
self.update();
|
||||
});
|
||||
opts.image.trigger('get-date');
|
||||
</script>
|
||||
</image-date>
|
||||
@@ -15,13 +15,21 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<remove-image>
|
||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" title="This will delete the image.">
|
||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" title="This will delete the image." hide="{ opts.multiDelete }">
|
||||
<i class="material-icons">delete</i>
|
||||
</material-button>
|
||||
<material-checkbox show="{ opts.multiDelete }" title="Select this tag to delete it."></material-checkbox>
|
||||
<script type="text/javascript">
|
||||
const self = this;
|
||||
|
||||
this.on('update', function() {
|
||||
if (!this.opts.multiDelete && this.tags['material-checkbox'].checked) {
|
||||
this.tags['material-checkbox'].toggle();
|
||||
}
|
||||
});
|
||||
|
||||
this.on('mount', function() {
|
||||
this.tags['material-button'].root.onclick = function() {
|
||||
this.delete = this.tags['material-button'].root.onclick = function(ignoreError) {
|
||||
const name = self.opts.image.name;
|
||||
const tag = self.opts.image.tag;
|
||||
const oReq = new Http();
|
||||
@@ -39,7 +47,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
registryUI.taglist.display()
|
||||
registryUI.snackbar('Deleting ' + name + ':' + tag + ' image. Run `registry garbage-collect config.yml` on your registry');
|
||||
} else if (this.status == 404) {
|
||||
registryUI.errorSnackbar('Digest not found');
|
||||
ignoreError || registryUI.errorSnackbar('Digest not found');
|
||||
} else {
|
||||
registryUI.snackbar(this.responseText);
|
||||
}
|
||||
@@ -60,6 +68,10 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
|
||||
oReq.send();
|
||||
};
|
||||
|
||||
this.tags['material-checkbox'].on('toggle', function() {
|
||||
registryUI.taglist.instance.trigger('toggle-remove-image', this.checked);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
</remove-image>
|
||||
|
||||
@@ -15,50 +15,9 @@ You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<tag-history-element class="{entry.key}">
|
||||
<div class="headline"><i class="material-icons">{ this.getIcon(entry.key) }</i>
|
||||
<div class="headline"><i class="material-icons">{ registryUI.getHistoryIcon(entry.key) }</i>
|
||||
<p>{ entry.key.replace('_', ' ') }</p>
|
||||
</div>
|
||||
<div class="value" if={!(entry.value instanceof Array)}> { entry.value }</div>
|
||||
<div class="value" each={ e in entry.value } if={entry.value instanceof Array}> { e }</div>
|
||||
<script type="text/javascript">
|
||||
this.getIcon = function(attribute) {
|
||||
switch (attribute) {
|
||||
case 'architecture':
|
||||
return 'memory';
|
||||
case 'created':
|
||||
return 'event';
|
||||
case 'docker_version':
|
||||
return '';
|
||||
case 'os':
|
||||
return 'developer_board';
|
||||
case 'Cmd':
|
||||
return 'launch';
|
||||
case 'Entrypoint':
|
||||
return 'input';
|
||||
case 'Env':
|
||||
return 'notes';
|
||||
case 'Labels':
|
||||
return 'label';
|
||||
case 'User':
|
||||
return 'face';
|
||||
case 'Volumes':
|
||||
return 'storage';
|
||||
case 'WorkingDir':
|
||||
return 'home';
|
||||
case 'author':
|
||||
return 'account_circle';
|
||||
case 'id':
|
||||
case 'digest':
|
||||
return 'settings_ethernet';
|
||||
case 'created_by':
|
||||
return 'build';
|
||||
case 'size':
|
||||
return 'get_app';
|
||||
case 'ExposedPorts':
|
||||
return 'router';
|
||||
default:
|
||||
''
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</tag-history-element>
|
||||
@@ -16,7 +16,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
-->
|
||||
<taglist>
|
||||
<!-- Begin of tag -->
|
||||
<material-card ref="taglist-tag" class="taglist">
|
||||
<material-card ref="taglist-tag" class="taglist" multi-delete={ this.multiDelete }>
|
||||
<div class="material-card-title-action">
|
||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" onclick="registryUI.home();">
|
||||
<i class="material-icons">arrow_back</i>
|
||||
@@ -42,7 +42,11 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
onclick="registryUI.taglist.reverse();">Tag
|
||||
</th>
|
||||
<th class="show-tag-history">History</th>
|
||||
<th class="remove-tag" show="{ registryUI.isImageRemoveActivated }"></th>
|
||||
<th class={ 'remove-tag': true, delete: this.parent.toDelete > 0 } show="{ registryUI.isImageRemoveActivated }">
|
||||
<material-checkbox ref="remove-tag-checkbox" class="indeterminate" show={ this.toDelete === 0} title="Toggle multi-delete. Alt+Click to select all tags."></material-checkbox>
|
||||
<material-button waves-center="true" rounded="true" waves-color="#ddd" title="This will delete selected images." onclick={ registryUI.taglist.bulkDelete } show={ this.toDelete > 0 }>
|
||||
<i class="material-icons">delete</i>
|
||||
</material-button></th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@@ -64,14 +68,79 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
<tag-history-button image={ image }/>
|
||||
</td>
|
||||
<td show="{ registryUI.isImageRemoveActivated }">
|
||||
<remove-image image={ image }/>
|
||||
<remove-image multi-delete={ this.opts.multiDelete } image={ image }/>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</material-card>
|
||||
<script>
|
||||
registryUI.taglist.instance = this;
|
||||
var self = registryUI.taglist.instance = this;
|
||||
|
||||
this.multiDelete = false;
|
||||
this.toDelete = 0;
|
||||
|
||||
this.on('delete', function() {
|
||||
if (!registryUI.isImageRemoveActivated || !this.multiDelete) {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.on('multi-delete', function() {
|
||||
if (!registryUI.isImageRemoveActivated) {
|
||||
return;
|
||||
}
|
||||
this.multiDelete = !this.multiDelete;
|
||||
});
|
||||
|
||||
this.on('toggle-remove-image', function(checked) {
|
||||
if (checked) {
|
||||
this.toDelete++;
|
||||
} else {
|
||||
this.toDelete--;
|
||||
}
|
||||
|
||||
if (this.toDelete <= 1) {
|
||||
this.update();
|
||||
}
|
||||
});
|
||||
|
||||
this._getRemoveImageTags = function() {
|
||||
var images = self.refs['taglist-tag'].tags['remove-image'];
|
||||
if (!(images instanceof Array)) {
|
||||
images = [images];
|
||||
}
|
||||
return images;
|
||||
};
|
||||
|
||||
registryUI.taglist.bulkDelete = function() {
|
||||
if (self.multiDelete && self.toDelete > 0) {
|
||||
self._getRemoveImageTags().filter(function(img) {
|
||||
return img.tags['material-checkbox'].checked;
|
||||
}).forEach(function(img) {
|
||||
img.delete(true);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
this.on('mount', function() {
|
||||
var toggle = this.tags['material-card'].refs['remove-tag-checkbox'].toggle;
|
||||
this.tags['material-card'].refs['remove-tag-checkbox'].toggle = function(e) {
|
||||
if (e.altKey) {
|
||||
self._getRemoveImageTags()
|
||||
.filter(function(img) { return !img.tags['material-checkbox'].checked; })
|
||||
.forEach(function(img) { img.tags['material-checkbox'].toggle() });
|
||||
} else {
|
||||
toggle();
|
||||
}
|
||||
};
|
||||
|
||||
this.tags['material-card'].refs['remove-tag-checkbox'].on('toggle', function() {
|
||||
registryUI.taglist.instance.multiDelete = this.checked;
|
||||
registryUI.taglist.instance.update();
|
||||
});
|
||||
});
|
||||
|
||||
registryUI.taglist.display = function() {
|
||||
registryUI.taglist.tags = [];
|
||||
if (route.routeName == 'taglist') {
|
||||
|
||||
Reference in New Issue
Block a user