HOWTO – Bootstrap Jenkins Controller on Control Node¶
Deploy the Jenkins controller on the control node as the long-lived CI control
plane. The result is a jenkins-controller service with pinned plugins,
Configuration as Code loaded from
/opt/jenkins/jenkins_home/casc_configs/, and controller executors disabled for
steady-state operation.
Difficulty: Intermediate Prerequisites: SSH access to the control node, Ansible control machine, and a secrets method (Ansible Vault / AKV / CI variables) to provide the initial admin password.
Demo¶
No academy walkthrough recording is linked here yet.
- Source: View role on GitHub
Context¶
Use this HOWTO when the control node is ready, Docker is available, and Jenkins needs to become the stable entry point for platform pipelines without also becoming the build worker.
This guide fits the standard HybridOps Jenkins placement model:
- the controller stays on the control node
- build execution moves to agents
- a Docker bootstrap agent is temporary, while RKE2 agents are the preferred steady-state target
This HOWTO is aligned to:
Steps¶
1. Confirm baseline and connectivity¶
-
Confirm Ansible connectivity:
ansible ctrl_nodes -m ping -i <inventory> -
Confirm OS facts (optional):
ansible ctrl_nodes -m setup -a 'filter=ansible_distribution*' -i <inventory>
Expected result:
- Ping succeeds.
- Target OS matches your platform baseline.
2. Apply Docker Engine baseline (ADR-0608)¶
Apply the Docker Engine baseline role to ensure Docker Engine and the Compose v2 plugin are present and healthy.
Example playbook:
- name: Bootstrap Docker Engine baseline on control node
hosts: ctrl_nodes
become: true
gather_facts: true
collections:
- hybridops.common
roles:
- role: hybridops.common.docker_engine
vars:
docker_engine_users:
- "{{ ansible_user | default('root') }}"
Run:
ansible-playbook -i <inventory> deployment/playbooks/bootstrap_docker_ctrl01.yml
Expected result on the control node:
docker version
docker compose version
3. Deploy the Jenkins controller (ADR-0603)¶
Provide the admin password via your secret method (Vault/AKV/CI vars). Example vars:
jenkins_admin_username: "admin"
jenkins_admin_password: "{{ vault_jenkins_admin_password }}"
jenkins_enable_healthcheck: true
# Bootstrap/lab only: enable a single executor to run trivial jobs before agents exist.
jenkins_controller_num_executors: 1
Example playbook:
- name: Bootstrap Jenkins controller on control node
hosts: ctrl_nodes
become: true
gather_facts: true
collections:
- hybridops.app
roles:
- role: hybridops.app.jenkins_controller
Run:
ansible-playbook -i <inventory> deployment/playbooks/bootstrap_jenkins_ctrl01.yml
Expected result:
- Container
jenkins-controlleris running. - HTTP endpoint responds on the configured port.
- JCasC files are rendered under the controller home and loaded at startup.
4. Validate readiness¶
-
Container status:
docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Image}}" | rg 'jenkins-controller' -
HTTP endpoint:
curl -sS -o /dev/null -w "HTTP=%{http_code}\n" http://localhost:8080/login -
JCasC rendered files:
sudo ls -la /opt/jenkins/jenkins_home/casc_configs/ -
Controller executor policy:
-
Bootstrap:
jenkins_controller_num_executors: 1(temporary) - Standard: set back to
0once agents are configured
Validation¶
Consider this complete when:
- Docker baseline is installed and verified (
docker+docker compose). - Jenkins controller container is healthy and stable.
- JCasC is loading (no Configuration as Code boot failures in logs).
- You can authenticate to
/whoAmI/api/jsonusing admin credentials.
Suggested run-record capture:
docker psoutputdocker logs --tail 200 jenkins-controller- HTTP probe output (
curl -I/ status codes) - The rendered
casc_configs/directory listing
Troubleshooting¶
-
Controller restart loop / JCasC boot failure Inspect logs and validate the rendered YAML:
docker logs --tail 200 jenkins-controller sudo sed -n '1,200p' /opt/jenkins/jenkins_home/casc_configs/00-controller.yaml
-
Permissions errors under JENKINS_HOME Ensure ownership matches the container user:
sudo chown -R 1000:1000 /opt/jenkins/jenkins_home
-
Endpoint never becomes healthy Increase memory (
jenkins_memory) and re-check logs.
References¶
- ADRs:
- ADR-0608 – Docker Engine baseline
-
ADR-0603 – Run Jenkins controller on the control node and move build execution to agents
-
Roles:
- GitHub –
hybridops.app.jenkins_controller -
Operations:
- Runbooks – Jenkins
License: MIT-0 for code, CC-BY-4.0 for documentation