Skip to content

Drone

Drone is a container-native, distributed continuous integration platform written in Go.

Installation

Docker

# Quick start with SQLite database
docker run -d \
  --volume=/var/lib/drone:/data \
  --env=DRONE_GITHUB_CLIENT_ID=your-client-id \
  --env=DRONE_GITHUB_CLIENT_SECRET=your-client-secret \
  --env=DRONE_RPC_SECRET=your-rpc-secret \
  --env=DRONE_SERVER_HOST=drone.example.com \
  --env=DRONE_SERVER_PROTO=https \
  --publish=80:80 \
  --publish=443:443 \
  --restart=always \
  --detach=true \
  --name=drone \
  drone/drone:latest

# Quick start runner
docker run -d \
  --volume=/var/run/docker.sock:/var/run/docker.sock \
  --env=DRONE_RPC_HOST=drone.example.com \
  --env=DRONE_RPC_PROTO=https \
  --env=DRONE_RPC_SECRET=your-rpc-secret \
  --env=DRONE_RUNNER_CAPACITY=2 \
  --env=DRONE_RUNNER_NAME=my-runner \
  --publish=3000:3000 \
  --restart=always \
  --detach=true \
  --name=runner \
  drone/runner-docker:latest

Docker Compose

version: '3'

services:
  drone-server:
    image: drone/drone:latest
    ports:
      - "80:80"
      - "443:443"
    volumes:
      - drone-data:/data
    environment:
      - DRONE_GITHUB_CLIENT_ID=${GITHUB_CLIENT_ID}
      - DRONE_GITHUB_CLIENT_SECRET=${GITHUB_CLIENT_SECRET}
      - DRONE_RPC_SECRET=${RPC_SECRET}
      - DRONE_SERVER_HOST=drone.example.com
      - DRONE_SERVER_PROTO=https
      - DRONE_USER_CREATE=username:admin,admin:true
    restart: always

  drone-runner:
    image: drone/runner-docker:latest
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_RPC_HOST=drone-server
      - DRONE_RPC_PROTO=http
      - DRONE_RPC_SECRET=${RPC_SECRET}
      - DRONE_RUNNER_CAPACITY=2
      - DRONE_RUNNER_NAME=docker-runner
    depends_on:
      - drone-server
    restart: always

volumes:
  drone-data:

Linux Binary

# Download latest release
curl -L https://github.com/harness/drone/releases/latest/download/drone_linux_amd64.tar.gz | tar zx

# Move to PATH
sudo install -t /usr/local/bin drone

# Start server
drone server --github-client-id=xxx --github-client-secret=yyy

Basic Commands

# Version information
drone --version

# Help and documentation
drone --help
drone build --help

# Drone info and health check
drone info
drone health

Pipeline Configuration

.drone.yml Basic Structure

---
kind: pipeline
type: docker
name: default

steps:
  - name: build
    image: golang:1.21
    commands:
      - go build
      - go test

  - name: publish
    image: plugins/docker
    settings:
      registry: docker.io
      repo: myuser/myapp
      tags: latest
    when:
      branch: main
      event: push

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

Matrix Builds

---
kind: pipeline
type: docker
name: default

steps:
  - name: test
    image: golang:${GO_VERSION}
    commands:
      - go test ./...

matrix:
  GO_VERSION:
    - 1.19
    - 1.20
    - 1.21

Conditional Execution

---
kind: pipeline
type: docker
name: default

steps:
  - name: build
    image: golang:1.21
    commands:
      - go build

  - name: publish
    image: plugins/docker
    settings:
      repo: myuser/myapp
    when:
      status: success
      branch: main

  - name: notify-failure
    image: plugins/slack
    settings:
      webhook: ${SLACK_WEBHOOK}
      message: "Build failed"
    when:
      status: failure

Drone Cloud/Enterprise Plugins

# Docker image building
image: plugins/docker
settings:
  registry: gcr.io
  repo: gcr.io/project/image
  dockerfile: Dockerfile
  tags: latest

# Kubernetes deployment
image: plugins/kubernetes
settings:
  kubeconfig: ${KUBE_CONFIG}
  deployment: myapp
  image_pull_policy: IfNotPresent

