Drone

CI/CDDroneContainer-NativeDockerKubernetesContinuous IntegrationAgentlessPlugins

CI/CD Tool

Drone

Overview

Drone is a Container-Native continuous delivery platform. It executes all builds inside isolated Docker containers and provides modern cloud-native CI/CD through deep Kubernetes integration.

Details

Drone is a continuous delivery system built on container technology, serving as a mature cloud-native CI/CD platform with over 25,700 GitHub stars and 300+ contributors. In 2024-2025, enhanced Kubernetes-native features achieved an agentless architecture, providing significant operational simplification compared to traditional CI/CD systems. It uses simple YAML configuration files (a superset of docker-compose) to define and execute pipelines inside Docker containers, with a container-first architecture enabling the same pipeline configuration across Kubernetes and Docker runtimes. All builds execute in isolated Docker containers, providing completely separated environments with auto-provisioning from thousands of available Docker images. Ephemeral builds guarantee clean environments for each pipeline execution, improving reproducibility. From a Kubernetes administrator perspective, agent installation, upgrading, and management are eliminated, significantly simplifying deployment. Host machine Docker socket mounting and Docker-in-Docker execution are unnecessary, enabling Kubernetes-native in-cluster builds. The plugin architecture features an innovative design where Drone plugins are Docker containers included as pipeline steps, unlike other CI tools that install plugins server-side. Single binary installation with automatic scaling, flexible deployment across on-premises, private cloud, and Kubernetes cloud-native infrastructure provides teams complete control over build infrastructure.

Pros and Cons

Pros

  • Container-Native: All builds executed in isolated Docker containers
  • Kubernetes-Native: Agentless K8s integration architecture
  • Simple Configuration: Intuitive pipeline definition via YAML files
  • Plugin Architecture: Innovative Docker container-based plugin system
  • High Reproducibility: Clean execution environments through ephemeral builds
  • Auto-Scaling: Easy installation and scaling from single binary
  • Portability: Unified configuration across multiple execution environments
  • Rich Images: Environment selection from thousands of Docker images
  • Local Execution: Local CI execution via Docker Extension

Cons

  • Docker Dependency: Strong dependency on Docker container technology
  • Learning Curve: Requires container technology and Kubernetes knowledge
  • Resource Consumption: Resource usage due to container overhead
  • Debug Complexity: Troubleshooting in containerized environments
  • Plugin Limitations: Constraints of container-based plugins
  • Network Configuration: Configuration challenges in complex network requirements
  • Ecosystem: Community size compared to other CI/CD tools
  • Storage Management: Persistent data management in ephemeral containers

Key Links

Code Examples

Basic Pipeline Configuration

# .drone.yml
kind: pipeline
type: docker
name: default

steps:
- name: build
  image: golang:1.21
  commands:
  - go mod download
  - go build -o app .

- name: test
  image: golang:1.21
  commands:
  - go test -v ./...
  - go test -race -coverprofile=coverage.out ./...

- name: lint
  image: golangci/golangci-lint:latest
  commands:
  - golangci-lint run

trigger:
  branch:
  - main
  - develop
  event:
  - push
  - pull_request

Kubernetes-Native Pipeline

# .drone.yml
kind: pipeline
type: kubernetes
name: default

# Resource request definitions
resources:
  requests:
    cpu: 1000
    memory: 1000MiB

steps:
- name: build
  image: node:18
  commands:
  - npm ci
  - npm run build
  resources:
    limits:
      cpu: 2000
      memory: 2000MiB

- name: test
  image: node:18
  commands:
  - npm test
  - npm run test:coverage

- name: security-scan
  image: node:18
  commands:
  - npm audit
  - npm run security:check

# Service containers
services:
- name: redis
  image: redis:7-alpine
- name: postgres
  image: postgres:15
  environment:
    POSTGRES_DB: testdb
    POSTGRES_USER: testuser
    POSTGRES_PASSWORD: testpass

# Volume mounts
volumes:
- name: cache
  temp: {}

Docker Integration and Multi-stage Builds

# .drone.yml
kind: pipeline
type: docker
name: default

steps:
- name: build-frontend
  image: node:18-alpine
  volumes:
  - name: cache
    path: /cache
  commands:
  - npm ci --cache /cache/.npm
  - npm run build
  - npm run test:unit

- name: build-backend
  image: golang:1.21-alpine
  volumes:
  - name: cache
    path: /go/pkg/mod
  commands:
  - go mod download
  - go build -o app .
  - go test ./...

- name: docker-build
  image: plugins/docker
  settings:
    repo: myregistry.com/myapp
    tags:
      - ${DRONE_COMMIT_SHA:0:8}
      - latest
    dockerfile: Dockerfile
    context: .
    registry: myregistry.com
    username:
      from_secret: docker_username
    password:
      from_secret: docker_password

- name: docker-scan
  image: aquasec/trivy
  commands:
  - trivy image myregistry.com/myapp:${DRONE_COMMIT_SHA:0:8}

volumes:
- name: cache
  temp: {}

trigger:
  branch:
  - main
  event:
  - push

Multi-platform and Multi-architecture

# .drone.yml - AMD64
---
kind: pipeline
type: docker
name: test-amd64

