Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
FROM ubuntu:14.04
FROM ubuntu:16.04

ENV DEBIAN_FRONTEND noninteractive
#prevent apt from installing recommended packages
RUN echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/docker-no-recommends && \
echo 'APT::Install-Suggests "false";' >> /etc/apt/apt.conf.d/docker-no-recommends

# Install java and tomcat
RUN apt-get update && apt-get install -y tomcat7 openjdk-7-jdk libyaml-perl libfile-slurp-perl && \
RUN apt-get update && apt-get install -y tomcat7 openjdk-8-jdk libyaml-perl libfile-slurp-perl && \
rm -rf /var/lib/tomcat7/webapps/* && \
rm -rf /var/lib/apt/lists/*

ENV JAVA_HOME /usr/lib/jvm/java-7-openjdk-amd64
ENV JAVA_HOME /usr/lib/jvm/java-8-openjdk-amd64
ENV CATALINA_HOME /usr/share/tomcat7
ENV CATALINA_BASE /var/lib/tomcat7

Expand Down
24 changes: 13 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,23 @@
# This repo is a fork version with some enhancement of this awesome repo https://github.com/mkuchin/docker-registry-web

# docker-registry-web

Web UI, authentication service and event recorder for private docker registry v2.

[![Docker Stars](https://img.shields.io/docker/stars/hyper/docker-registry-web.svg?maxAge=86400)](https://hub.docker.com/r/hyper/docker-registry-web/) [![Docker Pulls](https://img.shields.io/docker/pulls/hyper/docker-registry-web.svg?maxAge=86400)](https://hub.docker.com/r/hyper/docker-registry-web/)
[![Docker Stars](https://img.shields.io/docker/stars/lukenvn/docker-registry-web.svg?maxAge=86400)](https://hub.docker.com/r/lukenvn/docker-registry-web/) [![Docker Pulls](https://img.shields.io/docker/pulls/lukenvn/docker-registry-web.svg?maxAge=86400)](https://hub.docker.com/r/lukenvn/docker-registry-web/)

## Features:

* Browsing repositories, tags and images in docker registry v2
* Optional token based authentication provider with role-based permissions
* Docker registry notification recording and audit

### Warning: [this version config](https://github.com/mkuchin/docker-registry-web/blob/master/web-app/WEB-INF/config.yml) is not compatible with configuration of versions prior 0.1.0
[Migrating configuration from 0.0.4 to 0.1.x](https://github.com/mkuchin/docker-registry-web/wiki/Migrating-configuration)
### Warning: [this version config](https://github.com/lukenvn/docker-registry-web/blob/master/web-app/WEB-INF/config.yml) is not compatible with configuration of versions prior 0.1.0
[Migrating configuration from 0.0.4 to 0.1.x](https://github.com/lukenvn/docker-registry-web/wiki/Migrating-configuration)

### Docker pull command

docker pull hyper/docker-registry-web
docker pull lukenvn/docker-registry-web

### How to run

Expand All @@ -24,14 +26,14 @@ Web UI, authentication service and event recorder for private docker registry v2
Do not use _registry_ as registry container name, it will break `REGISTRY_NAME` environment variable.

docker run -d -p 5000:5000 --name registry-srv registry:2
docker run -it -p 8080:8080 --name registry-web --link registry-srv -e REGISTRY_URL=http://registry-srv:5000/v2 -e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
docker run -it -p 8080:8080 --name registry-web --link registry-srv -e REGISTRY_URL=http://registry-srv:5000/v2 -e REGISTRY_NAME=localhost:5000 lukenvn/docker-registry-web

#### Connecting to docker registry with basic authentication and self-signed certificate
docker run -it -p 8080:8080 --name registry-web --link registry-srv \
-e REGISTRY_URL=https://registry-srv:5000/v2 \
-e REGISTRY_TRUST_ANY_SSL=true \
-e REGISTRY_BASIC_AUTH="YWRtaW46Y2hhbmdlbWU=" \
-e REGISTRY_NAME=localhost:5000 hyper/docker-registry-web
-e REGISTRY_NAME=localhost:5000 lukenvn/docker-registry-web


#### No authentication, with config file
Expand All @@ -55,7 +57,7 @@ Do not use _registry_ as registry container name, it will break `REGISTRY_NAME`
2. Run with docker

docker run -p 5000:5000 --name registry-srv -d registry:2
docker run -it -p 8080:8080 --name registry-web --link registry-srv -v $(pwd)/config.yml:/conf/config.yml:ro hyper/docker-registry-web
docker run -it -p 8080:8080 --name registry-web --link registry-srv -v $(pwd)/config.yml:/conf/config.yml:ro lukenvn/docker-registry-web

3. Web UI will be available on `http://localhost:8080`

Expand Down Expand Up @@ -119,7 +121,7 @@ Do not use _registry_ as registry container name, it will break `REGISTRY_NAME`

docker run -v $(pwd)/conf/registry-web.yml:/conf/config.yml:ro \
-v $(pwd)/conf/auth.key:/conf/auth.key -v $(pwd)/db:/data \
-it -p 8080:8080 --link registry-srv --name registry-web hyper/docker-registry-web
-it -p 8080:8080 --link registry-srv --name registry-web lukenvn/docker-registry-web

6. Web UI will be available on `http://localhost:8080` with default admin user/password `admin/admin`.

Expand All @@ -139,10 +141,10 @@ User access allows to browse registry, admin access allows to create, delete and
UI_DELETE role allows deleting images in the UI based on ACLs.

Every non-special role has a list of ACLs, each of ACL grants permission grants permission to `pull`, `pull+push` or `pull+push+delete`
based on IP and image name [glob matching](https://github.com/mkuchin/docker-registry-web/wiki/Glob-matching).
based on IP and image name [glob matching](https://github.com/lukenvn/docker-registry-web/wiki/Glob-matching).
For example **read-all** role matches any IP and any image name with glob `*` and grants `pull` permission and
**write-all** role grants `pull+push` permission for any IP and any image name.

### [Configuration reference](https://github.com/mkuchin/docker-registry-web/blob/master/web-app/WEB-INF/config.yml)
### [Configuration reference](https://github.com/lukenvn/docker-registry-web/blob/master/web-app/WEB-INF/config.yml)

### [Docker Compose configuration examples](https://github.com/mkuchin/docker-registry-web/tree/master/examples)
### [Docker Compose configuration examples](https://github.com/lukenvn/docker-registry-web/tree/master/examples)
2 changes: 2 additions & 0 deletions examples/auth-enabled/conf/registry-web/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ registry:
url: http://registry:5000/v2
name: localhost:5000
readonly: false
# with this config the user will not see all the available repos in docker-registry-web
show-permitted-repo-only: true
auth:
enabled: true
key: /conf/auth.key
Expand Down
2 changes: 1 addition & 1 deletion examples/auth-enabled/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ services:
- 5000:5000
volumes:
- ./conf/registry:/etc/docker/registry:ro
- ./registry:/var/lib/registry
- ./registry:/registry
networks:
- registry-net

Expand Down
2 changes: 2 additions & 0 deletions examples/nginx-auth-enabled/conf/registry-web/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ registry:
url: http://registry:5000/v2
name: localhost
readonly: false
# with this config the user will not see all the available repos in docker-registry-web
show-permitted-repo-only: true
auth:
enabled: true
key: /conf/auth.key
Expand Down
4 changes: 2 additions & 2 deletions examples/nginx-auth-enabled/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ services:
- 127.0.0.1:5000:5000
volumes:
- ./conf/registry:/etc/docker/registry:ro
- ./registry:/var/lib/registry
- ./registry:/registry
networks:
- registry-net

networks:
registry-net:
registry-net:
12 changes: 7 additions & 5 deletions grails-app/conf/config.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
#dev config

registry:
# Docker registry url
url: 'http://localhost:5001/v2/'
name: 'hub.devspire.com.au'
# Docker registry url
url: http://localhost:5000/v2/
name: localhost:5000
# enable showing permitted repo only on docker registry web
show-permitted-repo-only: true
auth:
enabled: true
#issuer: 'xxx'
key: ssl/key-dec.pem
issuer: test
key: /Users/ngovannhung/Downloads/docker-registry-web-master/grails-app/conf/auth.key
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package docker.registry.web

import docker.registry.AccessControl
import docker.registry.Role
import docker.registry.RoleAccess
import groovy.json.JsonSlurper
import org.springframework.beans.factory.annotation.Value

Expand All @@ -11,8 +14,12 @@ class RepositoryController {
@Value('${registry.name}')
String registryName

@Value('${registry.show-permitted-repo-only}')
boolean enableShowPermittedRepoOnly

def restService
def authService
def springSecurityService;

//{"Type":"registry","Name":"catalog","Action":"*"}
def index() {
Expand All @@ -22,6 +29,8 @@ class RepositoryController {
boolean hasNext = false
def message
def url = "_catalog?n=${recordsPerPage}"


try {
if (params.start) {
url += "&last=${params.start}"
Expand All @@ -37,8 +46,12 @@ class RepositoryController {
pagination = hasNext || params.prev != null
def repos = restResponse.json.repositories
next = repos ? repos.last() : null
def permittedRepos = repos
if (enableShowPermittedRepoOnly == true) {
permittedRepos = filterPermittedRepoOnly(repos)
}

repoCount = repos.collect { name ->
repoCount = permittedRepos.collect { name ->
def tagsCount = getTagList(name).size()
[name: name, tags: tagsCount]
}
Expand All @@ -49,6 +62,26 @@ class RepositoryController {
[repos: repoCount, pagination: pagination, next: next, prev: params.start, hasNext: hasNext, registryName: registryName, message: message]
}

private List<String> filterPermittedRepoOnly(repos) {
def currentUser = springSecurityService.currentUser
def roles = currentUser.authorities.collect { role ->
Role.findByAuthority(role.authority)
}.findAll { it }
def acls = roles.collect { role ->
RoleAccess.findAllByRole(role).acl
}.flatten()
repos.findAll { name -> hasPermission(acls, name) }
}

def hasPermission(acls,name){

for (AccessControl element : acls) {
if (GlobMatcher.check(element.name, name)) {
return true;
}
}
return false
}
def tags() {
String name = params.id.decodeURL()
def tags = getTags(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ class UserController {
user.accountLocked = params.accountLocked as boolean
//update password only if it entered
if (params.password) {
user.password = params.password
user.password = params.password[1]
}

if (user.isDirty()) {
Expand Down
12 changes: 12 additions & 0 deletions grails-app/services/docker/registry/web/AuthService.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,18 @@ class AuthService {
}.actions.flatten().unique()
log.info "Granting permissions: $actions"
}
//scope: registry:catalog:*
if(aclList && scope && scope.type == 'registry' && scope.name == 'catalog' ){
actions = aclList.collect { AccessControl acl ->
def scopeActions = scope.actions;
if(scopeActions.size()>0){
if (GlobMatcher.check(acl.name, scopeActions[0])){
return scopeActions[0]
}else
return AccessLevel.NONE.actions;
}
}.flatten().unique()
}
actions
}

Expand Down
5 changes: 3 additions & 2 deletions grails-app/views/layouts/main.gsp
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@
</li>
<li>
<g:link controller="role">Roles</g:link>
</li></sec:ifAnyGranted>
<sec:ifLoggedIn>
</li>
<li>
<g:link controller="event">Events</g:link>
</li>
<li>
<g:link controller="status">Status</g:link>
</li>
</sec:ifAnyGranted>
<sec:ifLoggedIn>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true"
aria-expanded="false"><strong><sec:username/><span class="caret"></span></strong></a>
Expand Down
2 changes: 2 additions & 0 deletions web-app/WEB-INF/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ registry:
readonly: true
# Docker registry fqdn
name: 'localhost:5000'
# enable showing permitted repo only on docker registry web
show-permitted-repo-only: true
# Authentication settings
auth:
# Enable authentication
Expand Down