SYSTEM Cited by 1 source
Ryuk (Testcontainers reaper)¶
Ryuk (github.com/testcontainers/moby-ryuk) is a tiny Docker container shipped with Testcontainers whose only job is to kill orphaned containers after the parent JVM test process dies.
Problem¶
Testcontainers normally cleans up its containers via a JVM
shutdown hook: when the test JVM exits cleanly, the hook runs
.stop() on each container. But shutdown hooks don't fire in
crash scenarios — SIGKILL, OOM kill, CI worker preemption, kill
-9, laptop closed mid-run. Without a reaper, those containers
would accumulate indefinitely.
Mechanism¶
On first container creation, Testcontainers launches a single
Ryuk container with a Unix-domain socket into it. Testcontainers
sends Ryuk a filter (label: testcontainers=true + a unique
session id) and a heartbeat. As long as the heartbeat
arrives, Ryuk does nothing.
When the heartbeat stops (JVM died), Ryuk waits for a configurable timeout, then deletes every container, network, volume, and image matching the filter. The JVM's containers are GC'd; Ryuk itself exits.
Why a separate container?¶
The reaper has to outlive the JVM. Putting it in the JVM would be self-defeating. Putting it in the Docker daemon requires daemon-side plugins or modifications, not portable. A small containerised sidecar is portable across Docker, Podman, remote runtimes — wherever Testcontainers runs.
Tradeoffs¶
- Ryuk requires Docker socket access. In strict
multi-tenant CI environments, this can be a security concern;
some teams disable Ryuk (
TESTCONTAINERS_RYUK_DISABLED=true) and manage cleanup via other means. - Not bullet-proof. If Ryuk itself dies (e.g. machine reboot), orphaned containers from its session survive. Periodic fleet-level cleanup is still recommended in long-running CI environments.
- Startup cost — the first Testcontainers interaction in a JVM pays a small tax to launch Ryuk. Negligible relative to the Postgres / Localstack containers themselves.
Seen in¶
- sources/2021-02-24-zalando-integration-tests-with-testcontainers — Zalando ZMS post names Ryuk explicitly as the mechanism Testcontainers uses to clean up containers when the JVM process itself is unavailable; notes that Ryuk can be disabled.
Related¶
- systems/testcontainers — Ryuk ships with it.
- systems/docker — runtime Ryuk operates on.
- concepts/singleton-container-pattern — the singleton pattern relies on shutdown hooks + Ryuk as the twin cleanup mechanism.