Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Run docker private registry with read/write access control

Run docker private registry with read/write access control

Credits go to https://docs.docker.com/registry/recipes/nginx/ and http://mindtrove.info/control-read-write-access-docker-private-registry/

Follow the steps on https://docs.docker.com/registry/recipes/nginx/ with docker-compose.yml and nginx.conf below.

Run the following for admin UI:

docker run \
  -d --restart=unless-stopped --name registry-ui \
  -e ENV_DOCKER_REGISTRY_HOST=yourdomain.com \
  -e ENV_DOCKER_REGISTRY_PORT=5000 \
  -e ENV_DOCKER_REGISTRY_USE_SSL=1 \
  -e ENV_USE_SSL=yes \
  -e ENV_MODE_BROWSE_ONLY=false \
  -v ~/auth/domain.crt:/etc/apache2/server.crt:ro \
  -v ~/auth/domain.key:/etc/apache2/server.key:ro \
  -p 443:443 \
  coolersport/docker-registry-frontend
version: '2'
services:
nginx:
image: "nginx:alpine"
ports:
- 5000:443
links:
- registry:registry
volumes:
- ./auth:/etc/nginx/conf.d
- ./auth/nginx.conf:/etc/nginx/nginx.conf:ro
registry:
image: registry:2
environment:
REGISTRY_HTTP_ADDR: 0.0.0.0:5001
REGISTRY_STORAGE_DELETE_ENABLED: 'true'
ports:
- 127.0.0.1:5001:5001
volumes:
- ./registry:/var/lib/registry
events {
worker_connections 1024;
}
http {
upstream docker-registry {
server registry:5001;
}
## Set a variable to help us decide if we need to add the
## 'Docker-Distribution-Api-Version' header.
## The registry always sets this header.
## In the case of nginx performing auth, the header will be unset
## since nginx is auth-ing before proxying.
map $upstream_http_docker_distribution_api_version $docker_distribution_api_version {
'' 'registry/2.0';
}
server {
listen 443 ssl;
server_name yourdomain.com;
# SSL
ssl_certificate /etc/nginx/conf.d/domain.crt;
ssl_certificate_key /etc/nginx/conf.d/domain.key;
# Recommendations from https://raymii.org/s/tutorials/Strong_SSL_Security_On_nginx.html
ssl_protocols TLSv1.1 TLSv1.2;
ssl_ciphers 'EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH';
ssl_prefer_server_ciphers on;
ssl_session_cache shared:SSL:10m;
# 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;
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;
}
# To add basic authentication to v2 use auth_basic setting.
auth_basic "Registry realm";
auth_basic_user_file /etc/nginx/conf.d/htpasswd;
auth_request /_auth;
## If $docker_distribution_api_version is empty, the header will not be added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
proxy_pass http://docker-registry;
proxy_set_header Host $http_host; # required for docker client's sake
proxy_set_header X-Real-IP $remote_addr; # pass on real client's IP
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_read_timeout 900;
}
location /_auth {
if ($remote_user ~* "^admin-?.*$") {
# admin* is allowed to do anything
return 200;
}
if ($request_method ~* "^(GET|HEAD)$") {
# all other authed users can only GET/HEAD
return 200;
}
# anonymous users can do nothing
return 403;
}
}
}
@thecatontheflat

This comment has been minimized.

Copy link

thecatontheflat commented Jun 10, 2019

Thank you! Wasn't easy to find an example of nginx configuration for docker registry with ACL (the provided example in the docs certainly lacked this)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.