Overview
Test whether the container image produced by CI starts, serves work, drains on termination, and exits cleanly.
Draincheck is a provider-neutral CLI for running lifecycle tests against the final Linux container image that a pipeline may release. It starts an isolated container with Docker or Podman, waits for readiness, holds real work across the termination boundary, and produces CI-safe evidence about draining and exit behavior.
Think of it as a lifecycle unit test for the built image—not a load test, deployment tool, or platform compatibility checker.
Get started
Install Draincheck and verify a local image in one CI-shaped run.
Pilot a service
Add a non-blocking lifecycle check to an existing service pipeline.
Troubleshoot a failure
Read assertions, timelines, reports, and debug evidence in causal order.
Support boundary
See the exact v0.2 runtime, platform, and stability guarantees.
The lifecycle contract
One draincheck verify run proves that:
- The image starts and reaches its configured readiness condition.
- HTTP, gRPC, or repository-owned command traffic is genuinely active.
- The configured termination signal reaches the container.
- Readiness is withdrawn and in-flight work completes within its budgets.
- Optional streams and OpenTelemetry signals flush before exit.
- The container exits with the expected code without an OOM kill or forced cleanup.
Every run uses a unique container name and label, publishes selected ports on random loopback addresses, bounds untrusted output, and removes the exact container it created.
Choose your path
HTTP services
Send concurrent requests with bodies, headers, and exact status contracts.
gRPC services
Use unary calls, server streams, descriptors, reflection, and gRPC Health.
Long-lived connections
Verify SSE and WebSocket shutdown behavior alongside ordinary traffic.
Kubernetes profile
Model a shared grace period and an image-owned pre-stop hook before SIGTERM.
Designed for pipelines
Draincheck returns stable exit codes and can write JSON, JUnit, and bounded debug artifacts. It
tests a locally built image by default and never pulls implicitly when --pull=never is selected.
Use repeat to expose intermittent lifecycle behavior and suite when one image needs several
independent contracts.