Operations 16 min read

How to Replace Travis CI with Drone: A Step‑by‑Step Docker‑Based CI Guide

This article walks you through replacing Travis CI with Drone, covering Docker‑based installation, configuration of docker‑compose, Nginx reverse proxy, systemd service, pipeline‑as‑code with .drone.yml, secret management, troubleshooting tips, and a concise summary of Drone's strengths and limitations.

360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
360 Zhihui Cloud Developer
How to Replace Travis CI with Drone: A Step‑by‑Step Docker‑Based CI Guide

Introduction

The author, a former front‑end engineer at Qiwu Group and creator of the Firekylin blog platform, shares his experience using Drone.io to replace Travis CI for daily development CI tasks.

Why Choose Drone

After comparing several CI products, Drone was selected because it is an open‑source CI platform written in Go, can be self‑hosted, supports common Git repositories (GitHub, GitLab, Bitbucket, Gogs, etc.), and offers native Docker support, pipeline‑as‑code, and a rich plugin ecosystem.

Key Features

Native Docker Support – No need to add Docker commands in build scripts; plugins are Docker images, providing environment isolation and modularity.

Server‑Agent Architecture – Separate server and agent components allow easy horizontal scaling.

Pipeline as Code – A .drone.yml file in the project root defines the pipeline and is version‑controlled.

Simple Pipeline Example

<code>pipeline:
  build:
    image: node:6.6.0
    commands:
      - npm install --silent
      - npm test
</code>

This configuration builds the project using a Node image and runs tests.

Installation and Configuration

Drone is installed using Docker and docker‑compose. First, install Docker and docker‑compose on the host (Debian example shown). Then create a docker-compose.yml defining drone-server and drone-agent services, set environment variables for repository credentials, and expose ports.

<code>version: '2'
services:
  drone-server:
    image: drone/drone:0.8.2
    ports:
      - 3800:8000
      - 9000
    volumes:
      - /etc/drone:/var/lib/drone/
    restart: always
    environment:
      - DRONE_OPEN=true
      - DRONE_HOST=http://ci.example.com
      - DRONE_GITHUB=true
      - DRONE_GITHUB_CLIENT=xxxxx
      - DRONE_GITHUB_SECRET=xxxxx
      - DRONE_SECRET=xxxxx
  drone-agent:
    image: drone/agent:0.8.2
    command: agent
    restart: always
    depends_on:
      - drone-server
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
    environment:
      - DRONE_SERVER=drone-server:9000
      - DRONE_SECRET=xxxxx
</code>

Generate a random secret with LC_ALL=C </dev/urandom tr -dc A-Za-z0-9 | head -c 65 && echo . Start the services with docker-compose -f /etc/drone/docker-compose.yml up , then configure Nginx as a reverse proxy to expose Drone on port 80.

<code>map $http_upgrade $connection_upgrade {
  default upgrade;
  ''      close;
}
server {
  listen 80;
  server_name ci.example.com;
  set $drone_port 3800;
  location / {
    proxy_set_header X-Forwarded-For $remote_addr;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header Host $http_host;
    proxy_pass http://127.0.0.1:$drone_port;
    proxy_http_version 1.1;
    proxy_buffering off;
  }
  location ~* /ws {
    proxy_pass http://127.0.0.1:$drone_port;
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_read_timeout 86400;
  }
}
</code>

For daemonizing the service, use nohup docker-compose -f docker-compose.yml up &amp; or create a systemd unit file ( /etc/systemd/system/drone.service ) that starts and stops Drone via docker‑compose.

<code>[Unit]
Description=Drone server
After=docker.service nginx.service
[Service]
Restart=always
ExecStart=/usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml up
ExecStop=/usr/local/bin/docker-compose -f /etc/drone/docker-compose.yml stop
[Install]
WantedBy=multi-user.target
</code>

Secrets Management

To avoid exposing sensitive data (e.g., Telegram bot token) in .drone.yml , use Drone’s secret feature. Define secrets in the UI or via drone secrets add and reference them in the pipeline.

<code>telegram:
  image: appleboy/drone-telegram
  secrets: [telegram_token, telegram_to]
  token: ${TELEGRAM_TOKEN}
  to: ${TELEGRAM_TO}
</code>

Troubleshooting

If a build exits with code 137, it is typically killed by the Docker OOM killer due to insufficient memory. Increasing the host memory (e.g., to 2 GB) resolves the issue.

Conclusion

Drone provides a clean, Docker‑native CI workflow that meets most CI needs, though documentation fragmentation, a smaller community, and a minimal front‑end UI are current drawbacks.

Dockerci/cddevopspipelineSecretsDrone CI
360 Zhihui Cloud Developer
Written by

360 Zhihui Cloud Developer

360 Zhihui Cloud is an enterprise open service platform that aims to "aggregate data value and empower an intelligent future," leveraging 360's extensive product and technology resources to deliver platform services to customers.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.