Running Buildkite Agent on Google Cloud Platform

The Buildkite Agent can be run on Google Cloud Platform. For fine control over long–lived agents, you might like to run the agent using individual VM instances on Google Compute Engine. Or run Docker–based builds using a scalable cluster of agents on the Google Container Engine via Kubernetes.

Running the agent on Google Compute Engine

To run the agent on your own Google Compute Engine instance use whichever installer matches your instance type. For example:

Launch an instance using the latest Ubuntu LTS image through the console:

Screenshot of creating a Google Compute Engine instance running Ubuntu 16.04 LTS via the Google Cloud Console

Connect via SSH:

Screenshot of connecting to a Google Compute Engine instance via the Google Cloud Console

Follow the setup instructions for Ubuntu.

Running the agent on Google Kubernetes Engine

Google Kubernetes Engine can run the agent as a Docker container using Kubernetes. To run Docker–based builds, ensure the container is started with a privileged security context and mount the Docker socket as a volume.

Start a Google Kubernetes Engine cluster through the console using the General-purpose Machine family:

Screenshot of creating a Google Kubernetes Engine cluster via the Google Cloud Console

Open Google Cloud Shell, or your own console with gcloud installed and authenticated. You'll need to configure kubectl to talk to your new cluster. The console includes a "Connect" button which shows the exact command to run:

Screenshot of cluster connection settings in the Google Cloud Console

Running it should look like this, with your details in the right places:

$ gcloud container clusters get-credentials INSERT-YOUR-CLUSTER-NAME \
Fetching cluster endpoint and auth data.
kubeconfig entry generated for YOUR-CLUSTER-NAME

Double check it’s running by taking a look at the cluster info:

$ kubectl cluster-info
Kubernetes master is running at
GLBCDefaultBackend is running at
Heapster is running at
KubeDNS is running at
Metrics-server is running at

To further debug and diagnose cluster problems, use 'kubectl cluster-info dump'.

Create a secret with your agent registration token:

$ kubectl create secret generic buildkite-agent --from-literal=token=INSERT-YOUR-AGENT-TOKEN-HERE
secret "buildkite-agent" created

Create a deployment to start an agent:

$ cat | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
  name: buildkite-agent
  replicas: 1
      app: buildkite-agent
        app: buildkite-agent
        - name: buildkite-agent
          image: buildkite/agent
          imagePullPolicy: Always
            privileged: true
            - name: BUILDKITE_AGENT_TOKEN
                  name: buildkite-agent
                  key: token
            - name: docker-socket
              mountPath: /var/run/docker.sock
        - name: docker-socket
          hostPath: {path: /var/run/docker.sock}
# (press Control-D)

deployment "buildkite-agent" created

Verify this started a pod running the agent:

$ kubectl get pods
NAME                               READY     STATUS    RESTARTS   AGE
buildkite-agent-3220167863-dtzcf   1/1       Running   0          30s

And verify that the agent has registered successfully in the logs:

