Skip to main content

Lesson: Bitbucket Pipelines & Jenkins

What you'll learn

  • What Bitbucket Pipelines is and how its YAML compares to GitHub Actions.
  • The Jenkins server/agent model and what a "Jenkinsfile" pipeline looks like.
  • When you'd reach for each tool, and the practical limitations and trade-offs of each versus GitHub Actions.
  • That CI/CD concepts transfer between tools — once you understand the model, switching tools is mostly learning new syntax.

By the end you can compare three CI engines and pick a sensible one for a given situation.

The lesson

GitHub Actions is not the only CI/CD engine, and in your career you will meet others. The good news: the concepts from the previous chapters — triggers, stages, steps, runners, artifacts — apply everywhere. Only the syntax and the operating model change. This chapter gives you a working mental model of two common alternatives: Bitbucket Pipelines and Jenkins. We keep these at overview depth — enough to read one and know when to choose it.

1. The big picture: hosted vs self-managed

CI engines fall on a spectrum:

  More managed for you  <--------------------------------->  More you manage
  +-------------------+    +----------------------+    +-------------------+
  | GitHub Actions /  |    | Self-hosted runners  |    |     Jenkins       |
  | Bitbucket Pipelines|   | (Gitea runner, etc.) |    | (you run the      |
  | cloud runners      |   |                      |    |  whole server)    |
  +-------------------+    +----------------------+    +-------------------+

GitHub Actions and Bitbucket Pipelines are cloud-hosted: the vendor gives you runners and you just write YAML. Jenkins is a server you install and operate yourself — maximum control, maximum responsibility. The lab's Gitea runner sits in the middle: cloud-style YAML, but on a machine you own (10.100.100.11).

2. Bitbucket Pipelines

Bitbucket is Atlassian's Git hosting (often used alongside Jira). Bitbucket Pipelines is its built-in CI/CD, configured in a single file at the repo root: bitbucket-pipelines.yml.

The model is similar to GitHub Actions but simpler and more opinionated. Every step runs inside a Docker container (you pick the image), and steps are grouped under triggers like default, branches, and pull-requests:

image: node:20            # default container for all steps

pipelines:
  default:                # runs on every push (any branch)
    - step:
        name: Build and test
        script:
          - npm install
          - npm test
  branches:
    main:                 # runs only on the main branch
      - step:
          name: Build image
          script:
            - docker build -t myapp .
        services:
          - docker        # opt in to a Docker daemon

Notice the shape is the same idea as GitHub Actions: triggers at the top, then steps with a script: (the equivalent of run:). Key differences:

  • The whole config is one file, not many workflow files.
  • Each step is always a container; you set image: rather than runs-on:.
  • It is tightly tied to Bitbucket and Atlassian's ecosystem.

When to use it: your team already lives in Bitbucket/Jira. Limitations vs GitHub Actions: a far smaller marketplace of reusable actions, cloud build minutes are metered and can get costly, and it's less flexible for complex multi-job graphs.

3. Jenkins: the server/agent model

Jenkins is the veteran open-source automation server. Unlike the others, it is not bundled with a Git host — you install and run it yourself. Its defining feature is the controller/agent (historically "master/agent") architecture:

            +---------------------+
            |  Jenkins controller |   <- schedules jobs, stores config,
            |  (the web UI/brain) |      shows the dashboard
            +----------+----------+
                       |
        +--------------+--------------+
        |              |              |
   +---------+    +---------+    +---------+
   | Agent 1 |    | Agent 2 |    | Agent 3 |   <- where builds actually run
   | (Linux) |    | (Win)   |    | (ARM)   |
   +---------+    +---------+    +---------+

The controller is the brain: it stores configuration, schedules work, and serves the dashboard. Agents are worker machines that actually execute builds — you can have agents on different operating systems and architectures. This is powerful: one Jenkins can drive builds across a whole fleet.

Modern Jenkins pipelines are defined in code in a Jenkinsfile committed to your repo, written in a Groovy-based syntax:

pipeline {
    agent any                 // run on any available agent
    stages {
        stage('Build') {
            steps { sh 'docker build -t myapp .' }
        }
        stage('Test') {
            steps { sh './run-tests.sh' }
        }
        stage('Push') {
            steps { sh 'docker push myapp' }
        }
    }
}

Same concepts again — stages and steps — just different syntax (sh instead of run:/script:).

When to use it: you need to self-host for compliance or air-gapped reasons, you have unusual build needs (exotic OSes, hardware), or you have a huge existing Jenkins estate. Its enormous plugin ecosystem (1,800+ plugins) can integrate with almost anything.

Limitations / trade-offs vs GitHub Actions: you own the uptime, upgrades, security patching, and backups of the whole server — that's real operational work. The plugin ecosystem is powerful but plugins vary in quality and can break on upgrades. Groovy pipeline syntax is more complex than YAML. It does not come pre-integrated with your Git host's UI the way Actions does.

4. Choosing between them

A quick decision guide:

 Already on GitHub?            -> GitHub Actions
 Already on Bitbucket/Jira?    -> Bitbucket Pipelines
 Need full self-host control,
   exotic platforms, or have
   a big existing install?     -> Jenkins
 Want Actions syntax but on
   your own infrastructure?    -> self-hosted runner (the lab's Gitea runner)

The honest truth: the concepts dominate. Triggers, stages, runners/agents, secrets, artifacts, and push-vs-pull deployment exist in all three. If you deeply understand the GitHub Actions chapter, you can read a bitbucket-pipelines.yml or a Jenkinsfile and roughly follow it on day one. Pick the tool that fits where your code already lives and how much you want to operate yourself.

5. What they share (and what you should standardize on)

Whatever the engine, good pipelines look the same:

  • Triggered automatically on push / pull request.
  • Fast feedback: tests early, fail fast.
  • Secrets stored in the platform, never in the repo.
  • A versioned artifact (usually a container image tagged by commit) as the handoff to deployment.
  • The pipeline definition lives in the repo as code (workflow.yml, bitbucket-pipelines.yml, Jenkinsfile) so it's reviewed and versioned like everything else.

That last point — pipeline-as-code — is the throughline, and it sets up the next chapter, where Git becomes the source of truth for deployment too.

Dig deeper

Search terms

  • bitbucket pipelines yml tutorial
  • jenkins controller agent architecture explained
  • jenkinsfile declarative pipeline example
  • jenkins vs github actions comparison
  • bitbucket pipelines vs github actions
  • self hosted ci cd vs cloud hosted

Check yourself

  1. What single file configures Bitbucket Pipelines, and what does every step always run inside?
  2. In Jenkins, what is the difference between the controller and an agent?
  3. Name one situation where Jenkins is the better choice than GitHub Actions, and one cost of choosing it.
  4. List two things that are true of a good pipeline regardless of which engine runs it.
  5. Why does the chapter say "the concepts dominate"? Give an example of a concept that appears in all three tools.