When I started playing with Kubernetes a few months ago, there was one question that didn't seem to have a clear answer: Where do I store the images that will be running in Kubernetes?
Most of the documentation and examples are for deploying ready-made services like nginx or MariaDB. The services tend to be open source with images publicly available on Docker Hub. But sooner or later you're going to want to build a custom image and deploy it. You will also likely not want to publicly share all your images for anyone to find and download.
Requirements
My requirements for a Docker registry were pretty simple:
- Privacy
- Pricing
In more detail:
Privacy
https://hub.docker.com is the most popular Docker registry. It offers free public registries, however I decided early on that this wasn't a good option for me. Although most of my projects are open source, some are either private or not ready to be public, so I wouldn't want to make all my docker images public.
Pricing
For pricing, my view is that a registry is simply a place where you upload docker images and download them later. I'm building the images locally on my own machine, so there's no significant compute cost to the registry. For this reason, a registry is basically a specialized type of storage.
I would therefore expect the pricing of a registry service to be based on the amount of storage and upload/download bandwidth that I consume. Moreover, I would also expect the cost to be comparable to other types of cloud storage solutions, such as Amazon's S3 or Microsoft's Blob Storage. In other words, I would expect the service to cost a few cents (USD) per GB per month.
Exploring the Options
I did a little research and narrowed things down to the following options:
- Running my own registry server
- Upgrade to a Docker Hub paid plan
- Microsoft's Container Registry Service
- Amazon's Elastic Container Registry Service
I quickly decided against setting up my own registry. It might be fun to learn, but it would also probably be quite time-consuming. I'm also sure a paid service will be more reliable than anything I run myself.
Docker Hub offers 5 private repos for $7 a month. The plan includes an autobuild service, which makes that price very reasonable. However, I wasn't planning on using an autobuild service. I would also probably be needing 7 or 8 repositories, which would force me into a higher tier.
Looking at Microsoft's offering, the plan made a little more sense for my needs. The basic plan starts at around $5 a month for 10GB of storage, and you pay extra per GB if you go over that. This was closer to what I wasn looking for. As with Docker Hub, ACR offers some automated build features through ACR Tasks.
Finally, there's Amazon's solution. As far as I can tell, this service doesn't offer any of the additional build features that the other two do. It focuses only on securely storing and serving your images, and I assume leaves it up to you to integrate third-party build automation if you need that feature.
Amazon ECR's pricing is simple. You can create as many repositories as you like. You only pay per GB for the storage and bandwidth you use. In my case, it will cost me less than $1 a month. For these reasons, I decided to use Amazon's service.
Next Steps
I've been using Amazon ECR to deploy my Docker images for a few weeks now and so far it works great. There were a few tricks to get everything working smoothly. I'll write more about that experience in another post.
Whenever I want to update a docker image, I run the build and upload to the repo from my local machine. I then trigger a deployment update in Kubernetes. This works fine for small projects like this blog, but it's not really in line with best practices.
I will eventually look into CI/CD solutions for my deployments. At that point, it might be time to revisit the Docker and Microsoft options to see if they make more sense.