Drone CI’s Docker-in-Docker (dind) plugin fails to start containers in privileged mode because the privileged: true setting in the .drone.yml is ignored.
This happens because the Drone agent, which orchestrates container execution, doesn’t directly pass the privileged: true flag to the Docker daemon when it spawns the dind container. Instead, the dind container itself needs to be launched with the privileged flag.
Common Causes and Fixes
-
Incorrectly Configured
privileged: truein.drone.yml- Diagnosis: You’ve added
privileged: trueunder theservicesorcontainersection of your.drone.ymlfor thedocker:dindservice. - Fix: The
privileged: truesetting must be applied to thedocker:dindservice definition itself, not as an option within the service’s image configuration. It’s a top-level setting for the service.services: docker: dind: true privileged: true # This is the correct placement - Why it works: This tells the Drone agent to launch the
docker:dindcontainer with the--privilegedflag, allowing it to interact with the host’s Docker daemon as if it were a full Docker daemon itself, which is necessary for it to then spawn other containers in privileged mode.
- Diagnosis: You’ve added
-
Drone Agent Lacks Sufficient Permissions
- Diagnosis: Even with
privileged: truecorrectly set in.drone.yml, the Drone agent itself might not have the necessary permissions on the host system to run containers in privileged mode. This is common when running Drone on Kubernetes or other orchestrators. - Fix:
- Kubernetes: If Drone is running on Kubernetes, the
drone-agent(or the pod running the agent) needs asecurityContextthat allowsprivileged: true. This is usually configured in the Kubernetes deployment or StatefulSet YAML for the agent.spec: template: spec: containers: - name: drone-agent # ... other container config securityContext: privileged: true - Docker Swarm/Standalone Docker: If running Drone directly on Docker, the user or service running the Drone agent must have
CAP_SYS_ADMINcapabilities or be configured to run Docker commands with elevated privileges.
- Kubernetes: If Drone is running on Kubernetes, the
- Why it works: The
--privilegedflag at the container runtime level requires specific Linux capabilities (CAP_SYS_ADMIN) that allow a container to perform operations that would normally be restricted, such as mounting filesystems or creating devices. Granting this capability to the agent’s runtime environment allows it to pass this privilege down to the dind container.
- Diagnosis: Even with
-
Docker Daemon Configuration Restrictions
- Diagnosis: The host’s Docker daemon might be configured to disallow privileged containers. This is a security measure.
- Fix: Check the Docker daemon configuration file (e.g.,
/etc/docker/daemon.json). Ensure there are no settings that explicitly block privileged containers. If there are, remove them and restart the Docker daemon.
A typical// Example of a restrictive config (to be REMOVED or MODIFIED) { "no-new-privileges": true }daemon.jsonfor allowing privileged operations would simply not have such restrictions. - Why it works: The
--privilegedflag is ultimately interpreted by the host’s Docker daemon. If the daemon’s configuration prevents it, the flag will be ignored, and the dind container will not run with the necessary privileges.
-
Outdated Drone Agent or Docker Version
- Diagnosis: Older versions of Drone or the Docker daemon might have bugs or limitations in how they handle privileged container requests.
- Fix: Upgrade your Drone agent and the Docker daemon on your runner to the latest stable versions.
- Drone Agent: Refer to the Drone documentation for upgrade instructions specific to your deployment method (Docker, Kubernetes, etc.).
- Docker Daemon:
Restart the Docker daemon after upgrading.sudo apt-get update && sudo apt-get upgrade docker-ce # For Debian/Ubuntu sudo yum update docker-ce # For CentOS/RHEL
- Why it works: Newer versions often include bug fixes and improved support for container features, including proper handling of the
privilegedflag and its associated security contexts.
-
Container Runtime Interface (CRI) Conflicts (Kubernetes)
- Diagnosis: If running on Kubernetes, other components or configurations related to the Container Runtime Interface (e.g., containerd, CRI-O) might interfere with the
privilegedflag being correctly passed and honored. - Fix: Ensure your Kubernetes cluster’s CRI is configured to allow privileged containers, and that no network policies or security policies (like PodSecurityPolicies or their successors) are preventing the dind container from obtaining the necessary privileges. This often involves cluster-level administrator configuration.
- Why it works: The CRI is the interface between the Kubernetes node and the container runtime. If the CRI itself or the underlying runtime is configured to disallow privileged operations, even if Kubernetes requests it, the container won’t be started with those privileges.
- Diagnosis: If running on Kubernetes, other components or configurations related to the Container Runtime Interface (e.g., containerd, CRI-O) might interfere with the
-
Incorrect Docker-in-Docker Image
- Diagnosis: You might be using a custom or outdated
docker:dindimage that doesn’t properly initialize or support privileged operations. - Fix: Explicitly use the official
docker:dindimage and ensure it’s a recent version.services: docker: dind: true privileged: true image: docker:20.10.17 # Specify a recent, known-good version - Why it works: The
docker:dindimage contains the necessary entrypoint scripts and configurations to run a Docker daemon within a container. Using an official and up-to-date version ensures these internal components are functioning correctly and can manage child containers with the requested privileges.
- Diagnosis: You might be using a custom or outdated
After applying the correct privileged: true setting to the docker:dind service in your .drone.yml and ensuring the Drone agent and host Docker environment permit it, you will likely encounter a new error related to the commands you are trying to run inside the dind container that now require specific permissions.