mirror of
https://github.com/Joxit/docker-registry-ui.git
synced 2026-02-15 21:09:51 +00:00
Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d7af9f1822 | ||
|
|
6f5a5ff756 | ||
|
|
23a57e6c34 | ||
|
|
e41d6cfb85 | ||
|
|
c563f7dd4c | ||
|
|
bf3e3c9fa8 |
@@ -18,6 +18,7 @@ MAINTAINER Jones MAGLOIRE @Joxit
|
||||
|
||||
WORKDIR /usr/share/nginx/html/
|
||||
|
||||
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
|
||||
COPY dist/ /usr/share/nginx/html/
|
||||
COPY dist/scripts/script-static.js /usr/share/nginx/html/scripts/script.js
|
||||
COPY dist/scripts/tags-static.js /usr/share/nginx/html/scripts/tags.js
|
||||
|
||||
19
README.md
19
README.md
@@ -21,6 +21,8 @@ This web user interface uses [Riot](https://github.com/Riot/riot) the react-like
|
||||
- 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)
|
||||
|
||||
## Getting Started
|
||||
|
||||
@@ -83,13 +85,26 @@ docker run -d -p 80:80 joxit/docker-registry-ui
|
||||
|
||||
Some env options are available for use this interface for only one server.
|
||||
|
||||
- `URL`: set the static URL to use. (`Required`)
|
||||
- `DELETE_IMAGES`: if this variable is empty or `false`, delete feature is desactivated. It is activated otherwise.
|
||||
- `URL`: set the static URL to use (You will need CORS configuration). Example: `http://127.0.0.1:5000`. (`Required`)
|
||||
- `REGISTRY_URL`: your docker registry URL to contact (CORS configuration is not needed). Example: `http://my-docker-container:5000`. (Can't be used with `URL`, since 0.3.2).
|
||||
- `DELETE_IMAGES`: if this variable is empty or `false`, delete feature is deactivated. It is activated otherwise.
|
||||
|
||||
Example with `URL` option.
|
||||
|
||||
```sh
|
||||
docker run -d -p 80:80 -e URL=http://127.0.0.1:5000 -e DELETE_IMAGES=true joxit/docker-registry-ui:static
|
||||
```
|
||||
|
||||
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).
|
||||
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
|
||||
docker network create registry-ui-net
|
||||
docker run -d --net registry-ui-net --name registry-srv registry:2
|
||||
docker run -d --net registry-ui-net -p 80:80 -e REGISTRY_URL=http://registry-srv:5000 -e DELETE_IMAGES=true joxit/docker-registry-ui:static
|
||||
```
|
||||
|
||||
## Using CORS
|
||||
|
||||
Your server should be configured to accept CORS.
|
||||
|
||||
@@ -6,6 +6,11 @@ if [ -z "${DELETE_IMAGES}" ] || [ "${DELETE_IMAGES}" = false ] ; then
|
||||
sed -i "s/registryUI.isImageRemoveActivated *= *[^,;]*/registryUI.isImageRemoveActivated=false/" scripts/script.js
|
||||
fi
|
||||
|
||||
if [ -n "${REGISTRY_URL}" ] ; then
|
||||
sed -i "s,\${REGISTRY_URL},${REGISTRY_URL}," /etc/nginx/conf.d/default.conf
|
||||
sed -i "s,#!,," /etc/nginx/conf.d/default.conf
|
||||
fi
|
||||
|
||||
if [ -z "$@" ]; then
|
||||
nginx -g "daemon off;"
|
||||
else
|
||||
|
||||
2
dist/scripts/script-static.js
vendored
2
dist/scripts/script-static.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* docker-registry-ui
|
||||
* Copyright (C) 2016 Jones Magloire @Joxit
|
||||
* Copyright (C) 2016-2018 Jones Magloire @Joxit
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
||||
2
dist/scripts/script.js
vendored
2
dist/scripts/script.js
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* docker-registry-ui
|
||||
* Copyright (C) 2016 Jones Magloire @Joxit
|
||||
* Copyright (C) 2016-2018 Jones Magloire @Joxit
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
||||
4
dist/scripts/tags-static.js
vendored
4
dist/scripts/tags-static.js
vendored
File diff suppressed because one or more lines are too long
4
dist/scripts/tags.js
vendored
4
dist/scripts/tags.js
vendored
File diff suppressed because one or more lines are too long
6
dist/scripts/vendor.js
vendored
6
dist/scripts/vendor.js
vendored
File diff suppressed because one or more lines are too long
2
dist/style.css
vendored
2
dist/style.css
vendored
@@ -1,6 +1,6 @@
|
||||
/*!
|
||||
* docker-registry-ui
|
||||
* Copyright (C) 2016 Jones Magloire @Joxit
|
||||
* Copyright (C) 2016-2018 Jones Magloire @Joxit
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as
|
||||
|
||||
12
gulpfile.js
12
gulpfile.js
@@ -42,21 +42,21 @@ gulp.task('riot-tag', ['html'], function() {
|
||||
.pipe(license('agpl3', {
|
||||
tiny: false,
|
||||
project: 'docker-registry-ui',
|
||||
year: '2016',
|
||||
year: '2016-2018',
|
||||
organization: 'Jones Magloire @Joxit'
|
||||
}))
|
||||
.pipe(gulp.dest('dist/scripts'));
|
||||
});
|
||||
|
||||
gulp.task('riot-static-tag', ['html'], function() {
|
||||
return gulp.src(['src/tags/catalog.tag', 'src/tags/app.tag', 'src/tags/taglist.tag', 'src/tags/remove-image.tag'])
|
||||
return gulp.src(['src/tags/catalog.tag', 'src/tags/app.tag', 'src/tags/taglist.tag', 'src/tags/remove-image.tag', 'src/tags/image-size.tag'])
|
||||
.pipe(concat('tags-static.js'))
|
||||
.pipe(riot())
|
||||
.pipe(minifier({}, uglify))
|
||||
.pipe(license('agpl3', {
|
||||
tiny: false,
|
||||
project: 'docker-registry-ui',
|
||||
year: '2016',
|
||||
year: '2016-2018',
|
||||
organization: 'Jones Magloire @Joxit'
|
||||
}))
|
||||
.pipe(gulp.dest('dist/scripts'));
|
||||
@@ -69,7 +69,7 @@ gulp.task('scripts-static', ['html'], function() {
|
||||
.pipe(license('agpl3', {
|
||||
tiny: false,
|
||||
project: 'docker-registry-ui',
|
||||
year: '2016',
|
||||
year: '2016-2018',
|
||||
organization: 'Jones Magloire @Joxit'
|
||||
}))
|
||||
.pipe(gulp.dest('dist/scripts'));
|
||||
@@ -82,7 +82,7 @@ gulp.task('scripts', ['html'], function() {
|
||||
.pipe(license('agpl3', {
|
||||
tiny: false,
|
||||
project: 'docker-registry-ui',
|
||||
year: '2016',
|
||||
year: '2016-2018',
|
||||
organization: 'Jones Magloire @Joxit'
|
||||
}))
|
||||
.pipe(gulp.dest('dist/scripts'));
|
||||
@@ -103,7 +103,7 @@ gulp.task('styles', ['html'], function() {
|
||||
.pipe(license('agpl3', {
|
||||
tiny: false,
|
||||
project: 'docker-registry-ui',
|
||||
year: '2016',
|
||||
year: '2016-2018',
|
||||
organization: 'Jones Magloire @Joxit'
|
||||
}))
|
||||
.pipe(gulp.dest('dist/'));
|
||||
|
||||
33
nginx/default.conf
Normal file
33
nginx/default.conf
Normal file
@@ -0,0 +1,33 @@
|
||||
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;
|
||||
|
||||
location / {
|
||||
root /usr/share/nginx/html;
|
||||
index index.html index.htm;
|
||||
}
|
||||
|
||||
#! location /v2 {
|
||||
#! proxy_pass ${REGISTRY_URL};
|
||||
#! }
|
||||
|
||||
#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;
|
||||
#}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "docker-registry-ui",
|
||||
"version": "0.3.1",
|
||||
"version": "0.3.3",
|
||||
"scripts": {
|
||||
"build": "./node_modules/gulp/bin/gulp.js build"
|
||||
},
|
||||
@@ -24,7 +24,6 @@
|
||||
"gulp-riot": "^1.1.1",
|
||||
"gulp-uglify": "^2.1.2",
|
||||
"gulp-useref": "^3.1.3",
|
||||
"pump": "^1.0.2",
|
||||
"riot": "^3.7.4",
|
||||
"riot-mui": "^0.1.1",
|
||||
"riot-route": "^3.1.2",
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<script src="tags/change.tag" type="riot/tag"></script>
|
||||
<script src="tags/remove.tag" type="riot/tag"></script>
|
||||
<script src="tags/menu.tag" type="riot/tag"></script>
|
||||
<script src="tags/image-size.tag" type="riot/tag"></script>
|
||||
<script src="tags/app.tag" type="riot/tag"></script>
|
||||
<!-- endbuild -->
|
||||
<!-- build:js scripts/script.js -->
|
||||
|
||||
48
src/tags/image-size.tag
Normal file
48
src/tags/image-size.tag
Normal file
@@ -0,0 +1,48 @@
|
||||
<!--
|
||||
Copyright (C) 2018 Jones Magloire @Joxit
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
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/>.
|
||||
-->
|
||||
<image-size>
|
||||
<div>{ this.bytesToSize(this.size) }</div>
|
||||
<script type="text/javascript">
|
||||
var self = this;
|
||||
this.bytesToSize = function (bytes) {
|
||||
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB'];
|
||||
if (bytes == undefined || isNaN(bytes)) {
|
||||
return '?';
|
||||
} else if (bytes == 0) {
|
||||
return '0 Byte';
|
||||
}
|
||||
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
|
||||
return Math.ceil(bytes / Math.pow(1024, i)) + ' ' + sizes[i];
|
||||
};
|
||||
var oReq = new Http();
|
||||
oReq.addEventListener('loadend', function () {
|
||||
if (this.status == 200 || this.status == 202) {
|
||||
self.size = JSON.parse(this.responseText).layers.reduce(function (acc, e) {
|
||||
return acc + e.size;
|
||||
}, 0);
|
||||
self.update();
|
||||
} else if (this.status == 404) {
|
||||
registryUI.errorSnackbar('Manifest for ' + opts.name + ':' + opts.tag + ' not found');
|
||||
} else {
|
||||
registryUI.snackbar(this.responseText);
|
||||
}
|
||||
});
|
||||
oReq.open('GET', registryUI.url() + '/v2/' + opts.name + '/manifests/' + opts.tag);
|
||||
oReq.setRequestHeader('Accept', 'application/vnd.docker.distribution.manifest.v2+json');
|
||||
oReq.send();
|
||||
</script>
|
||||
</image-size>
|
||||
@@ -30,6 +30,7 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="material-card-th-left">Repository</th>
|
||||
<th>Size</th>
|
||||
<th class="{ registryUI.taglist.asc ? 'material-card-th-sorted-ascending' : 'material-card-th-sorted-descending' }" onclick="registryUI.taglist.reverse();">Tag</th>
|
||||
<th show="{ registryUI.isImageRemoveActivated }"></th>
|
||||
</tr>
|
||||
@@ -37,6 +38,7 @@
|
||||
<tbody>
|
||||
<tr each="{ item in registryUI.taglist.tags }">
|
||||
<td class="material-card-th-left">{ registryUI.taglist.name }</td>
|
||||
<td><image-size name={ registryUI.taglist.name } tag={ item } /></td>
|
||||
<td>{ item }</td>
|
||||
<td show="{ registryUI.isImageRemoveActivated }">
|
||||
<remove-image name={ registryUI.taglist.name } tag={ item }/>
|
||||
|
||||
Reference in New Issue
Block a user