Skip to content

feat: Resolve default Docker endpoint like the Docker CLI#108

Merged
HofmeisterAn merged 11 commits into
testcontainers:mainfrom
ebriney:feature/docker-cli-style-defaults
Jun 4, 2026
Merged

feat: Resolve default Docker endpoint like the Docker CLI#108
HofmeisterAn merged 11 commits into
testcontainers:mainfrom
ebriney:feature/docker-cli-style-defaults

Conversation

@ebriney

@ebriney ebriney commented Jun 1, 2026

Copy link
Copy Markdown

Summary

  • Make new DockerClientBuilder() resolve the daemon endpoint the same way the docker CLI does: DOCKER_HOST → active Docker context (DOCKER_CONTEXT / currentContext in ~/.docker/config.json) → platform default socket. Works the same on Linux, macOS, and Windows.
  • Add DockerClientBuilder.WithContext(name) to target a named Docker context explicitly. Endpoint is read from ~/.docker/contexts/meta/<sha256(name)>/meta.json (honors DOCKER_CONFIG).
  • Fix npipe:// URI parsing so the four-slash form docker contexts emit on Windows (npipe:////./pipe/docker_engine) is accepted alongside the existing npipe://./pipe/docker_engine form.
  • Give ssh:// its own branch with actionable guidance instead of the generic unsupported-scheme error, since SSH-based contexts are now reachable through the resolver (recommend an SSH tunnel + DOCKER_HOST).
  • Document the new behavior in the README.

Test plan

  • New unit tests in DockerClientBuilderTests covering env-var, context, and platform-default resolution
  • Constructor_SetsPlatformDefaultEndpoint isolated from the host's DOCKER_* env and ~/.docker/config.json so it passes on machines with an active non-default context
  • Manual: new DockerClientBuilder().Build() connects against Docker Desktop on macOS (desktop-linux context) and Windows (named pipe) with no explicit URI

ebriney and others added 5 commits June 1, 2026 15:02
Resolves the Docker daemon endpoint the same way the docker CLI does,
in this order:

  1. DOCKER_HOST environment variable (DOCKER_TLS_VERIFY upgrades
     tcp:// to https://)
  2. DOCKER_CONTEXT env var, or currentContext from
     ~/.docker/config.json, looked up under
     ~/.docker/contexts/meta/<sha256(name)>/meta.json
  3. Platform default socket (unix:/var/run/docker.sock on
     Linux/macOS, npipe://./pipe/docker_engine on Windows)

DOCKER_CONFIG is honored to override the config directory. Paths are
derived from the user profile so the same code works on Linux, macOS,
and Windows.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The parameterless DockerClientBuilder() now uses DockerContextResolver
instead of jumping straight to the platform default socket, so it
transparently honors DOCKER_HOST and the active Docker context just
like the docker CLI.

Add DockerClientBuilder.WithContext(string) to target a named Docker
context explicitly.

Also give ssh:// its own branch in ResolveTransportFactory with
actionable guidance, instead of the generic unsupported-scheme error,
since SSH-based contexts are now reachable through the resolver.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The previous parser required exactly three Uri segments with "pipe/"
at index 1, and failed on the canonical form docker contexts store on
Windows, "npipe:////./pipe/docker_engine", which parses with an empty
Host and an extra leading path segment.

Search for the "pipe/" segment instead of indexing it, and fall back
to the segment before "pipe/" for the server name when the Host is
empty. Empty / "localhost" server names still resolve to "." so
NamedPipeClientStream can connect.

Handles both URI shapes that the docker CLI emits:
  npipe://./pipe/docker_engine
  npipe:////./pipe/docker_engine

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Split the Usage section into the default client (env -> context ->
platform default), an explicit endpoint, and DockerClientBuilder
.WithContext for targeting a named context. Adds a note that ssh://
endpoints are not supported.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The parameterless DockerClientBuilder constructor now resolves the endpoint CLI-style via DockerContextResolver.Resolve(), so the test must neutralize DOCKER_HOST/DOCKER_CONTEXT/DOCKER_TLS_VERIFY and point DOCKER_CONFIG at an empty directory for the platform default to be selected. Without this, the test failed on any machine with an active non-default Docker context (e.g. desktop-linux).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@HofmeisterAn

Copy link
Copy Markdown
Collaborator

Thanks for the PR. I'll do the review sometime end of the week.

@HofmeisterAn

HofmeisterAn commented Jun 4, 2026

Copy link
Copy Markdown
Collaborator

Thanks again for the PR. While reviewing it, I noticed that much of it overlaps with functionality we already have in Testcontainers and that I've wanted to move into Docker.DotNet for a while.

I copied the Testcontainers implementation, made a few adjustments, and improvied testing for different configurations. We can also add proper TLS support later by reusing the Testcontainers implementation.

I'd like to do one final review, but if you're happy with the changes, I'm happy to merge them and publish a new version. WDYT?

Edit: I'll look into the failing tests. This was expected, as we've already set the DOCKER_* variables in our CI pipeline for several tests.

@ebriney

ebriney commented Jun 4, 2026

Copy link
Copy Markdown
Author

Thanks again for the PR. While reviewing it, I noticed that much of it overlaps with functionality we already have in Testcontainers and that I've wanted to move into Docker.DotNet for a while.

I copied the Testcontainers implementation, made a few adjustments, and improvied testing for different configurations. We can also add proper TLS support later by reusing the Testcontainers implementation.

I'd like to do one final review, but if you're happy with the changes, I'm happy to merge them and publish a new version. WDYT?

Edit: I'll look into the failing tests. This was expected, as we've already set the DOCKER_* variables in our CI pipeline for several tests.

I verified your commits and it is working well on windows and mac.
I'm happy with your changes, thanks.

@HofmeisterAn HofmeisterAn changed the title Resolve default Docker endpoint like the docker CLI feat: Resolve default Docker endpoint like the Docker CLI Jun 4, 2026
@HofmeisterAn HofmeisterAn added the enhancement New feature or request label Jun 4, 2026
@HofmeisterAn HofmeisterAn merged commit 06e4e0b into testcontainers:main Jun 4, 2026
15 checks passed
@ebriney ebriney deleted the feature/docker-cli-style-defaults branch June 5, 2026 09:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants