Chapter 25Lesson 02~210 minutes

Plugin Ecosystem, Plugin Dependencies, Update Center, Compatibility, Pinning, Removal, and Plugin Governance: Guided Hands-On Workflow and Core Operations

Use a disposable Jenkins 2.568.3 LTS controller to inventory plugins, trace the Dark Theme dependency chain, stage a maintained low-risk plugin change in a cloned controller, compare before/after manifests, test disable/removal behavior, and export a reproducible plugin set without touching a production controller.

Hands-onDisposable controllerdark-themePlugin manifestClone testRollback

Learning objectives

  • Create a disposable Jenkins 2.568.3 LTS controller and record image/core/Java identity.
  • Inventory installed plugins without changing them.
  • Trace Dark Theme → Theme Manager → API dependencies.
  • Stage a plugin update on a cloned controller and verify restart/load behavior.
  • Test disable/remove behavior in a clone and export a reproducible manifest.

1. Lab boundary and preflight

Scope guard. All plugin mutation in this lesson belongs to disposable containers/volumes named ch25-*. Do not install, disable or remove plugins on an accepted production controller. Plugin changes are administrator actions and can prevent startup.

Assumptions verified 17 September 2026: Jenkins 2.568.3 LTS, Java 21, image jenkins/jenkins:2.568.3-lts-jdk21, Dark Theme current 652.vea_da_dfea_e769, Theme Manager current 346.v06cca_64c6a_37. The old Dark Theme version used below (574.va_19f05d54df5) is only a disposable upgrade starting point.

docker pull jenkins/jenkins:2.568.3-lts-jdk21
docker image inspect jenkins/jenkins:2.568.3-lts-jdk21 \
  --format '{{index .RepoDigests 0}}' > ch25-controller-image.txt
mkdir -p ch25/{baseline,candidate,evidence}

Record the actual digest on your platform. Do not replace the versioned tag with lts during the exercise.

2. Build two explicit controller images

The baseline and candidate differ only in the direct plugin version. This isolates the plugin change from unrelated core movement.

# ch25/baseline/Dockerfile
FROM jenkins/jenkins:2.568.3-lts-jdk21
RUN jenkins-plugin-cli --plugins dark-theme:574.va_19f05d54df5 --latest=false
# ch25/candidate/Dockerfile
FROM jenkins/jenkins:2.568.3-lts-jdk21
RUN jenkins-plugin-cli --plugins dark-theme:652.vea_da_dfea_e769 --latest=false
docker build -t ch25-jenkins:baseline ch25/baseline
docker build -t ch25-jenkins:candidate ch25/candidate
docker image inspect ch25-jenkins:baseline --format '{{.Id}}' > ch25/evidence/baseline-image-id.txt
docker image inspect ch25-jenkins:candidate --format '{{.Id}}' > ch25/evidence/candidate-image-id.txt

jenkins-plugin-cli resolves required dependencies using Jenkins/plugin metadata. --latest=false is intentional: it avoids silently upgrading every dependency to the newest release while you are trying to test one controlled direct change. The resolved dependency set still needs to be recorded after startup.

3. Start the baseline and inventory before mutation

docker volume create ch25-home-baseline
docker run -d --name ch25-jenkins \
  -p 127.0.0.1:8080:8080 \
  -v ch25-home-baseline:/var/jenkins_home \
  ch25-jenkins:baseline

docker logs -f ch25-jenkins

Complete the local setup wizard with a lab-only administrator. Keep the built-in node at zero executors as established earlier in the course. This chapter does not need builds to run on the controller.

In Manage Jenkins → Plugins → Installed, inspect exact versions for dark-theme, theme-manager and their dependencies. Save screenshots/text evidence. Also record Jenkins and Java from Manage Jenkins → System Information or startup logs.

4. Trace one dependency chain before changing it

Plugin Role Dependency relationship to inspect
dark-theme Direct lab capability Requires Theme Manager ≥ 327.v780d7096ec29
theme-manager Theme extension layer Requires Ionicons API and Jackson 3 API in current release
API plugins Shared libraries/APIs May be shared by many unrelated plugins; removal impact is wider than Dark Theme

Use plugin-site dependency pages and the Installed tab together. The plugin-site page describes release metadata; the controller tells you the exact resolved versions actually loaded.

5. Export a reproducible plugin manifest

Use Jenkins CLI only on this local disposable controller. Download the CLI jar, create a fake lab API token, and avoid writing that token into course evidence.

curl -fsS http://127.0.0.1:8080/jnlpJars/jenkins-cli.jar -o ch25/jenkins-cli.jar
# Put lab-only credentials in local variables, not evidence files.
export JENKINS_AUTH='lab-admin:LAB_ONLY_TOKEN'
java -jar ch25/jenkins-cli.jar -s http://127.0.0.1:8080 \
  -auth "$JENKINS_AUTH" list-plugins \
  | tee ch25/evidence/plugins-baseline.txt

Normalize this into a reviewed plugins.lock.txt containing short name and exact version. This is SBOM-like inventory evidence, not a full software SBOM: it does not automatically include every Maven component inside every plugin.

