Daemonless, rootless builders are the safest of the three for building images in CI, because they need neither privileged mode nor access to a shared Docker daemon. Docker-in-Docker needs privileged mode. Binding the host Docker socket shares the host daemon with the job and can expose the host to privilege escalation.
The three approaches
Docker-in-Docker. The job starts its own Docker daemon in a service container. GitLab's documentation says the runner must support privileged mode for this. Each job gets its own isolated daemon, so concurrent jobs do not conflict.
Socket binding. The job container mounts the host's Docker socket and talks to the host daemon. It avoids privileged mode, but GitLab warns that sharing the daemon effectively disables the container's security mechanisms and can expose the host to privilege escalation. Concurrent jobs can also conflict, and volume mounts resolve against the host, not the job.
Daemonless builders. Tools such as rootless BuildKit or Buildah build OCI images without a Docker daemon. GitLab lists both as alternatives.
Comparison
| Approach | Needs privileged mode | Shares host daemon | Main risk |
|---|---|---|---|
| Docker-in-Docker | Yes | No | A privileged container on the runner host |
| Socket binding | No | Yes | Job can control every container on the host |
| Daemonless, rootless | No | No | Fewer features, some Dockerfile differences |
A related warning from the same documentation: with the shell executor, adding the runner user to the docker group gives it full root permissions.
How to choose
- Can you use a daemonless builder? Start there. Test your Dockerfiles, since behaviour can differ in edge cases.
- Need real Docker features? Use Docker-in-Docker, but only on runners dedicated to that purpose, with no deployment credentials and no access to trusted code paths.
- Tempted by socket binding? Treat it as giving the job root on the host. Use it only on throwaway runners that nothing else depends on.
- Any approach: run builds triggered by untrusted pull requests on isolated, ephemeral runners without secrets.
Scan what you build
Whichever builder you choose, the output image still carries whatever your base image and packages brought in. Scan the image before it is pushed and gate on findings.
Try it yourself
Click through it at your own pace, or open it full screen. Look at how findings are grouped by layer, which tells you whether to fix the base image or your own packages.
Quick check
Is Docker-in-Docker safe on a shared runner?
Not on a runner that also holds credentials or serves untrusted jobs. Privileged mode weakens the boundary between the job and the host.
Does rootless mean no risk?
No. It removes a large class of host escalation paths, but the build can still fetch bad dependencies or leak what it can read.
Safeguard scans container images and dependencies, and policies and gates can block a push on findings. The free scan is a quick start.
Sources
Last reviewed: 19 October 2026.