iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

Buildkite

Buildkite: hybrid CI with self-hosted agents and a hosted control plane. Pipelines as YAML, dynamic steps, and the patterns at scale.

CI/CD — Buildkite

EXAMPLE
# ===== The model =====
# Buildkite.com hosts the UI + scheduler.
# YOU run agents on your infrastructure (laptops, VMs, k8s, on-prem).
# Pipelines defined in YAML inside the repo or uploaded dynamically.

# ===== Install an agent =====
# macOS:
brew install buildkite/buildkite/buildkite-agent
buildkite-agent start --token <token>

# Docker:
docker run -d --name agent -e BUILDKITE_AGENT_TOKEN=<token> \
  -v /var/run/docker.sock:/var/run/docker.sock \
  buildkite/agent:3 start

# Kubernetes:
helm install agent buildkite/agent --set agentToken=<token> --set replicas=4

# ===== Pipeline YAML =====
# .buildkite/pipeline.yml
steps:
  - label: ":eslint: Lint"
    command: npm ci && npm run lint
    agents: { queue: 'default' }
  - label: ":jest: Test"
    command: npm test -- --coverage
    artifact_paths:
      - 'coverage/**/*'
  - wait
  - label: ":docker: Build image"
    command: docker build -t shop:$BUILDKITE_COMMIT .
    plugins:
      - docker-compose#v4.16.0:
          run: app
  - block: ":rocket: Deploy?"
    branches: main
  - label: ":aws: Deploy"
    command: ./deploy.sh
    branches: main
    env:
      AWS_REGION: ap-southeast-2

# 'wait' = barrier between phases.
# 'block' = manual approval gate.

# ===== Dynamic pipeline (upload) =====
# Some steps depend on the diff; generate the pipeline on the fly:
# .buildkite/pipeline.yml
steps:
  - label: 'Generate'
    command: ./scripts/gen-pipeline.sh | buildkite-agent pipeline upload

# Script outputs YAML to stdout; agent uploads it.

# ===== Queues + tags =====
# Agents register with a 'queue' (e.g. 'mac-arm', 'docker', 'gpu').
# Steps select queues with agents: { queue: 'gpu' }.
# Tag agents for capabilities; pin steps accordingly.

# ===== Artifacts =====
- label: 'Build'
  command: npm run build
  artifact_paths:
    - 'dist/**/*'
- label: 'Deploy'
  command: |
    buildkite-agent artifact download 'dist/**/*' .
    ./upload-to-s3.sh dist/

# ===== Secrets =====
# Two options:
# 1. Environment variables set on the agent (e.g. via systemd / .env)
# 2. buildkite-agent secret get my-secret (Buildkite cloud-managed)
# Plugins (aws-ssm, vault) integrate with external secret stores.

# ===== Plugins =====
plugins:
  - docker#v5.10.0:
      image: 'node:20-alpine'
      workdir: /app
      mount-buildkite-agent: true
  - test-collector#v1.10.2:
      files: 'junit.xml'
      format: 'junit'

# Plugins are versioned and shareable across pipelines.

# ===== Triggers (cross-pipeline) =====
- trigger: shared-libs-deploy
  label: 'Deploy shared libs'
  build:
    branch: main
    message: 'Triggered by ${BUILDKITE_PIPELINE_SLUG}'

# ===== Matrix =====
- label: 'Test :node-{{matrix}}'
  command: nvm use {{matrix}} && npm test
  matrix:
    - '18'
    - '20'
    - '22'

# ===== Patterns to internalise =====
# - Agents close to your code + secrets (great for regulated industries)
# - Dynamic pipeline upload for monorepo / per-app builds
# - Plugins instead of duplicated docker / aws / test-collector setup
# - Manual approval ('block') before risky steps

# ===== Pitfalls =====
# - Long-running agents collecting junk (clean workspaces between builds)
# - Secrets baked into agent images
# - Pipelines that grow into the YAML without dynamic upload
# - 'wait' steps everywhere -> sequential when parallelism would do

Why it matters

Buildkite shines when you want self-hosted agents but a hosted UI: low-latency runners, secrets close to your code, dynamic pipelines for monorepos. YAML pipelines + plugins + block steps cover most needs; pair with queues + tags as the team grows.

Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.

Example

Example
# .buildkite/pipeline.yml
steps:
    - label: ":hammer: test"
      command: npm test
    - wait
    - label: ":docker: build"
      command: docker build -t app .
Try it Yourself »

Discussion

Loading…