Skip to content

Conversation

@DC-Shi
Copy link

@DC-Shi DC-Shi commented Oct 17, 2025

Fix the auth issue, the format should be username and password(token) combination:

base64({"username": username,"password": password,}))

The docker config.json gives base64(username:password) so you need manually to make this.

Summary by Sourcery

Fix NIM image pull authentication by reading Docker credentials and formatting them correctly, with a fallback to environment-based API key and enhanced diagnostics.

Bug Fixes:

  • Fix authentication for pulling NIM images from nvcr.io by using username/password JSON format instead of raw base64 string.

Enhancements:

  • Add getDockerAuth helper to parse Docker config.json and retrieve registry credentials.
  • Use stored Docker credentials to set RegistryAuth in pullNIMImage and decode them from base64.
  • Fallback to NGC_API_KEY environment variable as OAuth token when no Docker credentials are found.
  • Add debug logs and warnings for missing credentials and improved error messages on auth failures.

ericcurtin and others added 2 commits October 14, 2025 12:32
- Add detection for NVIDIA NIM images (nvcr.io/nim/ prefix)
- Create NIM-specific container lifecycle management
- Configure NIM containers with GPU support, shared memory, and NGC API key
- Proxy chat requests to NIM container's OpenAI-compatible API
- Add tests for NIM detection and container naming
- Support both single prompt and interactive chat modes for NIM
- Add comprehensive NIM support documentation to README
- Improve user feedback for NIM initialization status
- Add GPU detection status messages
- Improve timeout error message with troubleshooting tip

Signed-off-by: Eric Curtin <eric.curtin@docker.com>
Copilot AI review requested due to automatic review settings October 17, 2025 10:27
@sourcery-ai
Copy link
Contributor

sourcery-ai bot commented Oct 17, 2025

Reviewer's Guide

This PR enhances the NIM image pull command by extracting Docker credentials from ~/.docker/config.json, reformatting them into the required {username,password} JSON token, adding debug output, and falling back to the NGC_API_KEY if no Docker login is found.

Sequence diagram for NIM image pull authentication flow

sequenceDiagram
    actor User
    participant CLI
    participant DockerClient
    participant DockerConfig
    participant Registry

    User->>CLI: Initiate NIM image pull
    CLI->>DockerConfig: Retrieve auth for nvcr.io
    alt Auth found in Docker config
        DockerConfig-->>CLI: Return base64(username:password)
        CLI->>CLI: Decode and reformat to {username, password} JSON
        CLI->>DockerClient: Pull image with RegistryAuth
    else No auth found
        CLI->>CLI: Check NGC_API_KEY env var
        alt NGC_API_KEY present
            CLI->>CLI: Create auth with $oauthtoken:NGC_API_KEY
            CLI->>DockerClient: Pull image with RegistryAuth
        else NGC_API_KEY not present
            CLI->>DockerClient: Pull image without auth
        end
    end
    DockerClient->>Registry: Request image pull
    Registry-->>DockerClient: Respond (success or error)
    DockerClient-->>CLI: Return result
    CLI-->>User: Show result
Loading

Class diagram for updated NIM image pull authentication logic

classDiagram
    class NIMImagePuller {
        +pullNIMImage(ctx, dockerClient, model, cmd) error
        +nimContainerName(model string) string
        +isNIMImage(model string) bool
    }
    class DockerConfig {
        +getDockerAuth(registry string) (string, error)
    }
    NIMImagePuller --|> DockerConfig : uses
    NIMImagePuller o-- DockerClient : dockerClient
    NIMImagePuller o-- cmd : cmd
    DockerConfig : Auths map[string]{Auth string}
    DockerConfig : CredHelpers map[string]string
    DockerConfig : config.json
    DockerConfig : getDockerAuth(registry string)
    NIMImagePuller : pullNIMImage(ctx, dockerClient, model, cmd)
    NIMImagePuller : nimContainerName(model string)
    NIMImagePuller : isNIMImage(model string)
    DockerClient : ImagePull(ctx, model, options)
    NIMImagePuller ..> DockerClient : calls ImagePull
Loading

File-Level Changes

Change Details Files
Introduce getDockerAuth to read and parse Docker config.json for registry credentials
  • Detect DOCKER_CONFIG env or default to ~/.docker
  • Load and unmarshal config.json into Auths structure
  • Return base64 auth string when present, or empty otherwise
