Working in a side project with a small team often poses resource and cost challenges. My goal is to have collaboration capability for managing code and build on a stable and secure platform with reasonable storage limit, while limiting cost. When I started containerizing my apps, my first natural choice was building with Docker CLI and pushing to Docker Hub for storage. However, the free plan’s limit on 1 private repo and no collaborator quickly starts to be a limiting factor. Some users online propose using tags to differentiate projects (e.g., user/myprojects:projN), but that really defeats the purpose of incremental build and using tags for pure versioning and arch. Thus began my journey to explore other free Docker container registries.
This post will explore 4 types of container registries and how they fit my scenario:
- pure container registries
- tight integration with devops workflow: Github vs Gitlab
- cloud platforms: AWS, Azure, GCP, Oracle
- self-hosted & universal repositories
While all of them offer the same basic feature of storing and distributing Docker images, they each have unique advantages, limitations, and use cases.
TL;DR: After comparing options, I have finally chosen Gitlab due to its free plan’s high limit on storage , repo and collaboration (For comparison, I would need the $16/user/month Docker Team plan to achieve something similar, or at least the $4/user/month Github team plan for a smaller storage). Most importantly, its full integration with Git repository management means that my team can continuously deploy and build code/images in the same platform without setting up and switching between services.
Pure container registry
Docker Hub
Docker Hub is the original and most widely used public registry with a huge library of public images. It’s the default for the docker
CLI, making it the most straightforward to use.
Pros:
- Build automation: Integrates with GitHub and Bitbucket for automated image builds on every code push.
Cons:
- Low pull limits: Free accounts have strict pull rate limits (e.g., 100 pulls per 6 hours for unauthenticated users and 200 for authenticated users).
- Only 1 private repositories: Free accounts are limited to a single private repository with only 500 MB storage , which can be restrictive for projects requiring multiple images.
Red Hat Quay.io
Quay.io focuses heavily on security and image vulnerability scanning.
Pros:
- Robust security: Offers built-in vulnerability scanning (via Clair) for free, which is a significant value-add for security-conscious users.
- Time-based retenion: Allows for granular image retention policies.
Cons:
- Quay.io’s free tier has no private repository, which is a major drawback. Paid plan starts at $15/month.
DevOps integration: Github & Gitlab
Both GitLab and GitHub provide an integrated experience for the entire workflow from code to image within a single platform. If your code repository is already there, the integration is seamless and requires minimal configuration. Using built-in CI/CD variables like $CI_REGISTRY_IMAGE
in GitLab or pre-made GitHub Actions makes building and pushing images simple and reproducible.
The performance is optimized for the developer workflow, and latency is typically not an issue for most projects. However, they may not offer the same level of global distribution and network optimization as a dedicated cloud provider.
Feature | GitLab | GitHub |
---|---|---|
Philosophy | All-in-one DevOps platform | Repository-centric, with a strong ecosystem |
CI/CD Tool | GitLab CI/CD (Built-in) | GitHub Actions (Add-on service) |
Configuration | .gitlab-ci.yml file | .github/workflows/*.yml files |
Container Registry | Native part of every project | Part of GitHub Packages service |
Login in CI/CD | Automated with pre-defined variables | Container registry needs explicit docker login with access token in a different scope from Actions’ default token |
Key Advantage | Seamless integration, unified experience | Extensibility, large marketplace, modularity |
Best For | Teams seeking a single, integrated platform | Users already in the GitHub ecosystem or who prefer a modular approach |
GitLab Container Registry
GitLab offers a fully integrated solution, combining a project-based Git repository for code, CI/CD pipeline to automate builds and deployments, issue tracker to manage tasks, and container registry in a single platform. The Container Registry is a core, native part of a GitLab project.
- Integrated DevOps platform: No need to link separate tools like Trello for project management or Jenkins for CI/CD. You can see your code, merge requests, CI/CD pipeline, and container images all from a single interface, providing a unified view of a project’s entire lifecycle. The image path is automatically configured, and login credentials are provided through pre-defined variables, making the build-push process painless.
- Generous free tier: GitLab’s free plan is extremely generous with
- unlimited number of private repositories, each with its own container registry.
- unlimited collaborators
- large storage: The free tier provides 10 GiB of storage for the Git repository, but the container registry, package registry, and build artifacts are not included in this limit.
- No unexpected costs : Unlike cloud providers (AWS, Azure, GCP) that use a pay-per-use model, GitLab’s free tier has clear and predictable limits.
- Build-in project management tools
Workflow
A small team developing a microservices architecture can use GitLab to host their code, run CI/CD jobs to build and push images to the registry, and deploy them. Each microservice gets its own project and its own registry.
- A developer creates a new feature branch and adds a
Dockerfile
to the project’s repository. - They define a CI/CD job in the
.gitlab-ci.yml
file at the root of the project. This file defines the entire build, push, and deployment pipeline for both code and images, and triggers on every push to a branch. Variables like$CI_REGISTRY_IMAGE
and$CI_REGISTRY_PASSWORD
automatically provide the correct paths and credentials, making the pipeline script clean and simple. - The developer pushes their code. GitLab’s CI/CD pipeline automatically runs, builds the image, and pushes it to
registry.gitlab.com/your_group/your_project/your_app:latest
. - Another team member can then pull this image using the same registry path, confident that it’s the latest version from the main branch.
- GitLab can automatically detect references to issue tickets in branch names or commit messages. When a developer creates a merge request, GitLab scans for these references and links the request to the corresponding issue ticket on the board. This feature not only saves time but also ensures that every code change is accounted for and can be traced back to a specific task or requirement.
GitHub Packages Container Registry
GitHub’s registry is part of its separate GitHub Packages service and is tightly integrated with GitHub Actions. Like Gitlab, it keeps code, CI/CD, and packages all in one place.
- Pros:
- GitHub Actions integration: Like GitLab, it’s a great choice if your CI/CD pipelines are built with GitHub Actions,.
- Granular build control: You can have multiple
.github/workflows
files, each for a different, specific task. For example, one workflow for building the image and another for deployment, triggered by different events. - Marketplace modularity: The GitHub Actions Marketplace has thousands of pre-built actions for everything from building and pushing Docker images to deploying to a specific cloud provider. This modular approach makes it easy to assemble a pipeline using existing tools.
- Easy collaboration: Leverages GitHub’s native collaboration and permission models.
- Cons:
- Low storage limits: The free tier only offers 500 MB of total storage for private packages including images.
- Limited free data transfer: Only 1 GiB data transfer per month for private repositories (unmetered from GitHub Actions).
My Verdict
GitHub is a very natural choice for a lot of developers, but its free plan is a bit more restrictive. While you get unlimited private repositories and collaborators, its GitHub Packages service (which includes the container registry) has a 500 MB storage limit and limited data transfer . For Docker images, this can be quickly used up, forcing you to manage your image sizes carefully or upgrade to a paid plan.
Workflow
- A developer adds a
Dockerfile
and a.github/workflows/docker.yml
file to the project’s repository. - The
docker.yml
file defines a workflow that triggers on apush
to the main branch. This workflow uses a sequence of marketplace actions:docker/login-action
to authenticate with the registry using aGITHUB_TOKEN
.docker/build-push-action
to build and push the image toghcr.io/your_username/your_project:latest
.
- The developer pushes their code, and GitHub Actions runs the workflow.
- Once the job completes, the image is available in the GitHub Packages Container Registry. Team members can pull it after logging in with a Personal Access Token or by using the
GITHUB_TOKEN
in a different workflow.
Cloud platforms
When comparing container registries from cloud providers like Oracle, Azure, AWS, and GCP with those from software development platforms like GitHub and GitLab, the primary difference lies in their ecosystem integration and pricing models. The cloud providers’ registries are deeply integrated with their respective cloud services, while GitHub and GitLab’s are tightly coupled with their source code management and CI/CD tools.
Price: Cloud providers’ pricing is typically based on pay-per-use models, charging for storage per GB per month and for data transfer (egress). While they have free tiers, they are usually trial-limited. This can get expensive for large-scale, high-traffic applications.
- Oracle’s OCI is a notable exception with its “Always Free” tier, offering a generous amount of free storage and data transfer, making it very cost-effective for personal or small-scale projects.
Performance: Offer high-performance, globally distributed registries that are optimized for their own cloud ecosystems. Pulling images from a registry in the same region as your compute service (e.g., an AWS ECR image to an AWS EC2 instance) is incredibly fast and has no data transfer costs. However, cross-region pulls can incur latency and cost.
Ease of Use & Integration: They can be more complex to set up if you’re using a different CI/CD tool. You’ll need to configure external credentials, IAM roles, and access policies. However, within their own cloud, the integration is very good. For instance, AWS ECR integrates smoothly with AWS CodeBuild, and Azure Container Registry works well with Azure DevOps and Azure Pipelines.
Oracle Container Registry
Oracle Cloud Infrastructure (OCI)’s registry is part of its “Always Free” tier, which offers a set of services that are free for life. The only con is the lengthy signup process for the entire OCI platform, which can be more complex than signing up for a specialized registry service.
- ““Always Free” tier: Provides a truly free and permanent solution without time-based trial limits. This peace of mind is extremely beneficial for small teams who are in the exploratory phase of product development.
- High availability: The registry is distributed and highly available.
- No pull limits: OCI does not have pull rate limits, making it suitable for high-traffic scenarios.
- High storage limit: The free tier offers a 10GB object storage that can be used with the Container Registry for storing images. There’s also a quota of 500 repositories per region, and 500 images per repository.
My Verdict
While cloud providers offer free tiers for their container registries, their pricing models are more complex, and the free tiers have limits that can be exceeded if not monitored carefully. For a small team, the overhead of managing cloud infrastructure and worrying about costs is not ideal.
Oracle’s “Always Free” tier is an excellent option for hosting services, but lacks the integrated project management and CI/CD features that GitLab and GitHub provide out of the box. You’d have to manually connect your code repository to OCI’s Container Registry and other cloud services, which adds unnecessary complexity.
Self-hosted & Universal repositories
Self hosting gives you full control over your data and infrastructure, but you’re responsible for managing them. There are also several other contenders that are designed to manage all types of software artifacts, not just container images.
Registry | Price | Key Features |
---|---|---|
Harbor | Free (self-hosted) | Secure, on-premise. Vulnerability scanning (Clair), content trust, replication |
JFrog Artifactory | Free tier available | Universal package management, advanced metadata tracking, security scanning |
Cloudsmith | Free tier available | Universal package management, global distribution, zero-trust security |
Harbor is a popular, open-source container registry that provides robust features for securing and managing artifacts. It’s a great choice for teams that want a private, on-premises solution with features like vulnerability scanning, content signing, and image replication. Since it’s self-hosted, it’s free to use, but you need to manage and pay for the infrastructure.
JFrog Artifactory: A powerful, enterprise-grade universal artifact repository. It can handle all major package types and is often used by large organizations to manage their entire software supply chain.
Cloudsmith : A cloud-native universal package manager that supports a wide range of formats, including Docker. It’s known for its ease of use, global distribution, and strong security features. It offers a free tier for a single user with 500MB of storage, and has a focus on a “Zero Trust” model for managing access to your software assets.
Comparing candidates
To reduce complexity, I have narrowed down my platform choice with the following criteria
- easy to signup, setup and manage, which rules out most cloud providers and self-hosted options
- allows collaboration
- offers >1 private repos
- high storage limit
- low and fixed cost. The latter part also rules out most cloud providers with pay-as-you-go model
The following table lists major attributes of each candidate. It is not difficult to see why I picked Gitlab as my choice!
Feature | Docker Hub | GitLab | GitHub | OCI |
---|---|---|---|---|
Private Repos | 1 | Unlimited | Unlimited | Unlimited |
Free Storage | 500 MB | 10 GiB per project (Git repo/LFS) + uncapped Container registry storage | 500 MB (for private repositories) | 10 GB Always Free Object Storage |
Collaborators | No | Yes. Can assign different roles (e.g., Guest, Reporter, Developer, Maintainer, Owner) to control their access. | Yes | Yes with Identity management configuration |
Pull Limits | 200 pulls/6h (auth) | None | 1 GiB/month (external) | None |
Ideal For | Personal projects, public images | Monorepos, microservices | Projects with GitHub Actions | Long-term projects, general use |
Key Pro | Simplicity, ease of use | CI/CD Integration, uncapped registry storage | Actions Integration, centralized dev | “Always Free” tier |
Key Con | Strict pull limits, limited private repos | Requires a GitLab project | Limited storage | Complex initial setup |
Comments