Image for post
Image for post
The pretty archaic Drone UI — but that’s all you need with Drone.

Introduction

We have been using Drone CI in our project for some months now. Recently I had to do a major refactoring regarding my team’s Drone pipelines so I thought that now that the Drone configurations are rather fresh in my memory I could write a blog post regarding my experiences with the Drone CI. So, here are my experiences using Drone CI as a developer — if you are looking for sysops stuff like how to install Drone CI, how to do authentication, etc. I’m not writing about that stuff and you need to read e.g. the official Drone documentation.

Drone CI Basics

I’m not going to give a lecture about Drone, you can read more about Drone in Drone CI home page but instead, I write about some important aspects about Drone CI regarding my experiences as a developer who maintains Drone pipelines and uses Drone to build and deploy applications as a daily basis.

Drone uses container architecture. This means that the Drone orchestrator is running in a Docker container and all steps in the Drone pipeline will trigger a new container that provides a nice isolated environment for that particular pipeline step. An example pipeline is depicted below:

It’s jsonnet and quite readable as is. You can read that it’s a pipeline meant to be run inside Kubernetes. The pipeline is triggered when a feature branch is pushed into the Git repository. I strongly recommend using jsonnet instead of yaml since you can use e.g. kind of “variables” (as the featureBranchPattern in the example above), “functions” (as the buildApps in the example above) and “branching constructs”(e.g. if). Jsonnet provides a lot better configuration language to template common parts of the pipeline, provide constants, etc.

You can basically use any Docker image in your Drone steps, i.e. basic Docker images from Docker Hub (e.g. we are using Docker Compose image to setup database, S3 simulator, various dependencies etc in tests), customized Docker images, i.e. Drone Plugins, meant to be used with Drone to do some specialized task (e.g. we are using AWS ECR Plugin to build images and push them to AWS ECR registry) or you can use your own custom built Docker images.

You can use Linux shell (e.g. bash) when writing Pipeline steps. The example below shows some simple bashing in a Drone pipeline step.

As you can see writing steps is pretty familiar using your favorite Linux shell. You can use any Docker image for the pipeline step, and inside the step do basically anything you can do in any Docker container. You could do the building also in a docker container, using some dind (Docker in Docker) image, and build Docker images and start containers there.

Developing Drone pipelines and steps is rather easy since you can use local drone exec to simulate your pipelines in your own workstation, e.g.

… and you can see drone exec starting the build process in your workstation:

Once you are confident your pipeline works in your own workstation you can push your branch to Git and let Drone server in your CI environment run the exactly same pipeline exactly the same way.

During the Drone pipeline Drone keeps a kind of environment which is shared between the steps. E.g. the git repo is checked into a certain directory which is automatically mounted to every step (docker container). This way you can refer to the same code directory structure in every container and also store more permanent artifacts (e.g. built jar files) into that directory structure (e.g. later on some other step builds a Docker image and bakes the jar (you built in some previous step) into the docker image.). You can also create e.g. Docker networks (e.g. using Docker Compose) in some previous step and spin some testing in another step using some other docker container running in the same network.

Running tests is pretty nice with Drone. Example:

So, first we start two containers in a docker-compose setup: Postgres (DB) and Minio (simulating S3 bucket). Then we run our tests in another container — the image that was built specifically to run tests of that application (but requires Postgres and Minio to be up and running during tests).

Some Observations

In this chapter I list some special observations I noted when using Drone.

Caching. Caching might be a bit challenging since your Drone executor spins up ephemeral Docker containers for steps and those containers die when their job is done. You can however cache e.g. node modules, maven depencies etc but you have to plan it a bit in the steps. The easiest way might be to download those dependencies in the working directory and at the end of the pipeline store the dependencies e.g. to AWS S3 where those dependencies can be stored using a specialized Drone Plugin (AWS S3 Cache).

Users and rights. Images from Docker hub use various built-in users which might not be the ones you’d like to have. Your actual CI environment might also cause some other aspects that need to be taken into consideration. Personally I found the easiest solution to be just use some specific user and make all steps to use that user, e.g. user in the example below:

Debugging tricks. A simple debugging trick is to put a temporary “stop the world” command inside the step:

… and watch it stop:

… then get a shell session inside the container and do debugging there…

Comparing Jenkins and Drone

I have mostly used Jenkins the previous years as my CI server. When comparing my Jenkins and Drone experiences I kind of like Drone more for the following reasons:

  • Shell scripting. As you could see in the examples above you can write your pipeline steps using simple shell commands inside container, and do basically anything you like in those steps. You don’t have to use some “language that is a bit like Groovy but not quite”, I guess you know what I mean.
  • Containers. Containers provide a nice isolated place for your builds and they are also rather nice to debug once you understand the basic Drone container based architecture. Debugging Jenkins builds are of course rather easy, since you can always just get a ssh session to the Jenkins server and go to the Jenkins workplace directory and experiment there.
  • Local development. drone exec is a real nice tool to develop your CI pipelines. And if you follow some practices (e.g. the same user in all steps…) your local pipeline runs are exactly the same way as your Drone server runs them.
  • No UI hassle. If you want to use some specific plugins in Jenkins you can of course install them when you install Jenkins, but there are quite a lot of configurations in those plugins that you usually need to do using Jenkins UI. With Drone everything are just Docker containers, no special configurations.

Conclusions

Drone is a refreshing new CI tool which provides a pretty different architecture and model to create your build pipelines. Give it a try — I think you just might like it!

The writer is working at Metosin using Clojure in cloud projects. If you are interested to start a Clojure project in Finland or you are interested to get Clojure training in Finland you can contact me by sending email to my Metosin email address or contact me via LinkedIn.

Kari Marttila

The article was first published in https://www.karimarttila.fi/

Written by

I’m a Software architect and developer. Currently implementing systems on AWS / GCP / Azure / Docker / Kubernetes using Java, Python, Go and Clojure.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store