UPDATE: With January 1st, 2017 we rebranded our hosted CI Platform for Docker from “Jet” to what is now known as “Codeship Pro”. Please be aware that the name “Jet” is only being used four our local development CLI tool. The Jet CLI is used to locally debug and test builds for Codeship Pro, as well as to assist with several important tasks like encrypting secure credentials.
So you're using Docker now. You even built an image. Now what do you do? Chances are you are going to want to use that image somewhere. So then how do you share that image with a teammate or get that image onto a machine somewhere else where it can actually run? This is where registries come into play.
What Is a Docker Registry?
A Docker registry is a place to store and distribute Docker images. It serves as a target for your
docker push and
docker pull commands. Before we get any further, let's cover some of the basic terminology related to Docker registries.
An image is essentially a template for Docker containers. It consists of a manifest and an associated series of layers.
A layer represents a filesystem difference. An image's layers are combined together into a single image that forms the base for a container’s filesystem.
A registry is a content delivery and storage system for named Docker images. It can be thought of as a collection of repositories keyed by name.
A repository is simply a collection of different versions for a single Docker image. In this way, you can think of it as being similar to a git repository. For example, the official Ubuntu repository has a description of what is in the image as well as a list of the available versions.
A tag is just a named version of the image. It allows you to identify a specific image later on. You can tag an image (almost) however you want. However, it's probably best to give it a meaningful, human-readable name that can be easily referenced later.
All right, now that we have that down, let's get into the more interesting stuff.
Why Do I Need a Docker Registry?
Imagine a workflow where you push a commit that triggers a build on your CI provider which in turn pushes a new image into your registry. Your registry can then fire off a webhook and trigger a deployment. All without a human having to step and manually do anything. Registries make a fully automated workflow like this much easier.
As the previous example demonstrates, you will likely want to have a private registry for storing your proprietary images. A public registry such as the one on Docker Hub is hugely helpful for publicly available and open-source images. However, for your company's private images, a private registry is what you need.
The question then is: hosted or self-hosted?
The decision to host your own private registry or to go with a hosted option is much like any other question of building it yourself versus outsourcing to a third party. Price, control, flexibility and maintenance all come into play. Instead of rehashing these arguments though, let's instead just run through what your options are.
Quay is a hosted Docker registry from CoreOS that sells itself as having "powerful build triggers," "advanced team permissions," and "secure storage." They are probably one of the more enterprise-friendly options out there, offering fine-grained permission controls.
They support any git server and let you build advanced workflows by doing things like mapping git branches to Docker tags so that when you commit code it automatically builds a corresponding image.
Quay offers unlimited free public repositories. Otherwise, you pay by the number of private repositories. There's no extra charge for storage or bandwidth.
Docker Hub is the Docker's own registry offering. Like Quay, they offer unlimited free public repositories and don't charge for storage or bandwidth. If you need private repositories, they charge based on the number you need and how many parallel builds you can have.
Docker Hub doesn't offer the fine-grained permissions that Quay does, which may be an issue for more enterprise-level shops. Docker Hub also has more limited git integration, requiring that your code live on GitHub or Bitbucket if you want to take advantage of the automated builds.
It's worth noting that Docker Hub is the default registry used when you
docker push or
docker pull. Regardless of whether you choose to use Docker Hub for you're private images, you will almost certainly be interacting with it, as most base images will be stored there.
AWS EC2 Container Registry (ECR)
Amazon's ECR is a relatively new option that makes a lot of sense if you are making heavy use of other AWS offerings such as their Elastic Container Service. It can be used like any other Docker registry, but you'll likely get the most benefit out of it within the AWS ecosystem. As with most other AWS products, ECR offers very fine-grained permissions and access control.
One important thing to note is that ECR's pricing model is very different from Quay and Docker Hub. Instead of charging based on the number of private repositories, they charge strictly based on storage and bandwidth.
Google Container Registry
Google's Container Registry is much like Amazon's ECR in that it can be used as a generic Docker registry. You'll likely get the most benefit if you are already using Google Cloud Platform.
Pricing is similar to ECR where you only pay for storage and network egress. Ultimately, your images are stored in Google Cloud Storage. Security is taken very seriously, but the workflow support is lacking a little bit currently. If you are looking to set up sophisticated, automated workflows with your Docker registry, you may want to look elsewhere.
The hosted options above are an easy way to get started. Docker Hub in particular is great for pulling down prebuilt images without needing to configure anything yourself.
However, if you need more control over how and where your images are stored or more flexibility into how your images are distributed, you might want to look into hosting your own registry. The easiest way to do this is by making use of [Docker Distribution].
Distribution is Docker's open-source registry implementation. It supports V2 of the Docker Registry HTTP API and supersedes the older Docker Registry. Distribution will likely serve as the basis for any custom registry you would want to deploy.
Deploying Distribution is extremely simple. The hardest part tends to be picking a storage backend. By default, the registry data is stored in a Docker volume on the host filesystem, but you will usually want to use a different option for scalability, redundancy, and availability reasons.
Distribution provides storage drivers for S3, Google Cloud Storage, and Azure Blob Storage, among others. There is also a well-documented storage driver API if you would like to implement your own.
Distribution has support for almost everything you'll want, out of the box. There is native support for TLS and basic authentication as well as robust webhook notifications. You can set up endpoints to be notified any time a manifest or layer is pushed or pulled. This is crucial for setting up automated workflows.
Where To Go From Here
We've covered where Docker registries fit in the picture and why you you likely need them in your Docker workflow. There are plenty of hosted registry providers out there like Quay and Docker Hub if you prefer to offload the maintenance work to someone else in exchange for a little less flexibility.
On the other hand, if you have requirements that make a registry-as-a-service a less attractive option, Docker Distribution makes rolling your own a much simpler proposition. If you'd like to see a more detailed rundown on actually rolling your own private registry with Docker Distribution, check out Jeff Nickoloff's great post.
For an even more through look at rolling your own registry with Distribution, check out the Codeship ebook "Running a Private Docker Registry on Amazon EC2". You can also have a look at Codeship's Documentation article on pushing to remote Docker registries with their hosted CI service for Docker: Codeship Jet.