KINTO Tech Blog
CI/CD

Migrating from Docker Hub to ECR Public Gallery

Cover Image for Migrating from Docker Hub to ECR Public Gallery

Self-Introduction

Hi, I'm Tetsu. I joined KTC in March 2025. I worked as an infrastructure engineer handling both on-premises and cloud environments. At KTC, I've joined the team as a platform engineer.

I'm a big fan of travel and nature, so I usually head out somewhere far during long holidays.

Overview

In this article, I’ll walk you through how to update your GitHub Actions workflow to pull public container images—such as JDK, Go, or nginx, from the ECR Public Gallery instead of Docker Hub.

Starting April 1, 2025, Docker Hub will tighten the rules on pulling public container images for unauthenticated users. More specifically, unauthenticated users will be limited to 10 image pulls per hour per source IP address. Learn more here.

The virtual machines that run GitHub Actions workflows are shared across all users, which means Docker Hub sees only a limited set of source IP addresses. Because of this, the above limits became a bottleneck when building containers with GitHub Actions, so we'll need to find a workaround.

Prerequisites

At our company, we used GitHub Actions with the following configuration to automate container builds (this is a roughly abstracted configuration).

Diagram

Considering Countermeasures

We explored a few ways to deal with the Docker Hub pull limit.

Using a Personal Access Token (PAT) to Log In to Docker Hub and Pull

You might be thinking, "Why not just authenticate with Docker Hub in the first place?" Fair point. You can generate a Docker Hub PAT and use it in your GitHub Actions workflow with docker login to authenticate. That way, you can get around the pull limit.

Just keep in mind, PATs are tied to individual users. Since our team shares GitHub Actions workflows, linking tokens to individual users isn’t ideal from a license management standpoint.

Log in to Docker Hub with your Organization Access Token (OAT) and pull

It's basically the same method as above, but the key difference is that you're authenticating with a shared token tied to your OAT.

To use this shared token, you'll need a Docker Desktop license for either the Team or Business plan.

Migrating to GitHub Container Registry (GHCR)

Here, I'll cover how to pull container images from GitHub Container Registry (GHCR), which is provided by GitHub. By using {{ secrets.GITHUB_TOKEN }} in your GitHub Actions workflow, you can authenticate and pull container images. That said, searching for images can be a bit tricky, especially if you're trying to compare versions with what's available on Docker Hub.

Here's how you can pull container images from the ECR Public Gallery provided by AWS. Restrictions differ depending on whether you use IAM to authenticate with ECR Public Gallery, but it's basically free to use.

For unauthenticated users, the following limits apply per source IP address when using the ECR Public Gallery:

  • 1 pull per second
  • 500GB of pulls per month

On the other hand, authenticated users are subject to the following restrictions on an account-by-account basis.

  • 10 pulls per second
  • Transfers over 5TB/month are charged at $0.09 per GB (the first 5TB is free)

You can find more details in the official documentation below.
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/public/public-service-quotas.html

https://aws.amazon.com/jp/ecr/pricing/

If you are not using an AWS account, data transferred from a public repository is restricted based on the source IP.

The ECR Public Gallery includes official Docker images, which are equivalent to those on Docker Hub. That makes it easier to use in practice and simplifies the migration process.

Case Comparison

I reviewed the proposals above and evaluated them based on QCD. Here's the comparison table:

Proposals Quality Cost Delivery
Log in to Docker Hub using PAT ×
- Relies on personal tokens, which isn't ideal for organizations
- No change in convenience from the current setup
〇 No additional cost 〇 Easy to implement with less workload
Log in to Docker Hub using OAT ○ No change from the current setup × License costs increase depending on the number of users × License changes take time to process
Transition to GHCR △ Hard to find equivalent images currently used on Docker Hub 〇 No additional cost 〇 Easy to implement with less workload
Transition to ECR Public Gallery 〇 Easy to find matching currently used on Docker Hub 〇 No additional cost 〇 Easy to implement with less workload
  • One advantage of using PAT or OAT is that it keeps things as convenient as they are now.
  • GHCR can be easily set up using GitHub's {{ secrets.GITHUB_TOKEN }}, but it's harder to search for container images compared to ECR Public Gallery.
  • ECR Public Gallery requires some IAM policy changes, but since they're minor, the extra workload is minimal.

