Repository navigation
[Feature]: Gitlab CI Support #12078
Copy link
Copy link
Open
Labels
Description
Module
No response
Problem
In many GitLab CI pipelines, integration tests that rely on Testcontainers need a running Docker daemon. The typical workaround is:
- Run a docker:dind service in privileged mode
- Mount the host Docker socket into the test container
- Set DOCKER_HOST=unix:///var/run/docker.sock in the test environment
This approach has several pain points:
| Issue | Impact |
|---|---|
| Privileged mode | Requiresprivileged: truein the job, which is disallowed in many shared runners for security reasons. |
| Docker socket exposure | Mounting/var/run/docker.sockcan inadvertently grant the test container full control over the host Docker daemon. |
| Port collisions & networking | The test container must be on the same network namespace as thedocker:dindservice, which is fragile and hard to debug. |
| Resource overhead | Each job starts a full DinD daemon, increasing build time and memory usage. |
| Complex configuration | Users must remember to setDOCKER_HOST,DOCKER_TLS_VERIFY, etc., which is error‑prone. |
A native GitLab CI services integration would eliminate the need for privileged mode, reduce configuration complexity, and improve security:
- Security – Avoid exposing the host Docker socket or running privileged containers.
- Simplicity – A single configuration flag should be sufficient to enable CI‑specific behavior.
- Performance – Reuse the GitLab CI service container’s Docker daemon instead of launching a new DinD instance per job.
- Consistency – Tests run in CI will mirror local development environments that use Testcontainers without any special CI configuration.
Solution
Add a new configuration option to the `Testcontainers` Java library (and analogous options for other languages) that allows the user to specify a GitLab CI service name and network alias. Example (Java):
TestcontainersConfiguration.getInstance()
.withGitLabService("docker:dind", "docker");Internally, Testcontainers will:
1. Detect that it is running inside a GitLab CI job (e.g., by checking `CI` environment variable).
2. Resolve the service container’s IP address via the GitLab CI network (`docker` alias).
3. Set `DOCKER_HOST=tcp://<service-ip>:2375` (or `2376` if TLS is enabled).
4. Optionally configure TLS certificates if the service exposes them.
Runtime Behavior
- No privileged mode – The job can run without `privileged: true`.
- Automatic network discovery – Testcontainers will query the GitLab CI network for the service alias.
- TLS support – If the GitLab service exposes TLS, the library can automatically pick up the certificates from known paths (`/etc/docker/certs.d/`).
Fallback
If the CI environment is not detected or the service is missing, Testcontainers will fall back to its normal local Docker daemon strategy, preserving backward compatibility.
Benefit
| Category | Impact |
| --- | --- |
| Security | Positive – reduces privileged execution and socket exposure. |
| Performance | Slightly better – reusing the CI service container avoids launching a separate DinD daemon. |
| Developer Experience | Positive – fewer environment variables, clearer CI configuration. |
| Maintenance | Minimal – only a small API addition and a few environment checks. |
| Compatibility | Backward compatible; old jobs continue to work unchanged. |
Alternatives
- Priviledge DinD Runner in Kubernetes
Would you like to help contributing this feature?
Yes
Reactions are currently unavailable
Activity
AB-xdev commentedon Sep 14, 2026
Some quick feedback from my side (I will not try to elaborate too deep because this issue looks AI generated) - we are using testcontainers in CI environments for many years now.
So each CI setup behaves very different when it comes to setting stuff up but they all share on core part: You need to connect to an exposed docker socket.
The default GitLab DinD documentation is IMHO quite straight forward and worked for us out of the box:
Add a sidecar container, set some environment variables and that's basically it. Around ~10 lines of total YAML code.
I also don't see how testcontainers - a java library - can influence a GitLab pipeline in such a way that the required docker setup is always correctly present.
Also most of the mentioned "problems" are GitLab design problems and unrelated to testcontainers or hallucinated:
This is not the case
That's a general GitLab (Docker) CI problem
GitLab CI ensures this automatically
You can't copy paste 3 environment variables?
hypery2k commentedon Sep 14, 2026
the problem is not to paste the env vars here. The problem is that you have to allow privileged containers which exposes security risks because it's a security ant-pattern. GitLab dynamic child pipelines allow you to trigger a downstream pipeline using a configuration file generated at runtime by a job, rather than a static YAML file saved in your repository which could be utilized by testcontainers
AB-xdev commentedon Sep 15, 2026
I'm not sure what you are talking about because my link to the docs clearly show that you do not need a privileged container, when using the "Example using DinD"?
You will also have the exact same problem with downstream pipelines because you still require a Docker execution environment/socket.
hypery2k commentedon Sep 15, 2026
Docker-in-Docker must run in privileged mode to work properly. Be aware that privileged mode provides full access to the host environment. For more information, go to the Docker documentation on Runtime Privilege and Linux Capabilities and this issue.
Within gitlab you need to run build pods privileged:
But for other CI systems the same apply.
The
--priviledgedflag gives all the capabilities to the container and it also lifts all the limitations enforced by the device cgroup controller. In other words, the container can do almost everything that the host, hereby Kubernetes worker node, can do. This flag exists to allow special use-cases, like running Docker-in-Docker: https://safeguard.sh/resources/blog/docker-privileged-mode-risks-alternativesAB-xdev commentedon Sep 15, 2026
Okay nevermind I was wrong here. You have to configure privileged in the underlying GitLab runner for that solution to work.
However this still doesn't change the fact that Testcontainers can't change how Docker or the GitLab CI works...
PS: You don't have lecture me in an AI summary to me how Docker's privileged works - I have been working with Docker for years.