# Slack notifications
image: plugins/slack
settings:
  webhook: ${SLACK_WEBHOOK}
  channel: #deployments
  message: "Deployment successful"

# GitHub status updates
image: plugins/github-status
settings:
  api_key: ${GITHUB_TOKEN}

CLI Operations

# Build commands
drone build ls                     # List builds
drone build info <repo> <build>   # Get build details
drone build log <repo> <build>    # View build logs
drone build retry <repo> <build>  # Retry failed build
drone build kill <repo> <build>   # Cancel running build

# Repository management
drone repo ls                      # List repositories
drone repo info <repo>            # Repository details
drone repo enable <repo>          # Enable repository
drone repo disable <repo>         # Disable repository
drone repo update <repo>          # Update repository settings
drone repo repair <repo>          # Repair repository

# Secret management
drone secret ls <repo>            # List secrets
drone secret get <repo> <secret>  # Get secret value
drone secret set <repo> <secret> <value>  # Create/update secret
drone secret delete <repo> <secret>       # Delete secret

# User management
drone user ls                      # List users
drone user add <username>         # Add user
drone user remove <username>      # Remove user
drone user admin <username>       # Grant admin access

Secrets Management

Create Secrets

# Repository secrets
drone secret set myrepo MY_SECRET "secret_value"
drone secret set myrepo DOCKER_USERNAME "myuser"
drone secret set myrepo DOCKER_PASSWORD "mypass"

# Organization secrets (Enterprise)
drone secret set --org myorg MY_SECRET "secret_value"

# Set secret with image restriction
drone secret set --pull-request myrepo SECRET "value"  # Only in PRs

# Set secret with branch restriction
drone secret set --event push myrepo SECRET "value"    # Only on push events

Use Secrets in Pipeline

---
kind: pipeline
type: docker
name: default

steps:
  - name: build
    image: golang:1.21
    environment:
      CGO_ENABLED: 0
    commands:
      - go build

  - name: publish
    image: plugins/docker
    environment:
      MY_TOKEN:
        from_secret: github_token
    settings:
      registry: gcr.io
      repo: gcr.io/project/image
      username:
        from_secret: docker_username
      password:
        from_secret: docker_password
      tags: latest

Drone Plugins

Docker Plugin

- name: publish
  image: plugins/docker
  settings:
    registry: docker.io
    repo: myuser/myapp
    username:
      from_secret: docker_username
    password:
      from_secret: docker_password
    tags:
      - latest
      - v1.0.0
    dockerfile: Dockerfile
    context: .
    build_args:
      - VERSION=1.0.0

Git Plugin

- name: clone-private-repo
  image: plugins/git
  settings:
    depth: 10
    skip_verify: false
    submodules: true

S3 Plugin

- name: upload-artifacts
  image: plugins/s3
  settings:
    bucket: my-bucket
    access_key:
      from_secret: aws_access_key
    secret_key:
      from_secret: aws_secret_key
    region: us-east-1
    source: build/**/*
    target: /build/${DRONE_BUILD_NUMBER}
    strip_prefix: build

Slack Plugin

- name: notify
  image: plugins/slack
  settings:
    webhook:
      from_secret: slack_webhook
    channel: "#builds"
    username: Drone
    template: |
      Build #{{ build.number }} {{ build.status }} for {{ build.commit }}
      {{ build.link }}

Kubernetes Plugin

- name: deploy-k8s
  image: plugins/kubernetes
  settings:
    kubeconfig:
      from_secret: kube_config
    namespace: production
    deployment: myapp
    image_pull_policy: IfNotPresent
    update_strategy: rolling

Configuration Examples

Python Project

---
kind: pipeline
type: docker
name: python

steps:
  - name: test
    image: python:3.11
    commands:
      - pip install -r requirements.txt
      - pytest
      - black --check .
      - flake8 .

  - name: build
    image: python:3.11
    commands:
      - python setup.py build
    when:
      branch: main

  - name: publish
    image: plugins/docker
    settings:
      registry: gcr.io
      repo: gcr.io/myproject/myapp
      tags: latest
    when:
      branch: main
      event: push

Node.js Project