platform:
  os: linux
  arch: amd64

steps:
- name: test
  image: golang:1.21
  commands:
  - go build
  - go test -v ./...

---
# ARM64 pipeline
kind: pipeline
type: docker
name: test-arm64

platform:
  os: linux
  arch: arm64

steps:
- name: test
  image: golang:1.21
  commands:
  - go build
  - go test -v ./...

---
# Windows pipeline
kind: pipeline
type: docker
name: test-windows

platform:
  os: windows
  arch: amd64
  version: 1909

steps:
- name: test
  image: golang:1.21-windowsservercore-1909
  commands:
  - go build
  - go test -v ./...

---
# Dependency definitions
kind: pipeline
type: docker
name: deploy

depends_on:
- test-amd64
- test-arm64
- test-windows

steps:
- name: deploy
  image: alpine
  commands:
  - echo "All tests passed, deploying..."

Plugin and Service Integration

# .drone.yml
kind: pipeline
type: docker
name: default

steps:
- name: build
  image: node:18
  commands:
  - npm ci
  - npm run build

- name: test
  image: node:18
  environment:
    DATABASE_URL: postgres://testuser:testpass@postgres:5432/testdb
    REDIS_URL: redis://redis:6379
  commands:
  - npm run test:integration
  depends_on:
  - postgres
  - redis

- name: sonarqube
  image: sonarqube/sonar-scanner-cli
  environment:
    SONAR_HOST_URL: https://sonarqube.company.com
    SONAR_LOGIN:
      from_secret: sonar_token
  commands:
  - sonar-scanner

- name: slack-notify
  image: plugins/slack
  settings:
    webhook:
      from_secret: slack_webhook
    channel: "#ci-cd"
    username: drone
    template: >
      {{#success build.status}}
        ✅ Build {{build.number}} succeeded. Branch: {{build.branch}}
      {{else}}
        ❌ Build {{build.number}} failed. Branch: {{build.branch}}
      {{/success}}
  when:
    status:
    - success
    - failure

- name: deploy-staging
  image: plugins/ansible
  settings:
    playbook: deploy.yml
    inventory: staging
    private_key:
      from_secret: ansible_key
  when:
    branch:
    - develop

- name: deploy-production
  image: plugins/ansible
  settings:
    playbook: deploy.yml
    inventory: production
    private_key:
      from_secret: ansible_key
  when:
    branch:
    - main
    event:
    - tag

services:
- name: postgres
  image: postgres:15
  environment:
    POSTGRES_DB: testdb
    POSTGRES_USER: testuser
    POSTGRES_PASSWORD: testpass

- name: redis
  image: redis:7-alpine

volumes:
- name: docker-sock
  host:
    path: /var/run/docker.sock

Conditional Execution and Matrix Builds

# .drone.yml
kind: pipeline
type: docker
name: test-matrix

strategy:
  matrix:
    NODE_VERSION:
    - "16"
    - "18"
    - "20"
    ENVIRONMENT:
    - "test"
    - "staging"

steps:
- name: test
  image: node:${NODE_VERSION}
  environment:
    NODE_ENV: ${ENVIRONMENT}
  commands:
  - npm ci
  - npm run test:${ENVIRONMENT}

---
kind: pipeline
type: docker
name: security-scan

steps:
- name: vulnerability-scan
  image: aquasec/trivy
  commands:
  - trivy fs .

- name: secret-scan
  image: trufflesecurity/trufflehog
  commands:
  - trufflehog filesystem .

- name: license-check
  image: licensefinder/license_finder
  commands:
  - license_finder

trigger:
  event:
  - pull_request

---
kind: pipeline
type: docker
name: production-deploy

steps:
- name: deploy
  image: kubectl
  environment:
    KUBECONFIG:
      from_secret: kubeconfig
  commands:
  - kubectl apply -f k8s/
  - kubectl rollout status deployment/myapp

trigger:
  branch:
  - main
  event:
  - push

depends_on:
- test-matrix
- security-scan

---
# Signature (for configuration file verification)
kind: signature
hmac: F10E2821BBBEA527EA02200352313BC059445190

ConfigMap and Secret Usage (Kubernetes)

# .drone.yml
kind: pipeline
type: kubernetes
name: default

steps:
- name: build
  image: node:18
  volumes:
  - name: build-config
    path: /config
  - name: secrets
    path: /secrets
  environment:
    DATABASE_URL:
      from_secret: database_url
    API_KEY:
      from_secret: api_key
  commands:
  - echo "Building with config from $(cat /config/environment)"
  - npm ci
  - npm run build

- name: test
  image: node:18
  volumes:
  - name: test-data
    path: /test-data
  commands:
  - npm test
  - npm run test:integration

- name: publish
  image: plugins/docker
  settings:
    repo: myregistry.com/myapp
    registry: myregistry.com
    username:
      from_secret: registry_username
    password:
      from_secret: registry_password
    tags:
    - ${DRONE_COMMIT_SHA}
    - latest

volumes:
- name: build-config
  config_map:
    name: build-config
    default_mode: 420

- name: secrets
  secret:
    secret_name: app-secrets

- name: test-data
  empty_dir: {}

image_pull_secrets:
- regcred