6. Hash plugin archives on the disposable controller

docker exec ch25-jenkins bash -lc '
  cd /var/jenkins_home/plugins
  sha256sum *.jpi 2>/dev/null | sort
' > ch25/evidence/plugin-sha256-baseline.txt

A hash proves binary identity, not trustworthiness. Keep it with source/update-center/advisory evidence.

7. Clone state before testing the candidate

Stop the baseline cleanly, then copy the volume into a new disposable volume. The clone is your change-test target; the baseline remains untouched.

docker stop ch25-jenkins
docker volume create ch25-home-candidate
docker run --rm \
  -v ch25-home-baseline:/from:ro \
  -v ch25-home-candidate:/to \
  alpine:3.22 sh -c 'cd /from && cp -a . /to/'
docker rm ch25-jenkins

docker run -d --name ch25-jenkins-candidate \
  -p 127.0.0.1:8081:8080 \
  -v ch25-home-candidate:/var/jenkins_home \
  ch25-jenkins:candidate

The image supplies the candidate plugin files, while the cloned JENKINS_HOME supplies accepted configuration/data. Watch startup logs for dependency/load warnings before declaring success.

8. Verify the candidate as a sequence of states

  1. Container running — process exists.
  2. Jenkins ready — startup completed without failed plugins.
  3. Plugin loaded — exact Dark Theme/Theme Manager versions visible.
  4. Configuration recognized — Appearance page loads and theme selection is available.
  5. Representative smoke test — login, job list and a harmless read-only Pipeline/job configuration page still render.
  6. Evidence retained — candidate inventory, hashes and startup log saved.

Do not collapse those into “container started, therefore upgrade succeeded.”

9. Disable-first retirement test

On a second clone, disable Dark Theme using the Installed page or local CLI. Jenkins documents disabling as the softer retirement path: the archive remains installed but extensions do not start. Reboot the clone and observe whether configuration references produce warnings and whether Theme Manager remains required elsewhere.

# Example only on the disposable clone
java -jar ch25/jenkins-cli.jar -s http://127.0.0.1:8081 \
  -auth "$JENKINS_AUTH" disable-plugin dark-theme -restart

Preserve the disable output and restart logs. Do not use dependency-cascade options without understanding every plugin that would be affected.

10. Removal test and old data

Only after the disable test should you evaluate uninstall. Jenkins warns that removing a required dependency can prevent boot and that uninstalling does not automatically remove plugin-created configuration. The Manage Old Data page is a separate, potentially destructive cleanup decision. In this lab, do not purge old data; just document what remains.

11. Challenge: identify the owning layer

The candidate clone boots, but a job configuration page shows “CannotResolveClassException” for a plugin-defined field. Should you add an executor, retry the build, edit XML, or inspect plugin/configuration compatibility?

Reason it out

The failure is in the controller/plugin configuration layer before queue/agent execution. Preserve the old config and startup warnings, confirm which plugin/version owns the class, and restore or upgrade the compatible plugin set in the clone. Agent capacity cannot repair deserialization.

12. Cleanup

docker rm -f ch25-jenkins-candidate 2>/dev/null || true
docker volume rm ch25-home-candidate 2>/dev/null || true
# Keep ch25-home-baseline only until the evidence/restore exercise is complete.

Never remove a volume whose identity you have not explicitly verified as ch25-*.

Next lesson

Configuration, Design Choices, and Tradeoffs

Decide when Jenkins should gain a plugin at all, how plugin sets are reviewed, when restarts are preferable, and how disable/uninstall choices affect recoverability.

Knowledge check

Answer before revealing the explanation.

1. Why does the lab use a cloned/disposable controller for plugin retirement tests?

2. Why was Dark Theme selected for the install/upgrade exercise?

3. What dependency must Dark Theme have?

4. What must be captured before and after the change?

5. Why export resolved versions instead of keeping only “dark-theme:latest”?

Official references and version notes

Verified baseline — 17 September 2026. Labs use Jenkins 2.568.3 LTS with Java 21; Jenkins 2.568.3 is tested with Java 21 and 25. The disposable controller image is jenkins/jenkins:2.568.3-lts-jdk21; record its platform-specific digest before execution. Dark Theme is 652.vea_da_dfea_e769 (requires Jenkins 2.528.3) and requires Theme Manager ≥ 327.v780d7096ec29; current Theme Manager is 346.v06cca_64c6a_37 (requires Jenkins 2.504.3). Current upstream Plugin Installation Manager Tool is 2.15.0; verify the exact jenkins-plugin-cli --version bundled in the selected controller image. Re-check all of these before reuse because plugin releases, dependency graphs and advisories change independently.

Keep the academy open

Support free, practical DevOps education.

Every lesson is designed to remain readable in a browser, downloadable from GitHub, and usable without a paid learning platform. Contributions help expand and maintain the curriculum.

Ethereum / ERC-20
0x716c4Ab160C4B66F31a28AE2448BfF68fc3a2ef0Send only Ethereum/ERC-20 compatible assets to this address.