
Table of Contents
By Khimananda Oli | Last reviewed: August 2026
Teams adopting Drone CI: Getting Started often struggle because they expect a traditional Jenkins-like setup, but Drone is fundamentally different: it is container-native, declarative, and ephemeral by design. This guide cuts through the noise to show you exactly how to install, configure, and secure a production-grade Drone instance in 2026, whether on a single VPS or a Kubernetes cluster. We will move from zero to a working pipeline that handles secrets safely and integrates with your existing Git workflow, avoiding common pitfalls I have seen derail deployments across Nepal and global teams.
How do you install and configure Drone CI for production?
For Drone CI: Getting Started, the most critical decision is choosing between a Docker-based runner for simplicity or a Kubernetes runner for scale. In my experience helping Nepali startups and enterprise teams, starting with Docker on a dedicated VPS is usually the right call until you hit concurrent build limits. Never run the Drone server and runner on the same host in production; resource contention during builds will starve the API, causing webhook timeouts and stuck pipelines.
Deploying the Drone Server
The server is lightweight but stateful. You must persist the database and configure OAuth correctly. Below is a production-ready docker-compose.yml snippet for a GitHub integration. Note that we explicitly set DRONE_RPC_SECRET—this is the shared token runners use to authenticate. Generate it with openssl rand -hex 16.
<!-- docker-compose.yml -->
services:
drone-server:
image: drone/drone:2.25
ports:
- "8080:80"
- "8443:443"
volumes:
- drone-data:/data
environment:
- DRONE_GITHUB_CLIENT_ID=${GITHUB_OAUTH_CLIENT_ID}
- DRONE_GITHUB_CLIENT_SECRET=${GITHUB_OAUTH_CLIENT_SECRET}
- DRONE_RPC_SECRET=${SHARED_SECRET}
- DRONE_SERVER_HOST=ci.yourdomain.com
- DRONE_SERVER_PROTO=https
- DRONE_DATABASE_DRIVER=postgres
- DRONE_DATABASE_DATASOURCE=postgres://drone:password@db:5432/drone?sslmode=disable
restart: always
db:
image: postgres:16-alpine
volumes:
- pg-data:/var/lib/postgresql/data
environment:
- POSTGRES_USER=drone
- POSTGRES_PASSWORD=password
- POSTGRES_DB=drone A common mistake in Drone CI: Getting Started tutorials is omitting the reverse proxy configuration. Drone expects to be behind TLS. If you are using Nginx, ensure you pass X-Forwarded-Proto and X-Forwarded-For headers, otherwise OAuth redirects will fail with a mismatch error. For teams managing infrastructure as code, I recommend wrapping this in Terraform or Ansible rather than manual compose files; see our guide on Infrastructure as Code with Terraform for patterns that prevent configuration drift.
Connecting the Runner
The runner polls the server for work. It does not need inbound network access, only outbound HTTPS. This makes it ideal for private networks or hybrid setups where build infrastructure sits behind a firewall.
<!-- runner-compose.yml on separate host -->
services:
drone-runner:
image: drone/drone-runner-docker:1.8
command: agent
restart: always
environment:
- DRONE_RPC_PROTO=https
- DRONE_RPC_HOST=ci.yourdomain.com
- DRONE_RPC_SECRET=${SHARED_SECRET}
- DRONE_RUNNER_CAPACITY=4
- DRONE_RUNNER_NAME=prod-runner-01
volumes:
- /var/run/docker.sock:/var/run/docker.sock Set DRONE_RUNNER_CAPACITY based on available CPU cores minus one. Over-provisioning capacity leads to OOM kills during parallel test suites. If you need more isolation or are running untrusted code, switch to the Kubernetes runner, which spawns pods instead of sibling containers. For local development or testing pipeline syntax before pushing, consider Minikube vs Kind to validate runner behavior without cloud costs.
How do you write effective Drone CI pipelines?
Pipeline definitions live in .drone.yml at the repo root. The YAML structure is strict: kind, type, name, steps. Every step is a container. There is no implicit shell environment carried between steps; if you need artifacts, you must use volumes or workspace persistence explicitly. This ephemerality is a feature, not a bug—it prevents flaky builds caused by leftover state.
Basic Pipeline Structure
Here is a realistic Node.js pipeline that installs dependencies, runs tests, and builds a Docker image. Notice the volumes section: without it, node_modules would vanish between the install and test steps.
kind: pipeline
type: docker
name: default
steps:
- name: install
image: node:20-alpine
commands:
- npm ci
- name: test
image: node:20-alpine
commands:
- npm test
depends_on: [install]
- name: build-image
image: plugins/docker
settings:
repo: registry.example.com/myapp
tags: latest
when:
branch: main
event: push
volumes:
- name: deps
temp: {} In practice, pin your base images to specific digests or minor versions (node:20.11-alpine) rather than floating tags. Floating tags are the #1 cause of "it worked yesterday" failures. Also, note the depends_on field: Drone runs steps sequentially by default, but explicit dependencies make the graph clear and enable future parallelization safely.
Leveraging Plugins vs Custom Scripts
Drone’s plugin ecosystem is vast, but vetting is essential. Official plugins (plugins/docker, plugins/s3) are maintained and signed. Community plugins vary in quality. When a plugin doesn’t exist, write a simple shell script in a standard Alpine container rather than forking an abandoned plugin. For complex deployments, especially to Kubernetes, integrating with GitOps with ArgoCD is often superior to direct deployment steps in CI, as it provides audit trails and drift detection that CI scripts lack.
How do you manage secrets securely in Drone CI?
Security is non-negotiable in Drone CI: Getting Started. Never hardcode credentials in .drone.yml. Drone has a built-in secrets manager accessible via CLI and UI. Secrets are encrypted at rest in the database and injected into containers as environment variables only for allowed events (e.g., exclude pull requests from forks).
- Add via CLI:
drone secret add --repository owner/repo --name DOCKER_PASSWORD --data "mypassword". This avoids shell history exposure. - Restrict Events: Always uncheck "Pull Request" for deployment secrets. Forked PRs could exfiltrate secrets if exposed.
- Use External Vaults: For SOC 2 or ISO 27001 compliance, integrate HashiCorp Vault or AWS Secrets Manager via the
from_secretsyntax combined with external secret operators. This centralizes rotation and audit logs outside Drone’s database. - Mask Output: Drone automatically masks values matching known secrets in logs, but custom scripts can accidentally leak partial matches. Use
echo "::add-mask::$VAR"equivalent patterns or avoid echoing sensitive vars entirely.
If you are handling database credentials for staging environments, review our guide on handling secrets in CI/CD for advanced rotation strategies and least-privilege IAM patterns that apply directly to Drone runners.
How does Drone CI compare to Jenkins and GitHub Actions?
Choosing the right tool depends on your team’s operational maturity and infrastructure constraints. Drone occupies a unique middle ground: more flexible than SaaS-only options, lighter than Jenkins.
| Feature | Drone CI | Jenkins | GitHub Actions |
|---|---|---|---|
| Configuration | Declarative YAML (.drone.yml) | Groovy / Declarative Pipeline | YAML Workflows |
| Execution Model | Ephemeral Containers (Native) | Persistent Agents / VMs | Managed VMs / Self-hosted |
| Setup Complexity | Low (Single binary/container) | High (Plugins, JVM tuning) | Zero (SaaS) / Medium (Self-hosted) |
| Secret Management | Built-in + Vault Integration | Credentials Store + Plugins | Encrypted Secrets + Environments |
| Best For | Container-native, Hybrid Cloud | Legacy Enterprise, Complex Logic | GitHub-centric Teams, SaaS Speed |
In 2026, Drone wins when you need self-hosted control without Jenkins’ maintenance burden. It loses to GitHub Actions for pure open-source projects where free SaaS minutes suffice. For teams in Nepal with intermittent internet or data residency requirements, Drone’s self-hosted model ensures builds continue even during upstream outages, provided your Git cache is configured.
Next Steps for Your Drone CI Journey
Getting Drone CI: Getting Started right means treating it as infrastructure, not just a config file. Start with a single runner, enforce secret hygiene from day one, and pin all image versions. As you scale, monitor runner queue depth and build duration using Prometheus exporters—observability is as critical here as in any microservice. If you are evaluating this for a team in Nepal or globally and need help designing a secure, compliant pipeline architecture, reach out to discuss your specific requirements. A well-tuned Drone instance should feel invisible; if you are fighting it, something in the foundation needs adjustment.