cmd/cli/commands/nim.go
Enhance pullNIMImage to use structured auth and fallback to NGC_API_KEY
  • Print debug messages around registry lookup and config entries
  • Call getDockerAuth and decode base64 to username/password
  • Re-encode credentials as base64 of JSON {username,password}
  • Use NGC_API_KEY as fallback when Docker auth is missing
  • Improve error messaging for authentication failures
cmd/cli/commands/nim.go

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@gemini-code-assist
Copy link
Contributor

Summary of Changes

Hello @DC-Shi, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request addresses a critical authentication problem encountered when attempting to download NIM images from nvcr.io. It introduces robust logic to automatically retrieve and correctly format authentication credentials from the user's Docker configuration or, as a fallback, utilize an NGC_API_KEY environment variable, ensuring seamless and authenticated image pulling. The changes streamline the process for users and provide clearer guidance in case of authentication failures.

Highlights

  • Docker Authentication Retrieval: Introduced a new function, getDockerAuth, to programmatically read and parse authentication credentials for specific registries from the user's Docker config.json file.
  • NIM Image Pull Authentication Fix: Resolved an authentication issue when pulling NIM images from nvcr.io by correctly reformatting the Docker auth string (typically base64(username:password)) into the base64({"username": username,"password": password,}) JSON format required by the registry.
  • NGC API Key Fallback: Implemented a fallback mechanism to use the NGC_API_KEY environment variable for authentication if no direct nvcr.io entry is found in the Docker configuration.
  • Improved Error Messaging: Enhanced error messages for failed image pulls to specifically guide users on authentication issues, suggesting docker login nvcr.io or setting the NGC_API_KEY.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

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

Hey there - I've reviewed your changes - here's some feedback:

  • The inline debug prints re-read the Docker config and print sensitive registry info; consider consolidating this into getDockerAuth and using a verbose logging flag instead of ad-hoc prints.
  • getDockerAuth currently ignores credHelpers, so environments relying on Docker credential helpers will still fail—adding support for them would improve compatibility.
  • When looking up entries in config.Auths, normalize registry names (e.g. with or without scheme) to avoid mismatches between how Docker writes registry keys and how you query them.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The inline debug prints re-read the Docker config and print sensitive registry info; consider consolidating this into getDockerAuth and using a verbose logging flag instead of ad-hoc prints.
- getDockerAuth currently ignores credHelpers, so environments relying on Docker credential helpers will still fail—adding support for them would improve compatibility.
- When looking up entries in config.Auths, normalize registry names (e.g. with or without scheme) to avoid mismatches between how Docker writes registry keys and how you query them.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes authentication issues when pulling NIM images from nvcr.io by properly formatting credentials for the Docker API. The key change is transforming Docker config's base64-encoded username:password format into the JSON format required by the Docker client API.

Key changes:

  • Added authentication retrieval from Docker config.json for nvcr.io registry
  • Implemented fallback authentication using NGC_API_KEY environment variable
  • Added debug logging to help troubleshoot authentication issues

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Comment on lines +166 to +169
// Create basic auth with NGC API key
// For nvcr.io, username is "$oauthtoken" and password is the NGC API key
auth := base64.StdEncoding.EncodeToString([]byte("$oauthtoken:" + ngcAPIKey))
pullOptions.RegistryAuth = auth
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

