## TL;DR

Testcontainers needs a Docker daemon the CI job can reach. Enable the Docker service in the CI runner, mount the socket, and run the job privileged where required.

## Error

```text
Could not find a valid Docker environment. Please check your Docker installation.
```

## Steps

1. Enable Docker in the runner: GitHub Actions `docker` is default on ubuntu runners; GitLab needs `docker:dind` service. Expected: a daemon exists.
2. Mount `/var/run/docker.sock` or set `DOCKER_HOST`. Expected: the client reaches the daemon.
3. For DinD, use `docker:dind` with privileged mode and set `TESTCONTAINERS_HOST_OVERRIDE` if needed. Expected: containers start inside the job.
4. Verify with `docker info` in a pre-step. Expected: the daemon responds before tests run.
5. Re-run. Expected: Testcontainers provisions dependencies.

## When to use

- `docker not available` in CI, works locally.
- Testcontainers-based integration tests.

## When not to use

- Local Docker problems.
- You can use static test services instead.

## Tool compatibility

- Testcontainers (Java/Node/Python/Go); any CI with Docker support.

## Variant phrasings

### Testcontainers CI setup

The general task; daemon access is the core.

### Docker in Docker for tests

The DinD variant; privileged mode required.

## Why it happens

Locally Docker Desktop just runs. CI runners need explicit Docker services and socket access.

## Edge cases

- Rootless Docker needs socket path configuration.
- Some CI providers ban privileged mode; use their Docker service instead.
- Ryuk (Testcontainers cleanup) needs to reach the daemon too.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_t4W7tMDJkqlLkL_7L_1IHg
