Chapter 03Lesson 02~105 minutes

JENKINS_HOME, Filesystem Layout, Controller Configuration, System Settings, Tools, and Global Properties: Guided Hands-On Workflow and Core Operations

Inspect a disposable JENKINS_HOME, make safe controller configuration changes, prove persistence across restart, separate controller state from workspace state, and create guarded snapshots.

Hands-onSystem settingsGlobal propertiesRestart persistenceSnapshot

Learning objectives

  • Start an isolated Jenkins 2.568.3 LTS controller with a named home volume and verify home path, OS identity, and safe filesystem metadata.
  • Make one controlled System Message change and one synthetic global environment property, then locate the persisted state without dumping unrelated configuration.
  • Prove the changes survive controller restart and distinguish container-local temporary files from mounted controller state.
  • Create a stopped-controller snapshot whose ordinary data and secret-key recovery material are kept in separate backup volumes.
  • Record a minimal evidence packet that can be reviewed without containing passwords, tokens, secret files, or proprietary source.

1. Preflight: create a chapter-specific disposable controller

This lab is independent of Chapter 02 so it remains runnable even if that controller was removed. It binds Jenkins to loopback and uses a chapter-specific named volume. The setup wizard still requires a local browser step; do not expose it publicly.

docker --version
docker pull jenkins/jenkins:2.568.3-jdk21

docker volume create jenkins-ch03-home
docker run -d \
  --name jenkins-ch03-controller \
  --restart=no \
  -p 127.0.0.1:18083:8080 \
  -v jenkins-ch03-home:/var/jenkins_home \
  jenkins/jenkins:2.568.3-jdk21

docker logs --tail 80 jenkins-ch03-controller

Open http://127.0.0.1:18083 and complete the local setup wizard with synthetic training values. Retrieve the initial administrator password locally only when the wizard requires it. Do not paste that password into evidence, source control, screenshots, or chat.

2. Capture a metadata-only baseline

mkdir -p jenkins-ch03-evidence

docker exec jenkins-ch03-controller sh -lc '
  printf "JENKINS_HOME=%s\n" "$JENKINS_HOME"
  id
  java -version 2>&1 | head -4
  stat -c "owner=%U:%G mode=%a path=%n" "$JENKINS_HOME"
  printf "top-level entries:\n"
  find "$JENKINS_HOME" -maxdepth 1 -mindepth 1 -printf "%f\n" | sort
' | tee jenkins-ch03-evidence/baseline.txt

docker inspect --format='image={{.Config.Image}} mount={{range .Mounts}}{{.Name}}:{{.Destination}}{{end}}' \
  jenkins-ch03-controller | tee -a jenkins-ch03-evidence/baseline.txt

The inventory intentionally records names rather than file contents. If you need version evidence, use Manage Jenkins → About/System Information or an authenticated API request after setup; do not infer the running core version solely from a tag.

3. Make controlled changes through supported UI surfaces

In the disposable controller, open Manage Jenkins → System. Set the System Message to:

DevOps Academy — Chapter 03 disposable controller

On the same page, under Global properties, enable Environment variables and add:

ACADEMY_CHAPTER = 03

Save. These values are synthetic and safe to find in persisted configuration. Do not use this exercise to add credentials, tokens, SMTP passwords, cloud keys, or other real secrets.

Why two changes? The system message is a visible controller setting; the global property affects build environment. Both demonstrate that one supported UI action is serialized into durable controller state.

4. Map persisted files before and after without dumping them

docker exec jenkins-ch03-controller sh -lc '
  stat -c "%y %s %n" "$JENKINS_HOME/config.xml"
  grep -n -E "systemMessage|ACADEMY_CHAPTER" "$JENKINS_HOME/config.xml" || true
' | tee jenkins-ch03-evidence/config-safe-excerpt.txt

docker exec jenkins-ch03-controller sh -lc '
  find "$JENKINS_HOME" -maxdepth 2 -type f \
    ! -path "*/secrets/*" \
    -printf "%TY-%Tm-%Td %TH:%TM:%TS %10s %p\n" 2>/dev/null \
    | sort | tail -80
' > jenkins-ch03-evidence/recent-files.txt

We grep only the two synthetic values we created. A production config.xml or plugin XML may contain sensitive or security-relevant values, so “cat every XML file” is not an acceptable evidence strategy.

5. Restart proves persistence—not recoverability

docker restart jenkins-ch03-controller
docker logs --tail 60 jenkins-ch03-controller

docker exec jenkins-ch03-controller sh -lc '
  grep -n -E "systemMessage|ACADEMY_CHAPTER" "$JENKINS_HOME/config.xml" || true
'

Reload the UI and confirm the System Message is still present. A restart demonstrates that the value is on durable controller storage. It does not prove that the volume can be restored after deletion, that plugin versions are recoverable, or that external integrations still work.

6. Prove that container-local temporary state is different