$ kubectl logs buildkite-agent-3220167863-dtzcf

  _           _ _     _ _    _ _                                _
 | |         (_) |   | | |  (_) |                              | |
 | |__  _   _ _| | __| | | ___| |_ ___    __ _  __ _  ___ _ __ | |_
 | '_ \| | | | | |/ _` | |/ / | __/ _ \  / _` |/ _` |/ _ \ '_ \| __|
 | |_) | |_| | | | (_| |   <| | ||  __/ | (_| | (_| |  __/ | | | |_
 |_.__/ \__,_|_|_|\__,_|_|\_\_|\__\___|  \__,_|\__, |\___|_| |_|\__|
                                                __/ |                    |___/
2017-02-16 03:34:10 NOTICE Starting buildkite-agent v3.0.0 with PID: 5
2017-02-16 03:34:10 NOTICE The agent source code can be found here:
2017-02-16 03:34:10 NOTICE For questions and support, email us at:
2017-02-16 03:34:10 INFO   Registering agent with Buildkite...
2017-02-16 03:34:11 INFO   Successfully registered agent "buildkite-agent-3220167863-1cvr5" with meta-data []
2017-02-16 03:34:11 INFO   Connecting to Buildkite...
2017-02-16 03:34:11 INFO   Agent successfully connected
2017-02-16 03:34:11 INFO   You can press Ctrl-C to stop the agent
2017-02-16 03:34:11 INFO   Waiting for work...

You’re successfully running a Buildkite Agent!

Running more than one agent

To run more than one agent you can increase replicas:

$ kubectl scale --replicas=5 deployment buildkite-agent
deployment "buildkite-agent" scaled

$ kubectl get pods
NAME                               READY     STATUS    RESTARTS   AGE
buildkite-agent-3220167863-0m269   1/1       Running   0          24s
buildkite-agent-3220167863-0mtps   1/1       Running   0          24s
buildkite-agent-3220167863-1cvr5   1/1       Running   0          3m
buildkite-agent-3220167863-9psz9   1/1       Running   0          24s
buildkite-agent-3220167863-m3nm2   1/1       Running   0          24s

Authenticating to private repositories

To run builds from private repositories you can store an SSH key for the agent in a secret and map it into the containers:

# Use an existing keypair, or generate a new one with something like:
$ ssh-keygen -t rsa -b 2048 -N "" -C buildkite-agent -f id_rsa
Generating public/private rsa key pair.
Your identification has been saved in id_rsa.
Your public key has been saved in

# Create a secret containing the ssh keys:
$ kubectl create secret generic buildkite-agent-ssh \
    --from-file id_rsa=id_rsa \
secret "buildkite-agent-ssh" created

# Change the spec to include new volumes to map the ssh key into place (because
# this is Docker the git and ssh processes are running as root):
$ kubectl edit deployment buildkite-agent
  - ...
    - name: ssh-keys
      mountPath: /root/.ssh/id_rsa
      subPath: id_rsa
    - name: ssh-keys
      mountPath: /root/.ssh/
  - name: ssh-keys
      secretName: buildkite-agent-ssh
      defaultMode: 0400

If you git clone over https (for example using a GitHub API token) you could mount a git-credentials file instead:

- ...
  - name: git-credentials
    mountPath: /root/.git-credentials
    subPath: .git-credentials
- name: git-credentials
    secretName: buildkite-agent-git-credentials
    defaultMode: 0400

You'll need to add an environment hook to set the git credential.helper to actually use your newly added git-credentials file. See here for an example.

Further configuration

To configure the agent further you can create a config map and volume mount it over the default agent configuration file in /buildkite/buildkite-agent.cfg.

To add agent hooks add another config map and volume mount them into /buildkite/hooks/.

To add container startup scripts, add another config map with files and volume mount them into /docker-entrypoint.d/. Note: scripts in this directory must not have any periods (.) or any file extensions since they are run by the run-parts util.

See our Docker setup instructions for more details on configuring and customising the Buildkite Agent running in Docker.

Uploading artifacts to Google Cloud Storage

You can upload the artifacts created by your builds to your own Google Cloud Storage bucket. Configure the agent to target your bucket by exporting the following environment variables using an environment agent hook (this can not be set via the Buildkite web interface, API, or during pipeline upload):


Make sure the agent has permission to create new objects. If the agent is running on Google Compute Engine or Google Container Engine you can grant Storage Write permission to the instance or cluster, or restrict access more specifically using a service account.

You can also set the application credentials with the environment variable BUILDKITE_GS_APPLICATION_CREDENTIALS. From Agent v3.15.2 and above you can also use raw JSON with the BUILDKITE_GS_APPLICATION_CREDENTIALS_JSON variable. See the Managing Pipeline Secrets documentation for how to securely set up environment variables.

If you are using any of the non-public predefined Access Control Lists (ACLs) to control permissions on your bucket, you won't have automatic access to your artifacts through the links in the Buildkite web interface. Artifacts will inherit the permissions of the bucket into which they're uploaded. You can set a specific ACL on an artifact:

export BUILDKITE_GS_ACL="publicRead"

If you need to be authenticated to view the objects in your bucket, you can use GCS's cookie-based authentication:


To use your own authenticating proxy for access control, set your proxy's domain as the access host:


If your proxy does not follow default GCS artifact path conventions, for example, not including the bucket name in the URL, you can override the artifact path.

To override the default path, export the environment variable BUILDKITE_GCS_PATH_PREFIX:

export BUILDKITE_GCS_PATH_PREFIX="custom-folder-structure/"

The above variable export will cause the artifact path to use your custom prefix instead of the GCS_BUCKET_NAME:

# default path

# using the BUILDKITE_GCS_PATH_PREFIX environment variable