CI/CD & DevOps
Container-native continuous integration platform with simple YAML configuration
Every build step runs in isolated Docker containers for clean, reproducible builds without dependencies
Pipeline as code with easy-to-understand YAML syntax stored in your repository
Hundreds of plugins for deploying, notifications, testing, and integrating with any service
Horizontal scaling with multiple runner nodes, automatically provision/deprovision based on queue depth
First-class support for GitHub, GitLab, Bitbucket, Gitea with OAuth and webhook automation
Encrypted secrets storage with fine-grained access control per repository or organization
# Install Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh
# Add current user to docker group
sudo usermod -aG docker $USER
newgrp docker
# Verify installation
docker --version2. Create Drone Server Configuration:# Create directory for Drone
sudo mkdir -p /var/lib/drone
sudo chown -R $USER:$USER /var/lib/drone
# Create environment file
cat > /var/lib/drone/.env <<'EOF'
# Drone Server Settings
DRONE_SERVER_HOST=drone.yourdomain.com
DRONE_SERVER_PROTO=https
DRONE_RPC_SECRET=$(openssl rand -hex 16)
DRONE_DATABASE_DRIVER=sqlite3
DRONE_DATABASE_DATASOURCE=/data/database.sqlite
# GitHub Integration (or use GitLab/Bitbucket)
DRONE_GITHUB_CLIENT_ID=your_github_oauth_app_id
DRONE_GITHUB_CLIENT_SECRET=your_github_oauth_secret
# Admin user (your GitHub username)
DRONE_USER_CREATE=username:yourgithubusername,admin:true
# Optional: Enable registration
DRONE_REGISTRATION_CLOSED=false
EOF3. Generate RPC Secret:# Generate a secure RPC secret
openssl rand -hex 16
# Update DRONE_RPC_SECRET in .env file4. Set Up GitHub OAuth Application:docker run --volume=/var/lib/drone:/data --env-file=/var/lib/drone/.env --publish=8080:80 --publish=443:443 --restart=always --detach=true --name=drone drone/drone:26. Verify Drone Server:# Check container status
docker ps | grep drone
# Check logs
docker logs drone
# Test web interface
curl http://localhost:80807. Install Drone Runner (Docker Runner):docker run --detach --volume=/var/run/docker.sock:/var/run/docker.sock --env=DRONE_RPC_PROTO=http --env=DRONE_RPC_HOST=localhost:8080 --env=DRONE_RPC_SECRET=your_rpc_secret_from_env --env=DRONE_RUNNER_CAPACITY=2 --env=DRONE_RUNNER_NAME=my-first-runner --publish=3000:3000 --restart=always --name=runner drone/drone-runner-docker:18. Configure Nginx Reverse Proxy (Production):sudo nano /etc/nginx/sites-available/drone
# Add this configuration:
server {
listen 80;
server_name drone.yourdomain.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}
# Enable site
sudo ln -s /etc/nginx/sites-available/drone /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx9. Set Up SSL with Let's Encrypt:sudo apt install certbot python3-certbot-nginx -y
sudo certbot --nginx -d drone.yourdomain.com10. Create Sample Pipeline (.drone.yml):kind: pipeline
type: docker
name: default
steps:
- name: test
image: node:18
commands:
- npm install
- npm test
- name: build
image: node:18
commands:
- npm run build
- name: docker
image: plugins/docker
settings:
repo: yourusername/yourapp
tags: latest
username:
from_secret: docker_username
password:
from_secret: docker_password
when:
branch:
- main11. Add Repository:# Install Drone CLI
curl -L https://github.com/harness/drone-cli/releases/latest/download/drone_linux_amd64.tar.gz | tar zx
sudo install -t /usr/local/bin drone
# Configure CLI
export DRONE_SERVER=https://drone.yourdomain.com
export DRONE_TOKEN=your_user_token_from_ui
# Add secrets
drone secret add --repository yourusername/yourrepo --name docker_username --data yourvalue
drone secret add --repository yourusername/yourrepo --name docker_password --data yourvalue
# Core Settings
DRONE_SERVER_HOST=drone.example.com
DRONE_SERVER_PROTO=https
DRONE_RPC_SECRET=supersecretkey
# Database
DRONE_DATABASE_DRIVER=postgres
DRONE_DATABASE_DATASOURCE=postgres://user:pass@localhost:5432/drone?sslmode=disable
# VCS Integration (GitHub example)
DRONE_GITHUB_CLIENT_ID=github_oauth_app_id
DRONE_GITHUB_CLIENT_SECRET=github_oauth_secret
# User Management
DRONE_USER_CREATE=username:admin,admin:true
DRONE_USER_FILTER=organization_name # Only allow specific org2. Pipeline Configuration (.drone.yml) - Basic:kind: pipeline
type: docker
name: build-test-deploy
steps:
- name: install
image: node:18
commands:
- npm ci
- name: test
image: node:18
commands:
- npm test
- npm run lint
- name: build
image: node:18
commands:
- npm run build
- name: deploy
image: plugins/ssh
settings:
host: production.example.com
username: deploy
key:
from_secret: ssh_private_key
script:
- cd /var/www/app
- git pull
- npm install
- pm2 restart app
when:
branch:
- main3. Matrix Builds (Multiple Versions):kind: pipeline
type: docker
name: matrix-test
steps:
- name: test
image: python:${PYTHON_VERSION}
commands:
- pip install -r requirements.txt
- pytest
matrix:
PYTHON_VERSION:
- "3.8"
- "3.9"
- "3.10"
- "3.11"4. Docker Build and Push:kind: pipeline
type: docker
name: docker-build
steps:
- name: build-and-push
image: plugins/docker
settings:
repo: username/myapp
tags:
- latest
- ${DRONE_COMMIT_SHA:0:8}
username:
from_secret: docker_username
password:
from_secret: docker_password
dockerfile: Dockerfile
context: .5. Kubernetes Deployment:kind: pipeline
type: docker
name: k8s-deploy
steps:
- name: deploy-to-k8s
image: sinlead/drone-kubectl
settings:
kubernetes_server: https://k8s.example.com
kubernetes_token:
from_secret: k8s_token
kubernetes_cert:
from_secret: k8s_cert
commands:
- kubectl set image deployment/myapp myapp=username/myapp:${DRONE_COMMIT_SHA}
- kubectl rollout status deployment/myapp
when:
branch:
- main6. Conditional Execution:kind: pipeline
type: docker
name: conditional-deploy
steps:
- name: deploy-staging
image: plugins/ssh
commands:
- deploy to staging
when:
branch:
- develop
- name: deploy-production
image: plugins/ssh
commands:
- deploy to production
when:
branch:
- main
event:
- push
- tag
- name: deploy-on-tag
image: plugins/ssh
commands:
- deploy release
when:
event:
- tag
ref:
- refs/tags/v*7. Services (Database, Redis for Testing):kind: pipeline
type: docker
name: integration-tests
services:
- name: postgres
image: postgres:14
environment:
POSTGRES_USER: testuser
POSTGRES_PASSWORD: testpass
POSTGRES_DB: testdb
- name: redis
image: redis:7
steps:
- name: test
image: python:3.11
environment:
DATABASE_URL: postgres://testuser:testpass@postgres:5432/testdb
REDIS_URL: redis://redis:6379
commands:
- pip install -r requirements.txt
- pytest tests/integration/8. Secrets Management:# Via CLI
drone secret add --repository user/repo --name aws_access_key --data value
drone secret add --repository user/repo --name aws_secret_key --data value
# In pipeline
kind: pipeline
type: docker
name: default
steps:
- name: deploy
image: plugins/s3
settings:
access_key:
from_secret: aws_access_key
secret_key:
from_secret: aws_secret_key
bucket: my-bucket
source: dist/**/*9. Caching Dependencies:kind: pipeline
type: docker
name: cached-build
steps:
- name: restore-cache
image: drillster/drone-volume-cache
volumes:
- name: cache
path: /cache
settings:
restore: true
mount:
- ./node_modules
- name: build
image: node:18
commands:
- npm ci
- npm run build
- name: rebuild-cache
image: drillster/drone-volume-cache
volumes:
- name: cache
path: /cache
settings:
rebuild: true
mount:
- ./node_modules
volumes:
- name: cache
host:
path: /var/lib/drone/cache10. Notifications (Slack, Email):kind: pipeline
type: docker
name: notify
steps:
- name: build
image: node:18
commands:
- npm run build
- name: slack
image: plugins/slack
settings:
webhook:
from_secret: slack_webhook
channel: deployments
template: >
{{#success build.status}}
✅ Build #{{build.number}} succeeded. Branch: {{build.branch}}
{{else}}
❌ Build #{{build.number}} failed. Branch: {{build.branch}}
{{/success}}
when:
status:
- success
- failureBest Practices:Get started in minutes with our simple VPS deployment process
Deploy in about 2 minutes • Full root access • Support by ticket and email