Create your own Secured Docker Private Registry (with SSL)

Introduction and what it is?

The Registry is a stateless, highly scalable server-side application that stores and lets you distribute Docker images. It is open-source, under the permissive Apache license link.

Why and where it is used?

Here are a few use cases where you will need a private registry.

1. To store docker images with custom domain.
2. Where there is no internet and you want to share the repository with the team or to install repository on server.
3. Application has a complex setup that requires a large number of dependancy packages. Docker allows us to build it in a single image file.
4. Remove external service provider costs

Here are the quick 5 steps with which you can get your Registry up and running.

  1. Running a docker registry up on port 5000.
  2. Making it secure using SSL which will enable it to work on port 443.
  3. Protect registry with a username and password.
  4. Test the registry by pushing new container.
  5. Store your images outside the container by mounting the volume.

Prerequisite: Docker should be installed on the server link.

1. Running a docker registry up on port 5000.

#This will fetch the new image file from docker hub and run on port 5000
docker run -d --restart=always --name registry -p 5000:5000 registry:2
# Verify the installation using below steps.
# docker push an image
docker pull your_domain.com:5000/image_name:version
#docker pull an image
docker pull your_domain.com:5000/image_name:version

2. Making it secure using SSL which will enable it to work on port 443.

Here you should have a valid SSL certificate. Else we can directly proceed to step 3.
Obtain you_domain.crt and zip file from the CA. The zip file will contain files that will come handy to create your_domain.pem certificate.

#we need following from SSL certificate console.
1. The Private Key - your_domain_name.key (This is user created while creating .csr)
2. The Primary Certificate - your_domain_name.crt
3. The Intermediate Certificate - DigiCertCA.crt
4. The Root Certificate - TrustedRoot.crt
Create a new empty file with name your_domain.pem and add below mentioned file data in given sequence.
Make sure to include the beginning and end tags on each certificate. The result should look like this:
-----BEGIN RSA PRIVATE KEY-----
(Your Private Key: your_domain_name.key)
-----END RSA PRIVATE KEY-----

-----BEGIN CERTIFICATE-----
(Your Primary SSL certificate: your_domain_name.crt)
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
(Your Intermediate certificate: DigiCertCA.crt)
-----END CERTIFICATE-----

-----BEGIN CERTIFICATE-----
(Your Root certificate: TrustedRoot.crt)
-----END CERTIFICATE-----

Now you have a your_domain.pem ready to use with your docker registry.
We will thus remove the existing docker running on port 5000 (created in Step 1) and run the new on port 443.
Ensure the port is enabled and your domain is pointing to it. (Which will help user )

# remove existing container
docker rm --force registry
# run new docker container on port 443. Create a cert folder and add both certificate file inside the folder.
docker run -d --restart=always --name registry >
-v ${path}/certs:/certs >
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 >
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/your_domain.pem >
-e REGISTRY_HTTP_TLS_KEY=/certs/your_domain.key >
-p 443:443 registry:2

Validate it is running correctly as expected by adding your URL https://your_domain.com and click check SSL Link.
There should not be any break symbols on this page. Output should be something as below (All Green and right symbols).

Now our registry is running on port 443, which is secured with our SSL certificate.

3. Protect registry with a username and password.

Private repository needs authentication to work.
We need a user for registry login. Below is the command for creating the user. Once we create a user we will provide the htpasswd file to the docker container.

# creating a user and save it to auth folder.
docker run --entrypoint htpasswd registry:2 -Bbn <your_username> <your_password> > auth/htpasswd
#remove the old repository
docker rm --force registry
#run the new container with htpasswd
docker run -d --restart=always --name registry >
-v ${path}/certs:/certs >
-v ${path}/auth:/auth >
-e "REGISTRY_AUTH=htpasswd" >
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" >
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd >
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 >
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/your_domain.pem >
-e REGISTRY_HTTP_TLS_KEY=/certs/your_domain.key >
-p 443:443 registry:2

4. Test the registry by pushing new container.

#docker login from the vm you require.
#this will prompt for username and password.
docker login your_domain.com
#docker push or pull a image from repository
docker pull your_domain.com/image_name:version

This will download the image to your VM. Now you can run the same on the VM.

5. Store your images outside the container by mounting the volume.

To retain the images pushed into the repository we need to store the images outside docker container.

Using -v we can mount a folder to docker container. Example.

#We created a folder named registry and mounted to the container
docker run -d --restart=always --name registry >
-v ${path}/registry:/var/registrylib/registry
-v ${path}/certs:/certs >
-v ${path}/auth:/auth >
-e "REGISTRY_AUTH=htpasswd" >
-e "REGISTRY_AUTH_HTPASSWD_REALM=Registry Realm" >
-e REGISTRY_AUTH_HTPASSWD_PATH=/auth/htpasswd >
-e REGISTRY_HTTP_ADDR=0.0.0.0:443 >
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/your_domain.pem >
-e REGISTRY_HTTP_TLS_KEY=/certs/your_domain.key >
-p 443:443 registry:2

Summary

Congratulations! You have successfully made your own private registry.
We hope you enjoyed it!
Thank you so much for taking your precious time to read this post.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store