Private Docker Registry
If you cannot (or want) to use DockerHub registry, then you can setup your own private docker registry which is cool because you can use docker itself to do that :)
We will use two available images
- https://hub.docker.com/_/registry/ : the registry itself
- https://hub.docker.com/r/konradkleine/docker-registry-frontend/ : a web frontend for the registry
Setting up the server
Certificate
First we need to create a certificate for SSL security Make sure that you enter the correct hostname as the last question (?)
mkdir certs
openssl genrsa -aes256 -out ca.key 2048
openssl req -new -x509 -days 7300 -key ca.key -sha256 -extensions v3_ca -out ca.crt
openssl genrsa -out domain.key 2048
openssl req -sha256 -new -key domain.key -out domain.csr
openssl x509 -sha256 -req -in domain.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out domain.crt -days 7300
# then verify
openssl verify -CAfile ca.crt domain.crt
(you probably would like to change the file names)
Basic Auth
We will setup basic authentication for the registry
mkdir auth
docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > auth/htpasswd
(Note: replace user and password!)
Docker Composing the Registry
Now that we have setted up all the required files lets create a new file docker-compose.yml to configure both docker images (registry and frontend) with the following content:
version: "2"
services:
registry:
image: registry:2
ports:
- 5000:5000
environment:
REGISTRY_HTTP_SECRET: aSecret
# ssl
REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
REGISTRY_HTTP_TLS_KEY: /certs/domain.key
# auth
REGISTRY_AUTH_HTPASSWD_REALM: 'Registry Realm'
REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
volumes:
- /home/ubuntu/docker-registry/data:/var/lib/registry
- /home/ubuntu/docker-registry/auth:/certs
- /home/ubuntu/docker-registry/auth:/auth
registry-frontend:
image: konradkleine/docker-registry-frontend:v2
ports:
- 5001:80
environment:
ENV_DOCKER_REGISTRY_HOST: registry
ENV_DOCKER_REGISTRY_PORT: 5000
links:
- registry
And now start it with
docker-compose up
To leave it running in background
docker-compose up -d
Now you can reach the registry frontend using the url http://localhost:8080/
Pushing
First setup your docker client with authentication data (user/passwd)
docker login --username <USER> --password <PASSWORD> my.server:5000
Then to push you need to first tag and image including the server name, and then push it using the full name
docker tag myImage my.server:5000/myImage
docker push my.server:5000/myImage
If you get an error about SSL certificates, then you will need to go to docker client Preferences (MacOS) and add your server to the "insecure registry" section.
Add it with the port my.server:5000
Continuous Integration with Private Registry
Here are some samples for building and publishing from different CIs to your own docker private registry
CircleCI
We need the server key to be used by docker a way to achieve this is to store the key along with the code, but encrypted. So to encrypt it
mkdir ci
cd ci
openssl aes-256-cbc -e -in domain.crt -out domain.crt.encrypted -k <<A_KEY_HERE>>
Notice that you need the domain.crt key that we generated on the server here. Also take note of the KEY you used here
Do the same for the ca.crt file we created on the server
openssl aes-256-cbc -e -in ca.crt -out ca.crt.encrypted -k <<A_KEY_HERE>>
Then
git add .
git ci -m "Adding encrypted docker private registry key"
Now edit circle.yml file
machine:
services:
- docker
dependencies:
override:
- docker info
test:
override:
- docker build --rm=false -t myImage .
deployment:
hub:
branch: build-docker-image
commands:
# decrypt cert
- openssl aes-256-cbc -d -in ci/domain.encrypted -k $SSL_ENCRYPT_KEY >> ci/domain.crt
- openssl aes-256-cbc -d -in ci/ca.crt.encrypted -k $SSL_ENCRYPT_KEY >> ci/ca.crt
# add cert to docker
- sudo mkdir -p /etc/docker/certs.d/myServer:5000/
- sudo cp ci/domain.crt /etc/docker/certs.d/myServer:5000/ca.pem
# add cert to OS
- sudo cp ci/ca.crt /usr/local/share/ca-certificates/domain-ca.crt
- sudo update-ca-certificates
# restart docker
- sudo service docker restart
# now use dokcer
- docker login -e $DOCKER_EMAIL -u $DOCKER_USER -p $DOCKER_PASS myServer:5000
- docker tag myImage myServer:5000/myImage
- docker push myServer:5000/myImage
And define the needed envvars in the build settings
- DOCKER_EMAIL
- DOCKER_USER
- DOCKER_PASS
- SSL_ENCRYPT_KEY: is the key we used to encrypt the certificates just a couple of steps before
Pending (not solved yet)
Authentication for the frontend
The frontend uses Kerberos authentication so lets create a user/passwd file for kerberos
(make sure you use the correct server name!)
sudo apt install krb5-user
ktutil
> addent -password -p jfernandes -k 1 -e rc4-hmac
>>> Password for [email protected]: ....
> ktutil: addent -password -p jfernandes -k 1 -e aes256-cts
>>> Password for [email protected]:
> wkt krb5.keytab
mkdir frontend-auth
mv krb5.keytab frontend-auth/
Then add to the frontend section of docker-compose.yml
# auth
ENV_AUTH_USE_KERBEROS: 1
ENV_AUTH_NAME: "NES Docker Registry Login"
ENV_AUTH_KRB5_KEYTAB: /etc/apache2/krb5.keytab
ENV_AUTH_KRB_REALMS: "nes.scvsoft.com"
ENV_AUTH_KRB_SERVICE_NAME: HTTP
volumes:
- /home/ubuntu/docker-registry/frontend-auth/krb5.keytab:/etc/apache2/krb5.keytab:ro
That's it, we will use this file in the docker-compose file.