Where Are Jenkins Configuration Files Managed? Understanding JENKINS_HOME Structure

Jenkins stores all configuration files in the directory defined by the JENKINS_HOME environment variable, with the global system configuration residing in a top-level config.xml file and separate subdirectories managing nodes, jobs, users, and plugins.

Jenkins persists its entire state to the filesystem through XML-based configuration files. According to the jenkinsci/jenkins source code, understanding where these files live and how they are structured is essential for backup strategies, migration tasks, and troubleshooting configuration drift.

The JENKINS_HOME Directory Structure

The JENKINS_HOME environment variable (or legacy HUDSON_HOME) defines the root directory where Jenkins maintains its persistent data. This location is validated at startup in core/src/main/java/hudson/Main.java at line 74, which ensures the directory exists and is writable. The default location varies by installation but can be overridden via command-line arguments defined in war/src/main/java/executable/Main.java at line 513.

Within this directory, Jenkins organizes configuration hierarchically:

  • Global configuration: config.xml at the root
  • Nodes: nodes/<node-name>/config.xml
  • Jobs: jobs/<job-name>/config.xml
  • Users: users/<user-id>/config.xml
  • Plugins: plugins/ directory
  • Secrets: secrets/ directory including master.key

Global System Configuration

The top-level system configuration lives in $JENKINS_HOME/config.xml. In core/src/main/java/jenkins/model/Jenkins.java at line 3279, Jenkins initializes this file using:

File root = Jenkins.get().getRootDir();
XmlFile globalConfig = new XmlFile(XSTREAM, new File(root, "config.xml"));

This file contains global settings such as system message, security realm, authorization strategy, and plugin-specific global configurations. Jenkins loads this during initialization and rewrites it whenever an administrator saves changes via the Manage Jenkins interface.

Node and Agent Configuration

Each Jenkins agent (node) maintains its own config.xml within a dedicated subdirectory. The core/src/main/java/jenkins/model/Nodes.java class handles this at line 223:

File nodeDir = new File(root, "nodes/" + nodeName);
XmlFile nodeConfig = new XmlFile(Jenkins.XSTREAM, new File(nodeDir, "config.xml"));

These files store the node name, description, number of executors, remote root directory, labels, and launcher configuration.

Job and Project Configuration

Individual job configurations reside under $JENKINS_HOME/jobs/<job-name>/config.xml. While the specific handling code spans multiple classes (notably hudson/model/Job.java), each job uses the same XmlFile pattern to serialize its build steps, SCM settings, triggers, and post-build actions.

User Configuration

User accounts and their metadata are stored in $JENKINS_HOME/users/<user-id>/config.xml. The User class manages these files through the XmlFile helper, persisting details such as the user's full name, API tokens, and security realm-specific data.

Plugin Configuration

Plugins store their global settings in distinct locations. Plugin archives reside in $JENKINS_HOME/plugins/ as .jpi files or exploded directories. The PluginManager class reads these configurations, while individual plugins may maintain their own XML files within the JENKINS_HOME structure.

Security Secrets and Encryption

Sensitive data is isolated from the main configuration files. The core/src/main/java/jenkins/security/DefaultConfidentialStore.java class (line 27) manages the secrets/ directory, including the master.key file used to encrypt other secrets. This separation ensures that credential stores and other sensitive configuration elements remain protected even if config.xml files are exposed.

How Jenkins Loads Configuration at Startup

When Jenkins boots, it follows a specific sequence to reconstruct its state:

  1. Validate environment: core/src/main/java/hudson/Main.java verifies that JENKINS_HOME exists and is writable.
  2. Load global config: Jenkins.java deserializes the root config.xml using XStream.
  3. Initialize nodes: The Nodes class iterates through the nodes/ directory, loading each config.xml.
  4. Load jobs: Jenkins scans the jobs/ directory, instantiating each project from its configuration file.
  5. Restore users: The User class loads user metadata from the users/ directory.

This process ensures that the entire state of the Jenkins instance is restored from the filesystem before accepting any connections.

Reading and Writing Configuration Files Programmatically

You can interact with Jenkins configuration files through the Java API or REST interface.

To access configuration programmatically within a Jenkins plugin:

// Load the global configuration
File root = Jenkins.get().getRootDir();
XmlFile globalConfig = new XmlFile(Jenkins.XSTREAM,
                                   new File(root, "config.xml"));
JenkinsConfig config = (JenkinsConfig) globalConfig.read();

// Save a node's configuration
File nodeDir = new File(root, "nodes/my-agent");
XmlFile nodeConfig = new XmlFile(Jenkins.XSTREAM,
                                 new File(nodeDir, "config.xml"));
nodeConfig.write(myNode);

To retrieve a job configuration via the REST API:

def jobConfig = new URL("${JENKINS_URL}/job/MyJob/config.xml")
                .openConnection()
                .with { setRequestMethod('GET'); inputStream.text }
println jobConfig

Summary

  • Jenkins configuration files are centralized under the JENKINS_HOME directory, controlled by the JENKINS_HOME environment variable.
  • The global system configuration resides in $JENKINS_HOME/config.xml, loaded by jenkins/model/Jenkins.java.
  • Node configurations are stored in individual subdirectories under nodes/, managed by jenkins/model/Nodes.java.
  • Job configurations live in jobs/<job-name>/config.xml, with each job managing its own XML serialization.
  • Sensitive data is stored separately in the secrets/ directory, handled by DefaultConfidentialStore.java.
  • Jenkins uses XStream-based XML serialization through the XmlFile class to persist and restore all configuration state.

Frequently Asked Questions

What environment variable controls where Jenkins stores configuration files?

The JENKINS_HOME environment variable defines the root directory for all Jenkins configuration files. If unset, Jenkins falls back to the legacy HUDSON_HOME variable or uses platform-specific defaults. The launcher code in war/src/main/java/executable/Main.java defines these defaults, while core/src/main/java/hudson/Main.java validates the directory's existence and write permissions at startup.

Where are Jenkins job configurations stored?

Job configurations are stored in $JENKINS_HOME/jobs/<job-name>/config.xml. Each job directory contains its own config.xml file that defines build steps, SCM settings, triggers, and parameters. The hudson/model/Job.java class and its subclasses handle the reading and writing of these files through the standard XmlFile mechanism.

How does Jenkins encrypt sensitive configuration data?

Jenkins stores encryption keys and sensitive secrets in the $JENKINS_HOME/secrets/ directory, separate from the main config.xml files. The DefaultConfidentialStore.java class manages this storage, including the master.key file that encrypts other confidential data. This architecture ensures that credentials and API keys remain encrypted even if someone gains access to the configuration XML files.

Can I edit Jenkins configuration files manually?

While possible, manual editing of Jenkins configuration files is not recommended without proper precautions. Changes to config.xml files require a Jenkins reload or restart to take effect, and syntax errors can prevent Jenkins from starting. Always back up JENKINS_HOME before manual modifications, and consider using the Reload Configuration from Disk option in the Manage Jenkins interface rather than restarting the service.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →