As I previously mentioned in my post on deploying with docker-compose: I don’t want to push my docker images to public DockerHub repos. My images aren’t intended for public consumption and I don’t want to worry about keeping secrets out of my images.
I finally got around to deploying a private docker registry, and luckily, the Docker development team has made it so incredibly easy. Deployment is so simple, because the registry server itself is actually a docker container. Talk about self-hosted.
Digital Ocean has an excellent tutorial on deploying a docker registry, secured with HTTPS via Let’s Encrypt. I deploy most of my applications on Ubuntu droplets (which the tutorial targets), but the steps should easily translate to any major Linux distribution.
It’s nearly as simple as:
- Create the
docker-compose up -don the provided docker-compose.yaml
- Reverse proxy the domain to the localhost port (nginx)
- Add a docker login account using
A Single Hiccup
The one issue I did have was using Cloudflare for HTTPS, instead of Let’s Encrypt/certbot.
After following the tutorial, I was able to log in just fine:
docker login https://my.registry.com
But when I tried pushing my first image to the registry, I got a cryptic error:
$ docker push my.registry.com/my-image The push refers to repository [my.registry.com/my-image] 91a6f9ebe82c: Pushing 3.584kB 8a90669ee51d: Retrying in 3 seconds 37ea6c8b75fa: Pushing 3.584kB 14f687b6870a: Pushing 4.096kB a638f39e4bbd: Pushing 3.072kB 4f8672401053: Waiting 3e207b409db3: Waiting unknown blob
After doing some digging (googling) I found a stackoverflow answer (praise be!) that pinned the issue on the nginx proxy configuration.
I changed this line:
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto https;
Since I use the “Flexible” Cloudflare encryption, I suspect the request nginx recieves is actually an http request, which was causing the docker registry service to reject the request. By hard-coding the
X-Forwarded-Proto as https, I circumvent the issue.
Is it a security concern? Perhaps, but I’ll accept that risk for now. Cloudflare is just so damn convenient.
UPDATE - July 27:
I managed to deploy SSL certificates to my nginx server – I didn’t realize Cloudflare let’s you generate (non-root) CA Certs for your domains, or I would have done this much sooner! I just uploaded the
.pem files and updated the nginx config: now all traffic on port 80 is
301 Redirected to
https. I’m now using
Strict SSL for my Cloudflare domains.