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.

FeatureGitLabGitHub
PhilosophyAll-in-one DevOps platformRepository-centric, with a strong ecosystem
CI/CD ToolGitLab CI/CD (Built-in)GitHub Actions (Add-on service)
Configuration.gitlab-ci.yml file.github/workflows/*.yml files
Container RegistryNative part of every projectPart of GitHub Packages service
Login in CI/CDAutomated with pre-defined variablesContainer registry needs explicit docker login with access token in a different scope from Actions’ default token
Key AdvantageSeamless integration, unified experienceExtensibility, large marketplace, modularity
Best ForTeams seeking a single, integrated platformUsers 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.

  1. A developer creates a new feature branch and adds a Dockerfile to the project’s repository.
  2. 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.
  3. 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.
  4. Another team member can then pull this image using the same registry path, confident that it’s the latest version from the main branch.
  5. 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

  1. A developer adds a Dockerfile and a .github/workflows/docker.yml file to the project’s repository.
  2. The docker.yml file defines a workflow that triggers on a push to the main branch. This workflow uses a sequence of marketplace actions:
    • docker/login-action to authenticate with the registry using a GITHUB_TOKEN.
    • docker/build-push-action to build and push the image to ghcr.io/your_username/your_project:latest.
  3. The developer pushes their code, and GitHub Actions runs the workflow.
  4. 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.

RegistryPriceKey Features
HarborFree (self-hosted)Secure, on-premise. Vulnerability scanning (Clair), content trust, replication
JFrog ArtifactoryFree tier availableUniversal package management, advanced metadata tracking, security scanning
CloudsmithFree tier availableUniversal 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!

FeatureDocker HubGitLabGitHubOCI
Private Repos1UnlimitedUnlimitedUnlimited
Free Storage500 MB10 GiB per project (Git repo/LFS) + uncapped Container registry storage500 MB (for private repositories)10 GB Always Free Object Storage
CollaboratorsNoYes. Can assign different roles (e.g., Guest, Reporter, Developer, Maintainer, Owner) to control their access.YesYes with Identity management configuration
Pull Limits200 pulls/6h (auth)None1 GiB/month (external)None
Ideal ForPersonal projects, public imagesMonorepos, microservicesProjects with GitHub ActionsLong-term projects, general use
Key ProSimplicity, ease of useCI/CD Integration, uncapped registry storageActions Integration, centralized dev“Always Free” tier
Key ConStrict pull limits, limited private reposRequires a GitLab projectLimited storageComplex initial setup