Will & Skill Developers

Will & Skill Developers


Thoughts, snippets and ideas from the team at Will & Skill AB, Stockholm.

Erik Svedin
Author

Share


W&S devops part 2 - Setting up a Continuous Integration (CI) server using Docker and drone.io

Erik SvedinErik Svedin

Welcome to part 2 in this series where we look at different tools and techniques to help create a better workflow for your development. In this tutorial we'll look at how we can install and configure our very own Continuous Integration server.

More specifically we'll be:
1. Installing docker on and drone.io on a server running ubuntu 14.04
2. Setting up drone.io integration with github

Introducing drone.io

First of a couple of words about drone: Like a couple of other CI services it is open source and you can find all the code over at github/drone/drone.

What I think is one of the biggest things about it, is that it's built on docker, which makes it very easy to install and get running. Also it actually executes all of your builds inside docker containers. Which is a great thing if you have a bunch of different projects using different languages and configs. You can use a wide range of official docker images for languages like python, go, node or whatever. Or even create your very own custom Docker image.

More info about drone.io can be found in this official blogpost

So without further ado, lets get to it:

Setting up server and installing Docker

First of we need to create our server and install the single dependency to drone.io: Docker. For the server creation I'm using Digitalocean to create a droplet with Ubuntu 14.04 installed and my SSH key already on it.

When we got the server created lets install Docker. You can check out the official documentation on how to install Docker. OR, what better way is there to continue where we left of the previous part of the series (introducing Ansible), than to continue using Ansible? So lets do that instead.

First of Vagrant is not here to help anymore so we will need to manually create our ansible.cfg and hostfile:

Example ansible.cfg:

[defaults]
remote_user           = SSH_USER_NAME  
private_key_file      = ~/.ssh/id_rsa

# aka inventory file
hostfile = ./ansible_inventory  

Example hostfile (ansible_inventory):

docker-drone ansible_ssh_host=YOUR_SERVER_IP ansible_ssh_port=22  

Using the Ansible Galaxy

Next thing we need to create the roles with the appropriate tasks to install Docker, and call it with a playbook. Good thing there is actually something called the Ansible Galaxy. This is a place where you can find ready made roles, that people uploaded for you to use. Open source really is a beautiful thing isn't it?
For more info about the role being used you can actually find a complete blogpost about it

Installing the docker_ubuntu role:

 ansible-galaxy install angstwad.docker_ubuntu

Now we can create our playbook to make use of the installed role. Create a file provision/provisioner.yml and add the following:

- hosts: docker-drone
  sudo: yes
  roles:
      - angstwad.docker_ubuntu

You can now call this playbook to install Docker:

$ ansible-playbook provision/provisioner.yml

Assuming you didn't run in to any errors you've now successfully installed Docker!

Installing drone.io and integration with github

Installation of drone is actually pretty simple, it basically comes down to pulling a docker image which is started with a set of env variables used to integrate with your github account. You can check out the official docs on installation. But of course we'll be using Ansible for this as well, what did you expect? To get started we need to create an application over at github:

Creating our github application

Go to your github settings page and choose applications and create a new developer application (direct link). Register the application with an appropriate name but more importantly the ip address to your newly created server and click create application. This will generate a CLIENT_ID and a CLIENT_SECRET which we will need for our drone.

You can actually leave the callback url field blank, this field will autofill when you create application.

Installing drone.io

Lets creat a simple role to install and start our drone. Inside your provision folder create the following structure:

└── roles
    └── install_drone
        ├── tasks
        │   └── main.yml
        └── vars
            └── main.yml

Inside tasks/main.yml:

- name: install and start drone image
  sudo: yes
  docker:
    name: drone
    image: drone/drone:0.4
    state: reloaded
    pull: always
    restart_policy: always
    detach: true
    ports:
    - "80:8000"
    volumes:
    - "/var/lib/drone:/var/lib/drone"
    - "/var/run/docker.sock:/var/run/docker.sock"
    env:
      REMOTE_DRIVER: github
      REMOTE_CONFIG: https://github.com?client_id={{ client_id }}&client_secret={{ client_secret }}

And inside your vars/main.yml:

client_id: YOUR_GITHUB_CLIENT_ID  
client_secret: YOUR_GITHUB_CLIENT_SECRET  

Now add our created role to our provisioner.yml playbook:

- hosts: docker-drone
  sudo: yes
  roles:
      - angstwad.docker_ubuntu
      - install_drone

...and call it once again:

$ ansible-playbook provision/provisioner.yml

Now pop open a browser and visit your server, you should be greeted by the drone login page:
Drone login page

Now you just have to login, authorize your application to access your github, and choose a repo to activate. Once you've activated a repo drone will now listen to the activity (pushes, merges, pull requests or whatever you choose in the settings) and automatically build your project and run certain commands which you define in a .drone.yml file.

More on that in the next part:
W&S devops part 2.5 - Testing a django project using drone.io

Erik Svedin
Author

Erik Svedin

Comments