This gist describes how to set up a private Docker Registry on an AWS EC2 instance and how to secure it with TLS using a certificate by Let's Encrypt.
A Docker registry is a server side application that stores and lets you distribute Docker images. It runs in an own Docker container and the image is freely available. Let's Encrypt is a Certificate Authority that gives away TLS certificates for free.
We require the following three items to be set up correctly before we start.
- An EC2 instance with Docker installed
- A domain name associated with the EC2 instance
- The EC2 instance's VPC and Security Group have been setup to expose the ssh port and the Docker Registry port (5000/TCP) publicly.
- On the EC2 instance, clone the certificate bot for obtaining the certificate from Let's Encrypt:
git clone https://github.com/certbot/certbot.git
- Run the bot with the
standalone plugin
(i.e., no webserver required). SubstituteYOUR_DOMAIN
in the examples from here on.
./certbot-auto certonly --standalone -d YOUR_DOMAIN --email YOUR_EMAIL_ADDRESS
This generates the following four files in /etc/letsencrypt/live/YOUR_DOMAIN
cert.pem chain.pem fullchain.pem privkey.pem
into the registry container next and copy the files into i
- Still on the EC2 instance, we will need the
fullchain.pem
andprivkey.pem
in our registry. Therefore, we create a directory/certs/
to be mounted as volume in the next step. For consistency with the Docker Registry documentation we rename the files todomain.crt
anddomain.key
, respectively. - Run the registry as follows.
docker run -d -p 5000:5000 -p 443:443 \
--restart=no \
--name registry \
-v /certs:/certs \
-e REGISTRY_HTTP_TLS_CERTIFICATE=/certs/domain.crt \
-e REGISTRY_HTTP_TLS_KEY=/certs/domain.key \
registry:2
- On your local machine (preferrably on the EC2 instance hosting the
registry), smoke test with
curl https://YOUR_DOMAIN:5000
. This should yield no errors. - Download and tag an image so that it points to the new registry:
docker pull sinatra && docker tag sinatra YOUR_DOMAIN:5000/sinatra
- Push the image to the new registry.
docker push YOUR_DOMAIN:5000/sinatra
. If the upload succeeds all is fine. - Verify by listing your registry's catalog
curl -X GET https://YOUR_DOMAIN:5000/v2/_catalog
.