---
kind: pipeline
type: docker
name: nodejs

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

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

  - name: security
    image: node:18
    commands:
      - npm audit

  - name: publish-npm
    image: plugins/npm
    settings:
      registry: https://registry.npmjs.org
      token:
        from_secret: npm_token
    when:
      branch: main
      event: tag

Go Project

---
kind: pipeline
type: docker
name: golang

steps:
  - name: test
    image: golang:1.21
    environment:
      CGO_ENABLED: 0
    commands:
      - go test -v -race ./...
      - go vet ./...

  - name: build
    image: golang:1.21
    environment:
      CGO_ENABLED: 0
    commands:
      - go build -o myapp .
    when:
      branch: main

  - name: publish
    image: plugins/docker
    settings:
      registry: docker.io
      repo: myuser/myapp
      username:
        from_secret: docker_username
      password:
        from_secret: docker_password
      tags: latest
    when:
      branch: main
      event: push

Advanced Pipeline Features

Multi-Pipeline Configuration

---
kind: pipeline
type: docker
name: lint

steps:
  - name: lint
    image: golang:1.21
    commands:
      - go fmt ./...
      - go vet ./...

---
kind: pipeline
type: docker
name: test

steps:
  - name: unit-tests
    image: golang:1.21
    commands:
      - go test -v -race ./...

  - name: integration-tests
    image: docker:latest
    volumes:
      - name: docker
        path: /var/run/docker.sock
    commands:
      - docker run --rm alpine sh -c 'echo "integration test"'

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

depends_on:
  - lint

---
kind: pipeline
type: docker
name: build

steps:
  - name: build
    image: golang:1.21
    commands:
      - go build -o myapp .

depends_on:
  - test

Promote Builds Across Environments

# Promote build to production
drone build promote <repo> <build> production

# View build promotions
drone build info <repo> <build>

Rollback Previous Build

# Rollback to previous build
drone build rollback <repo> <build>

Environment Variables

# Drone system variables in pipelines
DRONE_BUILD_NUMBER           # Build number
DRONE_BUILD_EVENT            # Event type (push, pull_request, etc.)
DRONE_BUILD_STATUS           # Build status (success, failure)
DRONE_BUILD_LINK             # Link to build in Drone UI
DRONE_BUILD_CREATED          # Build creation timestamp
DRONE_BUILD_STARTED          # Build start timestamp
DRONE_BUILD_FINISHED         # Build finish timestamp

DRONE_COMMIT                 # Commit SHA
DRONE_COMMIT_SHA             # Full commit SHA
DRONE_COMMIT_REF             # Reference (branch/tag)
DRONE_COMMIT_BRANCH          # Branch name
DRONE_COMMIT_MESSAGE         # Commit message
DRONE_COMMIT_AUTHOR          # Commit author name
DRONE_COMMIT_AUTHOR_EMAIL    # Commit author email

DRONE_REPO                   # Repository slug
DRONE_REPO_NAME              # Repository name
DRONE_REPO_NAMESPACE         # Repository owner
DRONE_REPO_LINK              # Repository URL

DRONE_PULL_REQUEST           # Pull request number
DRONE_PULL_REQUEST_SOURCE    # Source branch
DRONE_PULL_REQUEST_TARGET    # Target branch

Troubleshooting

# Check server logs
docker logs drone

# Check runner logs
docker logs runner

# Validate pipeline YAML
drone lint .drone.yml

# Enable debug logging
DRONE_LOG_LEVEL=debug drone server

# Check repository webhook
drone repo info myrepo

# Resync repository
drone repo repair myrepo

# View build logs
drone build log myrepo 1

Best Practices

  • Use separate branches for different deployment environments
  • Always validate pipeline YAML with drone lint before committing
  • Store sensitive credentials in Drone secrets, never in .drone.yml
  • Use specific image versions instead of latest tags
  • Implement status checks and branch protection in Git
  • Monitor build metrics and set up failure notifications
  • Use pipeline conditions to control when steps run
  • Document complex pipelines with inline comments
  • Test pipeline changes in a branch before merging
  • Regularly review and clean up old pipelines

Resources


Last updated: 2025-03-30