Skip to content

Conversation

@LaurentGoderre
Copy link
Contributor

What does this PR do?

When doing a Docker pull on an image with the default registry docker.io, the auth helper doesn't match the image to the authentication data stored by the engine under https://index.docker.io/v1 causing the error: credentials not found in native keychain

Why is it important?

This is important to support the default registry prefix.

How to test this PR

Unit test added

@LaurentGoderre LaurentGoderre requested a review from a team as a code owner November 3, 2025 15:41
@netlify
Copy link

netlify bot commented Nov 3, 2025

Deploy Preview for testcontainers-go ready!

Name Link
🔨 Latest commit bb3223a
🔍 Latest deploy log https://app.netlify.com/projects/testcontainers-go/deploys/6925837887e6660008768f54
😎 Deploy Preview https://deploy-preview-3482--testcontainers-go.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@coderabbitai
Copy link

coderabbitai bot commented Nov 3, 2025

Summary by CodeRabbit

  • Bug Fixes

    • Enhanced Docker Hub registry authentication by implementing case-insensitive normalization of Docker Hub registry aliases, ensuring consistent and reliable credential lookup regardless of registry reference format.
  • Tests

    • Added test for Docker image authentication with default registry validation.

✏️ Tip: You can customize this high-level summary in your review settings.

Walkthrough

Normalizes Docker Hub registry aliases (case-insensitive) before credential lookup and adds a test verifying default-registry authentication matching for docker.io image references.

Changes

Cohort / File(s) Summary
Registry normalization & auth lookup
docker_auth.go, internal/core/images.go
Remap Docker Hub aliases (e.g., docker.io, registry.hub.docker.com, registry-1.docker.io) to the default registry via case-insensitive checks before calling credential retrieval; preserve existing URL and fallback behavior.
Authentication tests
docker_auth_test.go
Add sub-test "match the default registry authentication by host" to verify credentials for docker.io/my/image:latest resolve to the configured default registry auth.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Caller
  participant Images as ExtractRegistry
  participant Norm as Registry Normalizer
  participant Auth as getRegistryAuth
  participant Result as Auth Result

  Client->>Images: Provide image ref ("docker.io/my/image:latest")
  Images->>Norm: Extract registry
  alt registry is docker.io / hub alias (case-insensitive)
    Norm->>Images: Return default registry (normalized)
  else other registry
    Norm->>Images: Return extracted registry
  end
  Images->>Auth: getRegistryAuth(registry)
  Auth->>Result: credentials / error
  Result-->>Client: auth (username/password/Auth) or error
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Areas to focus:
    • internal/core/images.go — verify case-insensitive comparisons and no unintended early-return side effects.
    • docker_auth.go — ensure normalization happens before all credential lookups and error handling unchanged.
    • docker_auth_test.go — confirm test coverage and determinism for defaultRegistry usage.

Poem

🐇 I nibble aliases, tidy and spry,
docker.io greets the default nearby.
Case folded, creds found without fuss,
A tiny test hops to verify us. 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'fix: docker auth for docker.io images' directly and clearly describes the main change: fixing Docker authentication for docker.io images, which matches the core objective of the PR.
Description check ✅ Passed The description explains the problem (auth helper not matching docker.io images), why it matters (supporting default registry prefix), and how to test (unit test added), all of which relate directly to the changeset.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 326fd77 and bb3223a.

📒 Files selected for processing (2)
  • docker_auth.go (2 hunks)
  • internal/core/images.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/core/images.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (15)
  • GitHub Check: lint (modules/minio) / lint: modules/minio
  • GitHub Check: lint (modules/vault) / lint: modules/vault
  • GitHub Check: lint (modules/milvus) / lint: modules/milvus
  • GitHub Check: lint (modules/nats) / lint: modules/nats
  • GitHub Check: lint (modules/chroma) / lint: modules/chroma
  • GitHub Check: lint (modules/azurite) / lint: modules/azurite
  • GitHub Check: lint (modules/dockermcpgateway) / lint: modules/dockermcpgateway
  • GitHub Check: lint (modules/meilisearch) / lint: modules/meilisearch
  • GitHub Check: lint (modules/inbucket) / lint: modules/inbucket
  • GitHub Check: lint (modules/aerospike) / lint: modules/aerospike
  • GitHub Check: lint (modules/k3s) / lint: modules/k3s
  • GitHub Check: lint (modules/azure) / lint: modules/azure
  • GitHub Check: lint (modules/elasticsearch) / lint: modules/elasticsearch
  • GitHub Check: lint (modules/gcloud) / lint: modules/gcloud
  • GitHub Check: Analyze (go)
