Configuration¶
With Docker Desktop or a local daemon no configuration is needed. Everything on this page is for the other topologies: remote daemons, TLS, CI containers, registry mirrors.
How the daemon endpoint is resolved¶
The standard Testcontainers order, first hit wins:
DOCKER_HOSTenvironment variabledocker.hostin~/.testcontainers.properties- The active docker context (
DOCKER_CONTEXT, else the config'scurrentContext) — including its TLS certificate store - Platform default —
unix:///var/run/docker.sock(with rootless-socket fallbacks) on Linux/macOS, the//./pipe/docker_enginenamed pipe on Windows
ssh:// endpoints (which a docker context can carry) are not supported and fall through to
the platform default.
The properties file¶
Every library switch reads an environment variable first, then a key of
~/.testcontainers.properties (under HOME, else USERPROFILE; read once per process).
A set env var decides even when it decides "off" — an explicit TESTCONTAINERS_RYUK_DISABLED=false
overrides a file-enabled switch.
The file is shared with the other Testcontainers implementations, so parsing matches
testcontainers-java where they could diverge: #/! comment lines, last duplicate key wins,
booleans follow Boolean.parseBoolean (case-insensitive true; 1 is false) — except
docker.tls.verify, where 1 also counts as true (docker-java parity).
| Environment variable | Properties key | Meaning |
|---|---|---|
DOCKER_HOST |
docker.host |
daemon endpoint (unix://, npipe://, tcp://, https://) |
DOCKER_TLS_VERIFY |
docker.tls.verify |
upgrade a tcp:// endpoint to verified TLS (port 2375 → 2376) |
DOCKER_CERT_PATH |
docker.cert.path |
directory with ca.pem / cert.pem / key.pem |
TESTCONTAINERS_HOST_OVERRIDE |
host.override |
address handed out for reaching published ports |
TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX |
hub.image.name.prefix |
registry mirror prefix for Docker-Hub image references |
TESTCONTAINERS_RYUK_DISABLED |
ryuk.disabled |
disable the Ryuk reaper |
TESTCONTAINERS_RYUK_CONTAINER_IMAGE |
ryuk.container.image |
override the reaper image (testcontainers/ryuk:0.11.0) |
TESTCONTAINERS_SSHD_CONTAINER_IMAGE |
sshd.container.image |
override the host-access sidecar image |
TESTCONTAINERS_SOCAT_CONTAINER_IMAGE |
socat.container.image |
override the compose ambassador image |
TESTCONTAINERS_COMPOSE_CONTAINER_IMAGE |
compose.container.image |
override the containerised compose client image |
TESTCONTAINERS_REUSE_ENABLE |
testcontainers.reuse.enable |
globally enable container reuse |
(The mapping rule: env name = TESTCONTAINERS_ + the key upper-cased with dots as
underscores — with two exceptions: the docker.* trio keeps its standard DOCKER_* names,
and a key already starting with testcontainers. is not doubled, hence
TESTCONTAINERS_REUSE_ENABLE.)
TLS and remote daemons¶
- An explicit
https://host:portendpoint dials TLS directly. - The docker-CLI spelling —
tcp://host:portplusDOCKER_TLS_VERIFY/docker.tls.verify— upgrades to TLS, moving the default port 2375 → 2376. Client certificates come fromDOCKER_CERT_PATH/docker.cert.path, falling back to~/.docker. - A docker context carries its own TLS store; those materials are used verbatim, and the
context's
SkipTLSVerifyturns server verification off while still presenting the client pair. - Mutual TLS is exercised end to end in CI against a real
--tlsverifydocker:dind daemon.
One deliberate divergence from the docker CLI: the CLI treats any non-empty
DOCKER_TLS_VERIFY as "verify" (even 0); this library recognizes 1/true only.
The TLS transport is a build option (TC_TLS, default ON) — with it off, an https://
endpoint throws a DockerError naming the option.
Running inside a container (Docker-in-Docker / CI)¶
With the daemon socket mounted into your CI container, set nothing: the library detects
the situation (/.dockerenv) and hands out the docker bridge gateway instead of localhost,
so published ports resolve correctly. With a remote agent in between (e.g. a cloud runner
architecture), set TESTCONTAINERS_HOST_OVERRIDE to wherever published ports actually
surface.
Registry authentication¶
Credentials for pulls resolve the standard way — first hit wins:
- Explicit
with_registry_auth(...)on the image DOCKER_AUTH_CONFIG(the JSON itself, CI-friendly)$DOCKER_CONFIG/config.json, else~/.docker/config.json— including credential helpers (credsStore/credHelpers, shelling out todocker-credential-<helper> get); plaintextauthsentries take precedence
Helper outcomes are cached per (helper, registry) for 5 minutes — including "no credentials",
the answer for every anonymous pull under Docker Desktop's credsStore.
404 can mean 'authentication required'
Registries answer 404 for private images requested without credentials, so a pull
NotFoundError on an image you know exists usually means the credentials didn't resolve.
Image name substitution¶
TESTCONTAINERS_HUB_IMAGE_NAME_PREFIX (or a custom with_image_name_substitutor) redirects
Docker-Hub references to your mirror — including every internal utility image the library
starts (Ryuk, the sshd sidecar, the socat ambassador, the containerised compose client,
volume-populate helpers). Registry-qualified references pass through untouched. Not
substituted by design: images built by GenericBuildableImage (the daemon resolves FROM),
services in compose YAML (the file is yours), and raw DockerClient calls.