Skip to content

HOWTO – Bootstrap Jenkins Docker Agent on Control Node

Provision a Docker-based Jenkins inbound agent on the control node so pipeline workload moves off the controller during the bootstrap phase. This HOWTO uses JCasC to define the node and the jenkins_agents_docker role to run the standard tools-enabled inbound agent container on the controller host.

Difficulty: Intermediate Prerequisites: Jenkins controller deployed (via jenkins_controller), Docker Engine installed, and admin credentials available via your secrets strategy.


Demo

No academy walkthrough recording is linked here yet.

Context

Use this HOWTO during the controlled bootstrap window:

  • Jenkins controller is already running on the control node.
  • RKE2 pod agents are not yet available (or are temporarily unavailable).
  • You still need a governed agent runtime to execute platform pipelines.

It aligns with:


Steps

1. Ensure the node exists via JCasC (no Script Console)

Define the ctrl-docker node in controller JCasC (recommended for hardened Jenkins). Example snippet:

jenkins:
  nodes:
    - permanent:
        name: "ctrl-docker"
        remoteFS: "/home/jenkins"
        numExecutors: 1
        mode: NORMAL
        labelString: "ctrl-docker"
        retentionStrategy: "always"
        launcher:
          inbound:
            webSocket: false

Expected result:

  • Jenkins starts cleanly (no JCasC boot failures).
  • The node exists in Jenkins once the controller is up.

2. Run the inbound agent container on the control node

Apply your playbook that includes hybridops.app.jenkins_agents_docker.

Example variables (hardened mode):

jenkins_agents_docker_manage_node: false
jenkins_agents_docker_agent_secret: "{{ vault_ctrl_docker_agent_secret }}"
jenkins_agents_docker_use_websocket: false

Run:

ansible-playbook -i <inventory> deployment/playbooks/bootstrap_jenkins_agents_docker_ctrl01.yml

Expected result:

  • Docker container jenkins-agent-ctrl-docker is running.
  • Jenkins reports node ctrl-docker as online.

3. Prove workloads run on the agent (not the controller)

Use a simple pipeline targeting the label:

pipeline {
  agent { label 'ctrl-docker' }
  stages {
    stage('validation') {
      steps {
        sh 'whoami'
        sh 'terraform version | head -n 1'
        sh 'docker version'
        sh 'docker compose version'
      }
    }
  }
}

Expected result:

  • Stage executes on the agent node.
  • Controller remains executor-less for normal operation.

Validation

  • Container is running:

    docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | rg 'jenkins-agent|jenkins-controller'
    
  • Jenkins shows the node online (token example):

    TOKEN="$(sudo sh -c 'tr -d "\n"