How to Set up a Self-Hosted Docker Repo

Docker Logo

Docker is a quite popular technology in developers world, better part of all the new projects were built with Docker. At least, Docker has a reputation of a great tool for software distribution. For reference, we use it in our project Ambar. It's a document search system that uses docker-compose for installation.

At the begining, when we'd just started working on Ambar, we were using the public Docker repo, but the project was growing fast and we created an enterprise version, so we had to move to a private repo. This paper describes how to set up your own self-hosted Docker repo step by step.

Local Docker Repo

You can set up a local Docker repo just by one command, let's do it:

docker run -d -p 5000:5000 --restart=always --name registry registry:2  

Let's check the repo and upload an Ubuntu image into it:
1. Download an image from the official repo and add a tag localhost:5000/ubuntu to it
2. Push the downloaded image into your local repo: docker push localhost:5000/ubuntu

Now we know how to work with a local repo, let's create a docker-compose.yml to store the repo's start parameters:

registry:  
  restart: always
  image: registry:2
  ports:
    - 5000:5000  
  volumes:
    - /path/data:/var/lib/registry /*path to the location whe you want your docker repo to store images*/

To start the repo just execute docker-compose up -d in the same location with docker-compose file. Now, let's move to SSL and authentication setup.

SSL Setup

Why do we need SSL? A Docker repo exposed to the Internet should be accessible only via secure https connection with authentication. You can override this by using self-signed sertificates, but it's not a solid solution that produces numbers of issues. Better to setup SSL right. If you don't have a valid SSL certificate you can use Letsencrypt service. Also, keep in mind that SSL is mandatory for docker repos to use authentication.

If you already have an SSL certificate - just add the path to the certificate file into the docker-compose file:

registry:  
  restart: always
  image: registry:2
  ports:
    - 5000:5000
  environment:
    REGISTRY_HTTP_TLS_CERTIFICATE: /certs/domain.crt
    REGISTRY_HTTP_TLS_KEY: /certs/domain.key
  volumes:
    - /path/data:/var/lib/registry 
    - /path/certs:/certs /*location with your SSL sertificate*/

In case you don't have a certificate - the simpliest way is to use Letsencrypt. Last Docker versions support it out-of-the-box. I could not find any working example, so I made one up:

registry:  
  restart: always
  image: registry:2
  ports:
    - 443:5000 /*it's mandatory to change port to 443 to let Letsencrypt work properly*/
  environment:
    REGISTRY_HTTP_TLS_LETSENCRYPT_CACHEFILE: /cache.letsencrypt /*file to store Letsencrypt cache*/
    REGISTRY_HTTP_TLS_LETSENCRYPT_EMAIL: hello@rdseventeen.com /*email to create Letsencrypt account*/    
  volumes:
    - /path/data:/var/lib/registry    

Please be aware that it's mandatory to change the repo's port to 443 to let Letsencrypt work properly. You can use any location to store Letsencrypt cache files.

To test the repo let's execute these commands:

docker pull ubuntu  
docker tag ubuntu myregistrydomain.com:443/ubuntu  
docker push myregistrydomain.com:443/ubuntu  
docker pull myregistrydomain.com:443/ubuntu  

Authentication Setup

Let's protect our repo with a password. To do this, you need to create a file with passwords and provide the repo with it's location.

The command below creates user testuser with password testpassword and moves it to path/auth/htpasswd file.

  docker run --entrypoint htpasswd registry:2 -Bbn testuser testpassword > path/auth/htpasswd

Let's add the path to the file with passwords and enable basic authentification in docker-compose file:

registry:  
  restart: always
  image: registry:2
  ports:
    - 443:5000
  environment:
    REGISTRY_HTTP_TLS_LETSENCRYPT_CACHEFILE: /cache.letsencrypt
    REGISTRY_HTTP_TLS_LETSENCRYPT_EMAIL: hello@rdseventeen.com
    REGISTRY_AUTH: htpasswd
    REGISTRY_AUTH_HTPASSWD_PATH: /auth/htpasswd
    REGISTRY_AUTH_HTPASSWD_REALM: Registry Realm
  volumes:
    - /path/data:/var/lib/registry
    - /path/auth:/auth

To commit this changes you should restart the repo with docker-compose restart command.
Now you can login into the repo with docker login myregistrydomain.com:443 command.
After you've successfully logged in into the repo you can pull any image from it.

End of Story

We walked through the creating and setting up a self-hosted docker repo process step by step. To get a deeper knowledge on the subject you may want to read the official manual and the list of docker repo settings.

Subscribe to our updates, and stay tuned!

Ilya P

Read more posts by this author.

Subscribe to Ambar Blog. How we made your docs searchable

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!