Setting up your own private Docker registry
If you’re using your own private Docker registry.
First install htpasswd
sudo yum install httpd-tools
Run this on the server where your private docker registry is running:
htpasswd -Bbn andres mypassword > /home/nginx/conf.d/nginx.htpasswd
Use nginx as proxy in front of your private docker registry in order to secure it with SSL and http authentication scheme.
Create a project directory for this private docker registry:
mkdir /home/andres/driver-studios/docker-registry/
Create the following files in the docker-registry directory. Update the sshHost variable in tasks.sh before proceeding.
Then run:
./tasks deploy_production
to deploy your registry to the server.
docker-registry/docker-compose.production.yml:
================================================
version: '3.7'
services:
registry:
image: registry:2
container_name: docker-registry
ports:
- "5000:5000"
networks:
- web
networks:
web:
external: true
docker-registry/tasks.sh
================================================
#!/bin/bash
# Build script to build and push the docker image to the remote repository
# Usage:
# ./task.sh deploy_production
sshHost=andres@dev.driverdigital.com
function main() {
case $1 in
deploy_production)
deploy_production
;;
esac
}
function deploy_production() {
DIR="docker-registry"
DIR=/tmp/$DIR
ssh ${sshHost} "
if [ ! -d $DIR ]; then
mkdir -p $DIR
fi"
rsync -avz ./docker-compose.production.yml ${sshHost}:$DIR
ssh ${sshHost} "cd $DIR && docker-compose -f docker-compose.production.yml up -d"
}
main $@
nginx configuration
Next we need to go to your nginx project folder in Visual Studio Code. This is the directory containing your ngninx hosts configurations.
cd /home/andres/driver-studios/nginx-dev
In your nginx project, create a configuration for the domain where your registry will be hosted (see below). Then upload the configuration via:
./build-tools/tasks.sh reload_production
Then generate an authentic SSL certificate from LetsEncrypt via
./build-tools/tasks.sh ssl_production
Then run this to generate the http password:
docker run --rm --entrypoint htpasswd registry:2 -Bbn andres mypassword > conf.d/nginx.htpasswd
Then run ./build-tools/tasks.sh reload_production again to upload the generate htpasswd file.
conf.d/docker-registry-01.driver-studios.com.conf
server {
listen 80;
server_name docker-registry-01.driver-studios.com;
location / {
return 301 https://$host$request_uri;
}
location /.well-known/acme-challenge/ {
root /var/www/certbot;
}
}
## 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 is 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 http2 ssl;
server_name docker-registry-01.driver-studios.com;
access_log /var/log/nginx/docker-registry-01.driver-studios.com.access.log;
error_log /var/log/nginx/docker-registry-01.driver-studios.com.error.log;
ssl_certificate /etc/letsencrypt/live/docker-registry-01.driver-studios.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/docker-registry-01.driver-studios.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
# Insure that UTF-8 encoding is specified in the Content-Type HTTP response
# header for most of our text responses
charset_types text/xml text/plain text/vnd.wap.wml application/javascript application/rss+xml text/css;
charset utf-8;
# 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 / {
root /usr/share/nginx/html;
index index.html index.htm;
}
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/nginx.htpasswd;
## If $docker_distribution_api_version is empty, the header is not added.
## See the map directive above where this variable is defined.
add_header 'Docker-Distribution-Api-Version' $docker_distribution_api_version always;
resolver 127.0.0.11 valid=3600s;
# ads-web resolves to the ip of the docker container running node app
set $upstream_channels docker-registry:5000;
proxy_pass http://$upstream_channels;
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;
}
}
Finally
Then to login to your registry in order to push or pull images to it
docker login -u=andres --password-stdin docker-registry-01.driver-studios.com
mypassword (Enter Ctrl+D after the “d” to submit the password) Note: Password I’m using for driver-studios registry is “a****”
To push an image from your machine to your private registry:
docker push docker-registry-01.driver-studios.com/test
To pull:
docker pull docker-registry-01.driver-studios.com/test