The NGC_API_KEY authentication format is inconsistent with the Docker config authentication format. Line 168 uses the old username:password base64 format, but according to the PR description and lines 155-159, the correct format should be a JSON object {\"username\": \"$oauthtoken\", \"password\": ngcAPIKey} that is then base64-encoded.

Suggested change
// Create basic auth with NGC API key
// For nvcr.io, username is "$oauthtoken" and password is the NGC API key
auth := base64.StdEncoding.EncodeToString([]byte("$oauthtoken:" + ngcAPIKey))
pullOptions.RegistryAuth = auth
// Create Docker auth JSON with NGC API key
// For nvcr.io, username is "$oauthtoken" and password is the NGC API key
authJSON, _ := json.Marshal(map[string]string{
"username": "$oauthtoken",
"password": ngcAPIKey,
})
pullOptions.RegistryAuth = base64.StdEncoding.EncodeToString(authJSON)

Copilot uses AI. Check for mistakes.
Comment on lines +155 to +158
authJSON, _ := json.Marshal(map[string]string{
"username": username,
"password": password,
})
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

The error from json.Marshal is silently ignored. While json.Marshal rarely fails for simple maps, the error should still be handled to maintain code robustness and provide better debugging information if marshaling does fail.

Copilot uses AI. Check for mistakes.
Comment on lines +54 to +56
configFile := filepath.Join(configDir, "config.json")

// Read Docker config file
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

The Docker config file reading and parsing logic is duplicated between the getDockerAuth function (lines 54-86) and the debug section in pullNIMImage (lines 119-137). Consider removing the duplicate logic in pullNIMImage and using the getDockerAuth function's results for debugging purposes.

Copilot uses AI. Check for mistakes.
Comment on lines +107 to +108
// Debug: Show what we're looking for
cmd.Printf("Looking for authentication for registry: nvcr.io\n")
Copy link

Copilot AI Oct 17, 2025

Choose a reason for hiding this comment

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

Corrected spelling of 'supprot' to 'support' in the PR title.

Copilot uses AI. Check for mistakes.
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request aims to fix authentication issues when pulling NIM images from nvcr.io. The changes introduce a helper function to read Docker's config.json and correctly format the authentication token as a JSON payload. My review focuses on the correctness of the authentication logic and code quality.

I've found a few issues:

  • The fallback authentication using NGC_API_KEY does not use the correct JSON payload format, which will likely cause it to fail.
  • There is a significant amount of debug code, some of which is implemented unsafely by ignoring errors and duplicating logic. This should be removed.

Overall, the main change to fix the Docker config authentication is correct, but the related changes need some cleanup and a fix for the fallback mechanism.

Comment on lines +117 to +138
if authStr == "" {
cmd.Printf("Debug: No stored credentials found for nvcr.io. Checking Docker config...\n")
configDir := os.Getenv("DOCKER_CONFIG")
if configDir == "" {
homeDir, _ := os.UserHomeDir()
configDir = filepath.Join(homeDir, ".docker")
}
configFile := filepath.Join(configDir, "config.json")

if data, err := os.ReadFile(configFile); err == nil {
var config struct {
Auths map[string]interface{} `json:"auths"`
}
if json.Unmarshal(data, &config) == nil {
cmd.Printf("Debug: Found auth entries for: ")
for registry := range config.Auths {
cmd.Printf("%s ", registry)
}
cmd.Printf("\n")
}
}
}
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This block of code appears to be for debugging. It's inefficient because it re-reads and re-parses the Docker config file, duplicating logic from getDockerAuth. More importantly, it's unsafe as it ignores potential errors from os.UserHomeDir() on line 121 and json.Unmarshal() on line 130. This entire block should be removed.

Comment on lines +168 to +169
auth := base64.StdEncoding.EncodeToString([]byte("$oauthtoken:" + ngcAPIKey))
pullOptions.RegistryAuth = auth
Copy link
Contributor

Choose a reason for hiding this comment

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

high

The authentication format for NGC_API_KEY is inconsistent with the fix for Docker config authentication. The PR correctly identifies that nvcr.io requires a base64-encoded JSON payload. However, this fallback logic is still using the older username:password string format. This will likely cause authentication to fail when NGC_API_KEY is used. The payload should be a JSON object with username as "$oauthtoken" and password as the ngcAPIKey.

Suggested change
auth := base64.StdEncoding.EncodeToString([]byte("$oauthtoken:" + ngcAPIKey))
pullOptions.RegistryAuth = auth
authJSON, _ := json.Marshal(map[string]string{"username": "$oauthtoken", "password": ngcAPIKey})
pullOptions.RegistryAuth = base64.StdEncoding.EncodeToString(authJSON)


reader, err := dockerClient.ImagePull(ctx, model, image.PullOptions{})
// Debug: Show what we're looking for
cmd.Printf("Looking for authentication for registry: nvcr.io\n")
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

This Printf statement appears to be a debug message. To avoid cluttering the command-line output for users, it's best to remove such messages or make them conditional (e.g., by showing them only when a --verbose flag is used).

@DC-Shi DC-Shi mentioned this pull request Oct 17, 2025
@ericcurtin
Copy link
Contributor

Thanks for working on this

@ericcurtin
Copy link
Contributor

@DC-Shi you can change:

docker:add-nim-support from DC-Shi:fix-nim-image-auth

to

main from DC-Shi:fix-nim-image-auth

if you'd like, might be easier

@DC-Shi DC-Shi changed the base branch from add-nim-support to main October 22, 2025 08:16
@DC-Shi
Copy link
Author

DC-Shi commented Oct 22, 2025

@DC-Shi you can change:

docker:add-nim-support from DC-Shi:fix-nim-image-auth

to

main from DC-Shi:fix-nim-image-auth

if you'd like, might be easier

Got it, changed to docker:main

@ericcurtin ericcurtin merged commit 5b56415 into docker:main Oct 22, 2025
4 checks passed
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.

2 participants