Runbook – Bootstrap Jenkins Controller on Control Node (ctrl-01)¶
Purpose: Deploy a controller-only Jenkins instance on ctrl-01 using Docker Compose and JCasC.
Owner: Platform Operations
Trigger: New control node build, controller rebuild, or controlled controller recovery.
Impact: Jenkins control plane availability; pipeline scheduling may be paused during deployment/restart.
Severity: P2
Pre-reqs: SSH access to ctrl-01, Docker Engine + Compose v2 available, secrets available (admin password at minimum).
Rollback strategy: Stop the compose stack and revert JCasC/config inputs; restore JENKINS_HOME from backup/snapshot if required.
Context¶
This runbook provisions the Jenkins controller on the control node (ctrl-01) as a containerised service:
- Controller runs in Docker using
docker compose. - Controller is configured by JCasC loaded from
/var/jenkins_home/casc_configs. - Build workload is expected to run on agents (Docker bootstrap agent initially; RKE2 agents in steady state).
This is aligned with the platform execution model in ADR-0603.
Preconditions and safety checks¶
1) Confirm you are targeting the correct host:
hostnamectl
ip -br a
2) Confirm Docker is healthy:
docker version --format '{{.Server.Version}}'
docker compose version
3) Confirm ports are available (or intentionally bound):
ss -lntp | egrep ':8080|:50000' || true
4) Confirm the secrets you will use are available:
jenkins_admin_password(required for bootstrap).- Optional:
jenkins_github_token, other credential material.
Steps¶
1) Apply the controller role
Run your playbook that applies:
hybridops.common.docker_engine(baseline, if needed)hybridops.app.jenkins_controller
Example execution:
ansible-playbook -i <inventory> <playbook>.yml
Expected result
- Controller image exists (built from the pinned plugin list).
- Compose stack starts successfully.
- Healthcheck passes (if enabled).
Evidence
- Save role output log to:
<runtime-root>/logs/ansible/jenkins_controller/<run_id>.log
2) Validate container health
docker ps --format "table {{.Names}} {{.Status}} {{.Image}}" | egrep "jenkins-controller|NAME"
docker logs --tail 200 jenkins-controller
Expected result
jenkins-controllerisUpand, when enabled,(healthy).- Logs show
Jenkins is fully up and running.
Evidence
<runtime-root>/logs/ci/jenkins_controller/docker_ps_<run_id>.txt<runtime-root>/logs/ci/jenkins_controller/docker_logs_<run_id>.txt
3) Validate HTTP and API probes (host-local)
curl -sS -o /dev/null -w "HTTP=%{http_code}
" http://localhost:8080/login
curl -sS -u "admin:<ADMIN_PASSWORD_OR_TOKEN>" http://localhost:8080/whoAmI/api/json && echo
Expected result
/loginreturns 200/302 (depending on configuration)./whoAmI/api/jsonreturns authenticated JSON for the admin user.
Evidence
<runtime-root>/logs/ci/jenkins_controller/http_probe_<run_id>.txt<runtime-root>/logs/ci/jenkins_controller/whoami_<run_id>.json
4) Confirm JCasC inputs are present
sudo ls -la /opt/jenkins/jenkins_home/casc_configs/
sudo sed -n '1,200p' /opt/jenkins/jenkins_home/casc_configs/00-controller.yaml
Expected result
- Controller baseline file exists and renders expected values.
Evidence
<runtime-root>/logs/ci/jenkins_controller/casc_listing_<run_id>.txt
5) Optional: Admin API token management
If enabled, the role can mint and persist an admin API token to a root-only file. Retrieve it on the controller host:
sudo cat /opt/jenkins/.secrets/admin_api_token
Use it as the Basic Auth “password”:
TOKEN="$(sudo sh -c 'tr -d "\n" </opt/jenkins/.secrets/admin_api_token')"
curl -sS -u "admin:${TOKEN}" http://localhost:8080/whoAmI/api/json && echo
Security note: avoid printing tokens in CI logs; rotate if exposure is suspected.
Verification¶
Success criteria:
jenkins-controllercontainer is running and healthy./loginis reachable and/whoAmIauthenticates.- JCasC files load without boot failures.
- Controller is configured for controller-only operation (typically
numExecutors: 0in steady state).
Post-actions and clean-up¶
- Reduce controller executors back to 0 after bootstrap validation (if you temporarily set 1 for smoke tests).
- Ensure an agent execution surface is available (Docker bootstrap agent or RKE2 agents) before scheduling production-like pipelines.
- Rotate secrets/tokens if any were exposed during the run.
References¶
- ADRs:
- ADR-0608 – Docker Engine baseline
-
HOWTOs:
-
HOWTO – Bootstrap Jenkins Controller on Control Node (ctrl-01)
-
Runbooks:
- Runbook index
-
Source:
- GitHub – hybridops.app jenkins_controller role
Maintainer: HybridOps
License: MIT-0 for code, CC-BY-4.0 for documentation