Skip to content

Buildkite

Buildkite is a more flexible and cheaper hybrid CI/CD solution than Github Actions. It's cheaper since you end up hosting the build agent on your own infrastructure, instead of renting time on Microsoft's expensive VMs. It's more flexible likely from Buildkite being solely focused on CI/CD vs Github Actions being just another one of the many products that Github builds for developers and organizations.

Start by creating a new Buildkite account.

Use the below steps to configure your self-hosted Buildkite agents.

Then, start them with the following command. Note that the start.sh script takes an argument which is the prefix of the Docker config file to handle separate agent swarms by Buildkite queue (see further description of queues below).

$ cd docker/buildkite
$ ./start.sh deploy

ubuntu@docker-003:~/ktsaas-starter/docker/buildkite$ ./start.sh deploy
deploy
[+] Building 49.4s (2/3)                                         docker:default
 => [internal] load .dockerignore                                         29.3s
 => => transferring context: 2B                                            0.0s
 => [internal] load build definition from Dockerfile                      23.0s
 => => transferring dockerfile: 301B                                       0.0s
 => [internal] load metadata for docker.io/buildkite/agent:edge-ubuntu-2  18.7s

Note: the start/stop script includes commented out WIP functionality for handling testing databases with isolated networks which will be included in an upcoming release.

Buildkite Agent Directory

The Buildkite agent runs all CI tasks within a specific directory that you can configure. In the below example, /var/lib/buildkite-agent is used.

Configure it in the docker/buildkite/.all.env file.

BUILDKITE_AGENT_DIR=/var/lib/buildkite-agent

Buildkite Agent Config

Create a Buildkite Agent config file with the name buildkite-agent.cfg in your agent directory (ie. /var/lib/buildkite-agent).

Copy the file from docker/buildkite/buildkite-agent.cfg.template or from the Buildkite docs.

Agent Binary

Use the install instructions from Buildkite to setup the agent CLI on your host. Add it within a /bin directory in your agent directory (ie. /var/lib/buildkite-agent/bin).

Agent Token

Edit the buildkite-agent.cfg to set your Buildkite agent token from your Buildkite account.

# The token from your Buildkite "Agents" page
token="<buildkite token>"

Agent Name

Edit the buildkite-agent.cfg to set a prefix for the VM host. This is especially useful if you have Buildkite agents running on many VMs and want a way to identify from the Buildkite dashboard where a given agent is running. If you are only running Buildkite agents on a single host, you can remove the prefix entirely.

# The name of the agent
name="<agent vm prefix>_%hostname_%spawn"

Agent Queue Tag

Edit the buildkite-agent.cfg to choose which queue the agent is handling jobs for. If commented out or left empty, the agent will serve the "default" queue. For cases like deploys where they must be run on your primary VM, you'll want to ensure that your Buildkite pipeline configuration and agent both have a the same corresponding specific queue like "deploy".

# Tags for the agent (default is "queue=default")
tags="queue=deploy"

Git SSH Keys

If your repo is private, then the Buildkite agents need a valid set of SSH keys with configured git access.

Copy your SSH keys into the Buildkite agent directory /var/lib/buildkite-agent/ssh-keys/.

Hermit Directory

Hermit is used to setup build dependencies for the starter repo including Java and Gradle.

Using the same directory across all agents speeds up builds by using a common shared dependency cache.

Configure it in the docker/buildkite/.all.env file.

HERMIT_STATE_DIR=/var/lib/hermit

Deploy Directory

To let a Buildkite agent handle deploys, it needs to have access to your primary code directory on the VM so it can have access to all the secrets, configuration, and DB migrations which you manually configured in setting up the application deploy.

Configure it in the docker/buildkite/.all.env file.

APPLICATION_DEPLOY_DIR=/home/ubuntu/ktsaas-starter

Buildkite Analytics

Analytics is an optional feature you can use which requires a separate token from your Buildkite dashboard. The Analytics feature tracks your test suite performance over time to highlight long running or flakey tests.

Configure it in the docker/buildkite/.all.env file.

BUILDKITE_ANALYTICS_TOKEN=<analytics-token-from-buildkite>

Testing Database

At this time, the testing database configuration is still WIP and is commented out for the default Buildkite configuration and in the .env.template. It will be fixed in a future update to the KtSaaS boilerplate.

MYSQL_ROOT_PASSWORD=
MYSQL_USER=
MYSQL_PASSWORD=

Scaling CI/CD

Once your team scales, usually your CI/CD will need to scale.

Engineers can put up with waiting for PR CI builds. They will not tolerate waiting 40 minutes for time on your lone CI agent.

With Github Actions, this simply means scaling your budget.

With Buildkite, scaling CI/CD means more agents running in parallel.

The included Docker Swarm configuration makes this easy. Tune the scale and Docker Swarm will make it so.

Dedicated CI/CD VM

It is highly recommended that beyond 1 Buildkite agent, you setup a dedicated VM for CI/CD.

In our experience, on a shared VM with all your application architecture plus 10 Buildkite agents running, there is significant risk that bursts of CI/CD compute can take down your whole VM. In testing and production, this has taken down entire applications.

The solution to this is to setup a separate VM for all non-deploy CI/CD tasks.

  • Deploys? Deploy queue. Application VM. 1 Agent.
  • PR test suite? Default queue. CI/CD VM. 10 Agents.

This setup means that new PRs will almost always have agents available to run the sharded test suite.

The deploy queue has to remain on the Application VM so that it can interact with your primary Docker Swarm.

The default queue for all other CI/CD tasks does not (& for security reasons should not) have access to your primary application VM and Docker Swarm.