From e0a557b894222dffd61de30804143d1dde420eb2 Mon Sep 17 00:00:00 2001 From: Ted Kaplan Date: Thu, 8 Oct 2026 22:22:13 +0000 Subject: [PATCH] fix(core): default to Ryuk 0.14.0, which doesn't break concurrent image pulls Ryuk 0.8.1 cleans up each session with ImagesPrune filtered to the session label. On the containerd image store, the default since Docker 29, the daemon's ImagePrune deletes every in-flight pull's lease before it applies the filter (moby/moby#53321). Each test session that ends therefore corrupts the image pulls of every other process on the same daemon, which fail with "lease does not exist", "failed commit on ref" or "failed to extract layer". Ryuk 0.10.0 and later remove images one at a time with ImageRemove and never call ImagesPrune. --- README.md | 2 +- docs/features/configuration.md | 4 ++-- docs/index.rst | 2 +- src/testcontainers/core/config.py | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index ce9289693..6e29eddef 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ You can set environment variables to configure the library behaviour: | `TESTCONTAINERS_DOCKER_SOCKET_OVERRIDE` | `/var/run/docker.sock` | Path to Docker's socket used by ryuk | | `TESTCONTAINERS_RYUK_PRIVILEGED` | `false` | Run ryuk as a privileged container | | `TESTCONTAINERS_RYUK_DISABLED` | `false` | Disable ryuk | -| `RYUK_CONTAINER_IMAGE` | `testcontainers/ryuk:0.8.1` | Custom image for ryuk | +| `RYUK_CONTAINER_IMAGE` | `testcontainers/ryuk:0.14.0` | Custom image for ryuk | | `RYUK_RECONNECTION_TIMEOUT` | `10s` | Reconnection timeout for Ryuk TCP socket before Ryuk reaps all dangling containers | Alternatively you can set the configuration during runtime: diff --git a/docs/features/configuration.md b/docs/features/configuration.md index fb9b1fcea..fc5a8b996 100644 --- a/docs/features/configuration.md +++ b/docs/features/configuration.md @@ -46,7 +46,7 @@ The following properties are supported: | `ryuk.disabled` | `TESTCONTAINERS_RYUK_DISABLED` | Disable the Garbage Collector | false | | `ryuk.container.privileged` | `TESTCONTAINERS_RYUK_PRIVILEGED` | Run Ryuk in privileged mode | false | | `ryuk.reconnection.timeout` | `RYUK_RECONNECTION_TIMEOUT` | Time to wait before reconnecting | 10s | -| `ryuk.image` | `RYUK_CONTAINER_IMAGE` | Ryuk container image | testcontainers/ryuk:0.8.1 | +| `ryuk.image` | `RYUK_CONTAINER_IMAGE` | Ryuk container image | testcontainers/ryuk:0.14.0 | | `connection.mode` | `TESTCONTAINERS_CONNECTION_MODE` | Connection mode (bridge_ip, gateway_ip, docker_host) | - | Additional configuration options: @@ -129,7 +129,7 @@ docker.cert.path=/path/to/certs ryuk.disabled=false ryuk.container.privileged=true ryuk.reconnection.timeout=30s -ryuk.image=testcontainers/ryuk:0.8.1 +ryuk.image=testcontainers/ryuk:0.14.0 # Testcontainers configuration tc.host=tcp://my.testcontainers.host:1234 diff --git a/docs/index.rst b/docs/index.rst index 613e903c9..575d2bc81 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -133,7 +133,7 @@ Configuration +-------------------------------------------+---------------------------------------------------+------------------------------------------+ | ``TESTCONTAINERS_RYUK_DISABLED`` | ``false`` | Disable ryuk | +-------------------------------------------+---------------------------------------------------+------------------------------------------+ -| ``RYUK_CONTAINER_IMAGE`` | ``testcontainers/ryuk:0.8.1`` | Custom image for ryuk | +| ``RYUK_CONTAINER_IMAGE`` | ``testcontainers/ryuk:0.14.0`` | Custom image for ryuk | +-------------------------------------------+---------------------------------------------------+------------------------------------------+ | ``DOCKER_AUTH_CONFIG`` | ``{"auths": {"": {"auth": ""}}}`` | Custom registry auth config | +-------------------------------------------+---------------------------------------------------+------------------------------------------+ diff --git a/src/testcontainers/core/config.py b/src/testcontainers/core/config.py index f5a9afc9f..15c522e4a 100644 --- a/src/testcontainers/core/config.py +++ b/src/testcontainers/core/config.py @@ -102,7 +102,7 @@ def _render_bool(self, env_name: str, prop_name: str) -> bool: max_tries: int = int(environ.get("TC_MAX_TRIES", "120")) sleep_time: float = float(environ.get("TC_POOLING_INTERVAL", "1")) - ryuk_image: str = environ.get("RYUK_CONTAINER_IMAGE", "testcontainers/ryuk:0.8.1") + ryuk_image: str = environ.get("RYUK_CONTAINER_IMAGE", "testcontainers/ryuk:0.14.0") _ryuk_privileged: Optional[bool] = None _ryuk_disabled: Optional[bool] = None _ryuk_docker_socket: str = ""