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

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.

results matching ""

    No results matching ""