Years ago, I used Artifactory to create a simple private registry that had private and proxy repos behind a grouped repo to make the repo look like one. The group repo defined which repo should be the default write repo. This was nifty, though managing SSL wasn't fun, and then I was running Artifactory on a VM.
Forward to today, where we have nice tools like Traefik and Nexus3. Traefik, easily integrates into my DNS server to allow for dynamic generation of SSL for my internal services. Nexus for my personal use is OpenSource and fits my budget for caching and hosting repos.
Why do I need SSL for my private services? First, I can. Second, browsers are trying to be more and more secure and having to save private SSL certs all the time are annoying.
I'm running my repo behind a Traefik proxy, with integration with Let's Encrypt
to provide my SSL cert. I can quickly add a label in my docker stack for nexus3:
traefik.frontend.rule=Host:nexus.cool.terzo.org. With this 1 label line
I have an SSL cert and A frontend port to start serving out my nexus repo.
Digging into Nexus3's docker registry, you have to expose private ports to enable a docker registry. This is due to how docker does all it's API calls expecting to be at the top level (https://docs.docker.com/registry/spec/api/) of a server.
When setting this up in nexus3, you create a local docker repo, which is your
private repo. Next create a proxy repo that points to say the hub. Finally
create an overlay group that combines those repos into one. The proxy repo
"ready-only" has to have it's own port (
18078) then the writing repo needs
it's own port (
18088) as well.
Initially I started with:
- registry.cool.terzo.org for docker pull.
- registry-write.cool.terzo.org for uploading registries.
This sucks, having to tag and and push with different host names gets's old.
Using the magic of Traefik, you can route the docker api based on the API methods.
Adding these labels to the nexus3 compose file:
labels: - traefik.docker.network=proxy - traefik.repo.port=8081 - traefik.repo.frontend.rule=Host:nexus.cool.terzo.org - traefik.repo.frontend.redirect.entryPoint=https - traefik.docker.port=18078 - traefik.docker.protocol=http - traefik.docker.frontend.rule=Host:registry.cool.terzo.org;Method:GET,HEAD - traefik.docker.frontend.redirect.entryPoint=https - traefik.docker-write.port=18088 - traefik.docker-write.protocol=http - traefik.docker-write.frontend.rule=Host:registry.cool.terzo.org;Method:PUT,DELETE,POST,PATCH - traefik.docker-write.frontend.redirect.entryPoint=https
What this does is creates 3 backends, the default, which is the standard nexus 8081
http access. You can hit
nexus.cool.terzo.org and reach the default app with SSL.
Next, I created a frontend
docker that points to nexus on 18078, the read-only port. I'm sending
HEAD methods to this port. At this point
docker pull registry.cool.terzo.org/alpine:3.7 will work. Adding the final
docker-write pointing to
PATCH methods. This allows for
docker push registry.cool.terzo.org/myspace/image:tag to work.