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

  1. Incorrectly Configured privileged: true in .drone.yml

    • Diagnosis: You’ve added privileged: true under the services or container section of your .drone.yml for the docker:dind service.
    • Fix: The privileged: true setting must be applied to the docker:dind service 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:dind container with the --privileged flag, 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.
  2. Drone Agent Lacks Sufficient Permissions

    • Diagnosis: Even with privileged: true correctly 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 a securityContext that allows privileged: 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_ADMIN capabilities or be configured to run Docker commands with elevated privileges.
    • Why it works: The --privileged flag 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.
  3. 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.
      // Example of a restrictive config (to be REMOVED or MODIFIED)
      {
        "no-new-privileges": true
      }
      
      A typical daemon.json for allowing privileged operations would simply not have such restrictions.
    • Why it works: The --privileged flag 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.
  4. 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:
        sudo apt-get update && sudo apt-get upgrade docker-ce # For Debian/Ubuntu
        sudo yum update docker-ce # For CentOS/RHEL
        
        Restart the Docker daemon after upgrading.
    • Why it works: Newer versions often include bug fixes and improved support for container features, including proper handling of the privileged flag and its associated security contexts.
  5. 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 privileged flag 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.
  6. Incorrect Docker-in-Docker Image

    • Diagnosis: You might be using a custom or outdated docker:dind image that doesn’t properly initialize or support privileged operations.
    • Fix: Explicitly use the official docker:dind image 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:dind image 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.

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.

Want structured learning?

Take the full Drone course →