🔇 Additional comments (1)
docker_auth.go (1)

46-51: Consolidate duplicated normalization logic—lines 46-51 partially duplicate core.ExtractRegistry behavior.

Verification confirms the original concern. After ExtractRegistry is called at line 44, the code re-normalizes the result at lines 46-51, creating partial duplication:

  • docker.io normalization (line 47) is redundant: ExtractRegistry already returns fallback for docker.io (core/images.go:104-105).
  • registry.hub.docker.com normalization (lines 48-49) creates design conflict: ExtractRegistry deliberately preserves this as an "explicit registry reference" (core/images.go:108-110), but docker_auth.go then normalizes it away for credential lookup.
  • registry-1.docker.io normalization (line 49) may be redundant: ExtractRegistry would return fallback via line 117 since it's not a URL.

Past review discussions indicated this logic should be consolidated in core.ExtractRegistry. Either remove lines 46-51 entirely and rely on ExtractRegistry, or consolidate the credential-lookup normalization into core.ExtractRegistry itself to avoid this inconsistency.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@LaurentGoderre LaurentGoderre changed the title fix docker auth for docker.io images fix: docker auth for docker.io images Nov 3, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf4458c and df49f93.

📒 Files selected for processing (2)
  • docker_auth.go (1 hunks)
  • docker_auth_test.go (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • docker_auth_test.go
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (20)
  • GitHub Check: lint (modules/dynamodb) / lint: modules/dynamodb
  • GitHub Check: lint (modulegen) / lint: modulegen
  • GitHub Check: lint (modules/dind) / lint: modules/dind
  • GitHub Check: lint (modules/registry) / lint: modules/registry
  • GitHub Check: lint (modules/dockermodelrunner) / lint: modules/dockermodelrunner
  • GitHub Check: lint (modules/postgres) / lint: modules/postgres
  • GitHub Check: lint (modules/qdrant) / lint: modules/qdrant
  • GitHub Check: lint (modules/pinecone) / lint: modules/pinecone
  • GitHub Check: lint (modules/redpanda) / lint: modules/redpanda
  • GitHub Check: lint (modules/solace) / lint: modules/solace
  • GitHub Check: lint (modules/memcached) / lint: modules/memcached
  • GitHub Check: lint (modules/openfga) / lint: modules/openfga
  • GitHub Check: lint (modules/pulsar) / lint: modules/pulsar
  • GitHub Check: lint (modules/artemis) / lint: modules/artemis
  • GitHub Check: lint (modules/influxdb) / lint: modules/influxdb
  • GitHub Check: lint (modules/rabbitmq) / lint: modules/rabbitmq
  • GitHub Check: lint (modules/dolt) / lint: modules/dolt
  • GitHub Check: lint (modules/mariadb) / lint: modules/mariadb
  • GitHub Check: lint (modules/consul) / lint: modules/consul
  • GitHub Check: Analyze (go)

docker_auth.go Outdated
Comment on lines 46 to 50
// Make comparison case-insensitive and handle both aliases
if strings.EqualFold(reg, "docker.io") || strings.EqualFold(reg, "registry.hub.docker.com") {
reg = defaultRegistry
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

question: should this be handled by core.ExtractRegistry?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It could. Up to y'all

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should live there, @mdelapenya thoughts?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, let's move it there, and once we use the go-sdk, it will be resolved and easier to replace

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 00cbc7d and 3b90c7b.

📒 Files selected for processing (2)
  • docker_auth.go (1 hunks)
  • internal/core/images.go (1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: lint (modules/artemis) / lint: modules/artemis
  • GitHub Check: lint (modules/azurite) / lint: modules/azurite
  • GitHub Check: Analyze (go)

Comment on lines 103 to 106
// Make comparison case-insensitive and handle both aliases
if strings.EqualFold(registry, "docker.io") || strings.EqualFold(registry, "registry.hub.docker.com") {
return fallback
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

Implementation correctly addresses the authentication issue.

The case-insensitive alias check properly handles both docker.io and registry.hub.docker.com, ensuring they map to the canonical registry address for credential lookup. This resolves the original issue where Docker Hub images failed authentication.

Please verify whether other Docker Hub aliases like registry-1.docker.io also require similar handling:


🏁 Script executed:

#!/bin/bash
# Description: Check if registry-1.docker.io is referenced in the codebase or tests

echo "=== Searching for registry-1.docker.io references ==="
rg -n -C3 'registry-1\.docker\.io' --type go

echo -e "\n=== Checking Docker documentation and common registry patterns ==="
# Check if there are other registry patterns in use
rg -n -C2 'docker\.io|registry.*docker' --type go -g '!*vendor*' | head -30

Length of output: 1740


🌐 Web query:

Docker registry aliases docker.io registry-1.docker.io index.docker.io registry.hub.docker.com

💡 Result:

Short answer: those hostnames are different DNS names/endpoints for Docker Hub (the Docker registry). registry-1.docker.io is the primary Docker Registry (v2) endpoint used by the Docker client; index.docker.io / index.docker.io/v1 refer to the older index/v1 API (legacy); docker.io is the short/default registry name (the client expands it to the Hub registry); hub.docker.com / registry.hub.docker.com are the web UI and related hostnames for Docker Hub. All are effectively different hostnames that point to Docker Hub’s registry services (not separate registries). [1][2][3][5]

Details (concise):

  • docker.io — the default/short registry name used by the Docker client (maps to Docker Hub). [2][3]
  • registry-1.docker.io — the Docker Hub image registry API endpoint (v2) that docker pull/push talk to. [5][2]
  • index.docker.io — legacy “index” (v1) API / historical name; seen in older tooling and some auth/token flows. Prefer registry-1.docker.io for current registry API. [1][5]
  • hub.docker.com / registry.hub.docker.com — the Docker Hub website/API-facing hostnames (web UI and related services); hub.docker.com is the site you visit in a browser. [6][1]

If you need URLs for auth/token flows or configuring container runtimes (containerd, etc.), use registry-1.docker.io as the registry endpoint. [5][7]

Sources:
[1] Docker Docs — What is a registry? (Docker Hub is the default registry).
[2] Blog / documentation notes on docker.io / registry hostnames.
[3] StackOverflow and community answers describing registry-1.docker.io vs index.docker.io.
[5] StackOverflow / how-to answers recommending registry-1.docker.io for v2 API.


Add missing Docker Hub registry aliases: registry-1.docker.io and index.docker.io

The current implementation only handles docker.io and registry.hub.docker.com, but is missing the primary Docker Registry v2 endpoint registry-1.docker.io (used by docker pull/push and other registry operations) and the legacy index.docker.io (v1 API). Without these aliases, image authentication will fail when users reference these endpoints directly.

Update the alias check to include:

  • registry-1.docker.io (primary v2 registry endpoint)
  • index.docker.io (legacy v1 API, for compatibility)
🤖 Prompt for AI Agents
In internal/core/images.go around lines 103 to 106, the registry alias check
only handles "docker.io" and "registry.hub.docker.com" but must also treat
"registry-1.docker.io" and "index.docker.io" as Docker Hub aliases; update the
conditional to include those two values (using the same case-insensitive
EqualFold checks or consolidating into a small list/set and checking membership)
so the function returns the fallback for any of the four recognized Docker Hub
registry names.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants