Drone.io: first impressions

Štěpán Vraný
5 min readJan 12, 2019

--

Even though I use Jenkins as CI/CD every day — I’m not stopping looking to its competitors. That’s why I was experimenting with Brigade.sh a few weeks ago, that’s why I was experimenting with Drone.io yesterday!

Perhaps this is an older Drone.io logo but damn, I like it so much!

Drone is a Continuous Delivery platform that helps your organization optimize and automate software delivery.
— Drone.io

High level concept

Unlike Jenkins, Drone.io is container native solution, this means that every single step is executed in the Docker container. This is similar to the concept used in Brigade.sh or Concourse.

Even the plugins are Docker containers, it means that you can write your very own plugin (in any language you want), push it to the Dockerhub and profit.

Personally, I think Container native solutions are the future. It’s just so much cleaner than scripted pipelines working on top of shared workspace!

Installation

As I’ve mentioned before, Drone.io is container native solution. So it would be a shame if the installation was not container based, right? Everything is documented here, this is single-machine scenario with Github integration which will be absolutely sufficient for basic user testing.

You basically just need to register a new application in your Github account and start a Docker container with the certain parameters. And that’s it. Translated to numbers, in the cloud era when you don’t have to hassle with the installation of computing resource you can build Drone.io node in less than 5 minutes!

Installation checklist

  • Create Virtual Machine and record its public IP address
  • Create a DNS record (required for Oauth callbacks)
  • Install Doker CE
  • Register a new application in your GitHub account
  • Run the Drone.io container according to documentation
docker run \
--volume=/var/run/docker.sock:/var/run/docker.sock \
--volume=/var/lib/drone:/data \
--env=DRONE_GITHUB_SERVER=https://github.com \
--env=DRONE_GITHUB_CLIENT_ID=<id> \
--env=DRONE_GITHUB_CLIENT_SECRET=<secret> \
--env=DRONE_RUNNER_CAPACITY=2 \
--env=DRONE_SERVER_HOST=drone.yourdomain.co.uk \
--env=DRONE_SERVER_PROTO=https \
--env=DRONE_TLS_AUTOCERT=true \
--publish=80:80 \
--publish=443:443 \
--restart=always \
--detach=true \
--name=drone \
drone/drone:1.0.0-rc.3

So simple!

Repository configuration

In the main screen of Drone.io you have to enable your repository first.

It will open a repository configuration menu which is almost as same as minimalist as the main screen.

There’s really nothing we have to think about, everything important will be written in .drone.yml file! Let’s write out first pipeline.

Pipeline basics

I have to repeat myself, everything in Drone.io is just container so the pipeline syntax reflects this fact — almost every letter there is related to the container specification. Neat.

The basic Hello World example

kind: pipeline
name: default
steps:
- name: hello
image: alpine
commands:
- echo Hello World!

becomes this when we push to the master branch

Conditions

Each pipeline step can be configured to be triggered only by certain events or in certain branches. You can find documentation for the whole topic here. This is typically useful for pull request events when you want to run some tests without building the final image etc.

kind: pipeline
name: default
steps:
- name: test
image: node:10.14.2
commands:
- npm install
- npm run test
when:
event:
- push
- pull_request
- name: build-docker-image
image: alpine
err_ignore: true
commands:
- echo Building image
when:
event:
- push
branch:
- master
- stage
- development

So in this example, every event will trigger “test” step but “build-docker-image” will be triggered only by pushing to master, stage or development. Let’s test it with pull request.

First we have to open a new PR

Which will produce following output

See? Pipeline step “build-docker-image” was not triggered. Now let’s merge these branches.

Bingo! Our dummy “build-docker-image” step is triggered only by push events.

Secrets management

Drone.io also supports secrets management, it means that you can keep your API keys out from the version control system. You just need to create a new secret in the repository settings

and refer it in the pipeline like this

steps:
- name: build
image: alpine
environment:
GCP_SERVICE_ACCOUNT_KEY:
from_secret: gpc_service_account

Drone.io should also support Vault integration but I’ve not tested it yet. But if this is true — it’s killing feature 😉

Promotion

Sometimes you don’t want to deploy new build automatically, you know, things can get messy. For those cases, Drone.io introduces a special event: promotion. This event has to be triggered from the Drone CLI (available for all major platforms) and the timeline of usage is following:

  • push event with number XY
  • build has finished successfully
  • promotion of build number XY to the given environment

As I said, promotion is just another event so you can add conditions for this particular event. See the example.

CLI command:

drone build promote vranystepan/drone-hello-world 48 production

Pipeline step:

- name: deploy-production
image: alpine
commands:
- echo deploy-production!
when:
event:
- promote
target:
- production

Conclusion

I think Drone.io is the very competitive product that can cover almost every CI/CD use case. There might be some concerns from Jenkins users who are used to create complicated scripted pipelines with dozens of plugins but this is the matter for some comparison article (and this is not my goal to do that).

I’m very impressed by the simplicity of the whole product. For the Jenkins user, this is a whole new universe 😀 Can’t wait to test with some real project!

Do you have any tips or comments? Do not hesitate to leave a comment in the discussion!

Edit #1: you can even specify multiple pipelines for different events in the single file!

kind: pipeline
name: nodejs-cd
clone:
disable: false
steps:
- name: test
image: node:10.14.0
err_ignore: true
commands:
- echo cd works.
trigger:
branch:
- master
- stage
- development
event:
- push
---
kind: pipeline
name: nodejs-ci
clone:
disable: false
steps:
- name: test
image: node:10.14.0
err_ignore: true
commands:
- echo ci works.
trigger:
event:
- pull_request

--

--