Based on these points, we decided to go with the plan of "migrating to ECR Public Gallery," as it's low-workload, cost-free, and offers good usability.

Note: Depending on your environment or organization, this option may not always be the best fit.

Settings for Migrating to ECR Public Gallery

To migrate, you'll need to update the container image source, set up the YAML file for the GitHub Actions workflow, and configure AWS accordingly.

Diagram

Diagram

Fixing the Container Image Source

Searching for Container Images

In most cases, you probably define where to pull container images from in files like your Dockerfile or docker-compose.yml. This time, we'll walk through how to migrate the source of a JDK container image from Docker Hub to ECR Public Gallery using a Dockerfile.

Let's say your Dockerfile includes a FROM clause like this:

FROM eclipse-temurin:17.0.12_7-jdk-alpine

Search here to check if the image is available on ECR Public Gallery. In this case, search for the official Docker Hub image like eclipse-temurinbefore the ":" and pick the one labeled "by Docker."

image_tag1

Select "image tags" to display the image list.

image_tag2

Type the tag of the official Docker Hub image (in this case, 17.0.12_7-jdk-alpine) into the image tags search field to find the image you're looking for. Then copy the "Image URI".

image_tag3

Fixing the Container Image Source

Paste the modified container image URI into the FROM line.

In this case, the updated URI looks like the example below (note the addition of public.ecr.aws/docker/library/ compared to the original).

FROM public.ecr.aws/docker/library/eclipse-temurin:17.0.12_7-jdk-alpine

With this change, your setup will now pull images from ECR Public Gallery.

AWS Configuration

To pull from ECR Public Gallery while authenticated, you'll need to set up an IAM role and policy.

IAM Role

You can follow the steps in GitHub's official documentation for this.
https://docs.github.com/ja/actions/security-for-github-actions/security-hardening-your-deployments/configuring-openid-connect-in-amazon-web-services

Start by setting up the identity provider, then create the IAM role.

IAM Policy

Create an IAM policy that allows the action to pull from the ECR Public Gallery. I referred to the following docs for this:
https://docs.aws.amazon.com/ja_jp/AmazonECR/latest/public/docker-pull-ecr-image.html

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Sid": "GetAuthorizationToken",
      "Effect": "Allow",
      "Action": [
        "ecr-public:GetAuthorizationToken",
        "sts:GetServiceBearerToken"
      ],
      "Resource": "*"
    }
  ]
}

Attach this IAM policy to the IAM role you created above.

To log in to the ECR Public Gallery with authentication, add a login process to the YAML file that defines the Github Actions workflow.

In our setup, we add the following before the Docker Build step.

    ## ECR Public Galleryへログイン
    - name: Login to ECR Public Gallery
      id: login-ecr-public
      run: |
        aws ecr-public get-login-password --region us-east-1 | docker login --username AWS --password-stdin public.ecr.aws

*Since the ECR Public Gallery is located in the us-east-1 region, make sure to explicitly set --region us-east-1.

Conclusion

In this article, we walked through how to set up your GitHub Actions workflow to pull public container images (like JDK, Go, nginx, etc.) from the ECR Public Gallery instead of Docker Hub.

Hope this helps with your development and daily tasks!

Facebook

関連記事 | Related Posts

We are hiring!

【DBRE】DBRE G/東京・名古屋・大阪・福岡

DBREグループについてKINTO テクノロジーズにおける DBRE は横断組織です。自分たちのアウトプットがビジネスに反映されることによって価値提供されます。

【クラウドエンジニア】Cloud Infrastructure G/東京・大阪・福岡

KINTO Tech BlogWantedlyストーリーCloud InfrastructureグループについてAWSを主としたクラウドインフラの設計、構築、運用を主に担当しています。

イベント情報