docker exec jenkins-ch03-controller sh -lc '
  printf "temporary chapter03 marker\n" > /tmp/jenkins-ch03-ephemeral.txt
  printf "durable chapter03 marker\n" > "$JENKINS_HOME/ch03-durable-marker.txt"
  ls -l /tmp/jenkins-ch03-ephemeral.txt "$JENKINS_HOME/ch03-durable-marker.txt"
'

The /tmp marker lives in the container layer. The home marker lives on the named volume. The checkpoint lab will recreate a controller from backup and verify that the durable marker returns while the container-local marker does not. Neither marker represents an agent workspace; agent execution state belongs to the agent machine/container/pod and is covered in later chapters.

7. Guarded snapshot: stop first, separate ordinary data from secret keys

For this training controller, we make a consistent stopped-controller snapshot. Production systems may use storage snapshots and coordinated backup tooling, but the same trust boundary applies.

docker stop jenkins-ch03-controller

docker volume create jenkins-ch03-config-backup
docker volume create jenkins-ch03-secret-backup

# Ordinary controller backup: intentionally excludes the secrets directory.
docker run --rm --entrypoint /bin/sh \
  -v jenkins-ch03-home:/source:ro \
  -v jenkins-ch03-config-backup:/backup \
  jenkins/jenkins:2.568.3-jdk21 -c '
    cd /source &&
    tar --exclude=./secrets -czf /backup/jenkins-home-nonsecrets.tgz . &&
    sha256sum /backup/jenkins-home-nonsecrets.tgz
  '

# Protected recovery material: kept in a separate volume.
docker run --rm --entrypoint /bin/sh \
  -v jenkins-ch03-home:/source:ro \
  -v jenkins-ch03-secret-backup:/backup \
  jenkins/jenkins:2.568.3-jdk21 -c '
    cd /source &&
    tar -czf /backup/jenkins-secrets.tgz secrets &&
    chmod 600 /backup/jenkins-secrets.tgz &&
    ls -l /backup/jenkins-secrets.tgz
  '

docker start jenkins-ch03-controller
Training simulation: two local Docker volumes demonstrate separation; a real recovery design stores secret-key material under a stronger, separately controlled trust boundary. Never upload either archive to a public repository.

8. Controller home is not an agent workspace

Current Jenkins controller-isolation guidance is to run builds on agents instead of the built-in node. When later chapters create agents, their workspaces may exist on entirely different filesystems and disappear when ephemeral agents terminate. Therefore:

  • Do not put release truth in an agent workspace.
  • Do not copy arbitrary workspaces into controller backups.
  • Archive or publish intended evidence explicitly.
  • Record source SHA, build number, artifact digest, and external repository identity instead of relying on “the file was still in workspace.”

9. Mini challenge: classify the state before choosing a fix

For each item, decide whether it belongs to controller durable state, separately protected recovery material, agent execution state, or an external system:

  1. A global System Message.
  2. The encryption keys under JENKINS_HOME/secrets.
  3. A Maven target/ directory on a Kubernetes agent.
  4. A promoted package in Nexus.
  5. A job’s retained build record and archived artifact.

Then state what evidence proves recovery for each. The correct answer is not “back up everything together.”

10. Cleanup choices

If you are continuing to Lesson 5, keep the controller and three volumes. Otherwise remove only the chapter resources you created:

docker rm -f jenkins-ch03-controller
# Delete these only if you intentionally discard the lab and its recovery exercise:
# docker volume rm jenkins-ch03-home jenkins-ch03-config-backup jenkins-ch03-secret-backup
rm -rf jenkins-ch03-evidence

11. Summary

  • Supported UI changes become durable controller state under JENKINS_HOME.
  • Metadata-only inspection is safer than dumping controller configuration.
  • A restart proves persistence, not disaster recovery.
  • Container-local files, controller-home files, agent workspaces, and external systems are distinct layers.
  • Consistent backups and separately protected secret-key recovery material are both required for a credible restore.
Next lesson

Configuration, Design Choices, and Tradeoffs

Turn the filesystem observations into operating decisions: UI versus configuration as code, global versus agent-local tools, selective versus full backups, and controller-local versus external state.

Knowledge check

Why does this lab stop the controller before creating its tar snapshots?

Why is the secrets archive kept separately?

A System Message survives docker restart. What remains unproven?

Why is /tmp/jenkins-ch03-ephemeral.txt useful in the lesson?

What should you collect instead of the contents of the secrets directory?

Official references and version notes

Version and compatibility note

Version-sensitive statements were rechecked on 2026-09-14. The disposable baseline continues Chapter 02 with Jenkins 2.568.3 LTS on Java 21 using the official jenkins/jenkins:2.568.3-jdk21 image. Jenkins and plugins evolve; regenerate the storage map from the actual controller, keep plugin-specific files opaque unless the plugin documents them, and re-check backup/security guidance before applying the patterns to a production controller.

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.