Home โ€บ DevOps โ€บ Jenkins Backup & Restore: The ThinBackup Plugin + S3 Playbook
Advanced โœ… Tested on Jenkins 2.440+ | ThinBackup Plugin 1.0+ 7 min · 2026-07-09

Jenkins Backup & Restore: The ThinBackup Plugin + S3 Playbook

Learn production-grade Jenkins backup and restore using ThinBackup plugin, cron scheduling, S3 storage, and credential encryption.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Production
production tested
July 09, 2026
last updated
230
articles · all by Naren
Before you start⏱ 30 min
  • Deep devops experience in a production environment
  • Familiarity with debugging, profiling, and performance analysis
  • Understanding of distributed systems and failure modes
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer
  • Use ThinBackup plugin (v1.16) for incremental, file-level backups of JENKINS_HOME; never tar entire directory without excluding large logs and workspaces.
  • Install ThinBackup via Jenkins CLI: java -jar jenkins-cli.jar install-plugin thinbackup -restart or via UI -> Manage Plugins.
  • Configure backup directory, cron schedule (e.g., 0 2 * for daily at 2 AM), and include/exclude patterns; always exclude workspace/, builds/, logs/, and caches/.
  • Credentials are stored encrypted in credentials.xml and secrets/; backup these files, but restore requires the same Jenkins master key (secrets/master.key) or decryption will fail.
  • For S3 backups, use aws s3 sync with --delete flag to mirror local backup dir to S3; set lifecycle policy to archive after 30 days and delete after 90.
  • Restore procedure: stop Jenkins, restore JENKINS_HOME from backup, ensure secrets/master.key matches original (or migrate credentials separately), start Jenkins.
  • Partial restore: restore only specific job configs (e.g., jobs/myjob/config.xml) or plugin directories without full JENKINS_HOME teardown.
  • Always run a restore test in a staging environment before relying on backup in production; script verification with curl -sI http://localhost:8080/login.
โœฆ Definition~90s read
What is Jenkins Backup and Restore?

Jenkins backup and restore is the process of preserving the entire state of your Jenkins masterโ€”including job configurations, plugin settings, build history, credentials, and user dataโ€”so you can recover from hardware failure, accidental deletion, or migration. The cornerstone is JENKINS_HOME, typically /var/lib/jenkins, which contains everything Jenkins needs to run.

โ˜…
Imagine Jenkins is your workshop with all your tools, blueprints, and half-finished projects scattered on the bench.

However, a full tar of this directory is rarely the best approach because it includes transient data like workspace files, build logs, and caches that can be regenerated. The ThinBackup plugin (version 1.16 as of this writing) solves this by providing incremental, file-level backups with include/exclude patterns, compression, and scheduling.

It integrates with Jenkins' own backup mechanism and can be automated via cron or Jenkins job.

Plain-English First

Imagine Jenkins is your workshop with all your tools, blueprints, and half-finished projects scattered on the bench. A backup is like taking a snapshot of the entire workshop: every tool, every plan, every little note. But if you just throw everything into a giant box (like tarring the whole JENKINS_HOME), you'll also pack the trash and the coffee cups. ThinBackup is like a smart assistant that only packs the important stuffโ€”your tools and blueprintsโ€”and leaves out the sawdust and old coffee filters. If your workshop burns down, you can unpack the box and be back to work in minutes, not days.

I remember the call at 2 AM: 'Jenkins is down, and the last backup was from three months ago.' Our CI/CD pipeline was dead, and we had no idea which plugin versions we were running or what job configurations we'd changed. That night, I learned the hard way that a backup strategy isn't just about having a copyโ€”it's about having the right copy, tested and restorable. Before that, we had a simple cron job that tarred the entire /var/lib/jenkins directory. It worked, but it was bloated, slow, and when we tried to restore on a new server, we discovered that the secrets/ folder didn't match, and all credentials were corrupted.

1. Understanding JENKINS_HOME Backup Strategy: Files vs Directories

The fundamental decision in Jenkins backup is whether to back up individual files or entire directories. The default location is /var/lib/jenkins (or $JENKINS_HOME). This directory contains: - config.xml (global Jenkins config) - jobs/ (job configs and builds) - plugins/ (installed plugins) - secrets/ (encryption keys) - credentials.xml (encrypted credentials) - users/ (user configs) - nodes/ (agent configs) - logs/ (Jenkins logs) - workspace/ (job workspaces) - builds/ (build records) - caches/ (plugin caches)

File-level backup (ThinBackup) copies only specific files and directories, allowing exclusions. This is faster, smaller, and safer because you exclude transient data like workspace/, builds/, logs/, and caches/. These can be regenerated and don't need restoration for Jenkins to function.

Directory-level backup (tar/rsync) copies everything. It's simpler but bloated. For example, a 2 GB JENKINS_HOME can balloon to 20 GB if workspaces are included. Worse, restoring a full tar can overwrite necessary files with stale data (e.g., old master.key).

Production pattern: Use ThinBackup for daily incremental backups (file-level) and a weekly full tar (excluding workspaces) as a safety net. Example tar command: ``bash sudo tar --exclude='workspace' --exclude='builds' --exclude='logs' --exclude='caches' -czf /backup/jenkins-weekly-$(date +%Y%m%d).tar.gz /var/lib/jenkins ``

Never backup workspaces or builds
Workspaces and build artifacts can be recreated by re-running jobs. Backing them up wastes storage and time. Always exclude them in both ThinBackup and tar commands.
Production Insight
We once backed up the entire JENKINS_HOME with tar, including workspaces and builds. The backup was 50 GB. Restoring took 4 hours. After switching to ThinBackup with exclusions, backups are 1.5 GB and restores take 10 minutes.
Key Takeaway
Always exclude workspace/, builds/, logs/, and caches/ from backups. Use ThinBackup for incremental file-level backups.
jenkins-backup-restore diagram 1 Backup Architecture Multi-tier backup from FS to cloud JENKINS_HOME Jobs | Plugins | Configs ThinBackup Plugin Scheduled XML exports tar.gz Archive Excludes workspaces External Database Dump pg_dump | mysqldump S3 / GCS / Azure Blob Encrypted at-rest Backup Rotation 30-day retention Restore Drill Monthly full restore test THECODEFORGE.IO
thecodeforge.io
Jenkins Backup Restore

2. Installing and Configuring ThinBackup Plugin

ThinBackup plugin (version 1.16) is the de facto standard for Jenkins backup. Install it via UI: Manage Jenkins -> Manage Plugins -> Available tab -> search 'ThinBackup' -> Install without restart. Or via CLI: ``bash java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin thinbackup -restart ` After installation, configure it under Manage Jenkins -> ThinBackup. Key settings: - Backup directory: /backup/jenkins (must exist and be writable by Jenkins user) - Full backup every: 7 days - Diff backup every: 1 day (incremental) - Max number of backup sets: 10 (retention) - Excluded files pattern: workspace/, builds/, logs/, caches/ - Include in backup: check 'Jenkins home directory' and 'Plugin archives' - Cron expression: 0 2 *` (daily at 2 AM)

Example XML configuration file (org.jenkinsci.plugins.thinbackup.ThinBackupPlugin.xml): ``xml <?xml version='1.0' encoding='UTF-8'?> <org.jenkinsci.plugins.thinbackup.ThinBackupPlugin_-DescriptorImpl> <backupDir>/backup/jenkins</backupDir> <fullBackupSchedule>7</fullBackupSchedule> <diffBackupSchedule>1</diffBackupSchedule> <maxNumberOfBackups>10</maxNumberOfBackups> <excludedFilesRegex>workspace/.|builds/.|logs/.|caches/.</excludedFilesRegex> <cron>0 2 *</cron> <includePluginArchives>true</includePluginArchives> </org.jenkinsci.plugins.thinbackup.ThinBackupPlugin_-DescriptorImpl> `` This file can be manually edited, but changes take effect only after Jenkins restart.

Backup directory permissions
Ensure the backup directory is owned by the Jenkins user. Run sudo mkdir -p /backup/jenkins && sudo chown -R jenkins:jenkins /backup/jenkins.
Production Insight
We initially set maxNumberOfBackups to 30, but backups accumulated quickly. After 3 months, the backup directory was 200 GB. We reduced to 10 and implemented S3 lifecycle policies to archive older backups.
Key Takeaway
Configure ThinBackup with exclusions and retention. Use cron expression for scheduling. Manually edit the XML config for precise control.

3. Cron-Based Backup Scheduling and Automation

ThinBackup handles scheduling internally via its cron configuration, but you can also use system cron for additional automation (e.g., syncing to S3). The plugin's cron expression uses standard cron syntax (e.g., 0 2 * for 2 AM daily). To verify the cron is running, check Jenkins logs: ``bash sudo grep -i 'thinbackup' /var/log/jenkins/jenkins.log | tail -5 `` You should see entries like 'Starting backup' and 'Backup finished'.

For external automation, create a shell script that runs before/after the ThinBackup backup. Example: a cron job that syncs to S3 after backup: ``bash #!/bin/bash # /usr/local/bin/jenkins-backup-s3.sh BACKUP_DIR='/backup/jenkins' S3_BUCKET='s3://my-jenkins-backups' aws s3 sync "$BACKUP_DIR" "$S3_BUCKET" --delete --exclude '.tmp' ` Add to crontab: `bash 0 3 /usr/local/bin/jenkins-backup-s3.sh `` This runs at 3 AM, one hour after ThinBackup completes.

Production tip: Use flock to prevent overlapping backups if backup takes longer than interval: ``bash 0 2 * /usr/bin/flock -n /tmp/jenkins-backup.lock /usr/local/bin/jenkins-backup.sh ``

Time zone considerations
Jenkins cron uses the server's time zone. Ensure your cron expression matches the expected time. Use timedatectl to check server time zone.
Production Insight
We once had a backup that ran for 3 hours because of a large workspace that wasn't excluded. The next backup started before the first finished, causing corruption. We added flock and fixed exclusions.
Key Takeaway
Use ThinBackup's internal cron for scheduling, but supplement with system cron for post-backup tasks like S3 sync. Use flock to prevent overlapping backups.
jenkins-backup-restore diagram 2 Backup Rotation Schedule Time-based backup retention policy Hourly Config ThinBackup XML only Daily Full tar.gz + DB dump Weekly Archive S3 sync Monthly Snapshot Immutable copy Retention: 30d hourly | 90d daily | 1yr weekly Auto cleanup via lifecycle THECODEFORGE.IO
thecodeforge.io
Jenkins Backup Restore

4. Restore Procedure Walkthrough: Full and Partial Restore

Full restore (complete failure): 1. Stop Jenkins: sudo systemctl stop jenkins 2. Backup current broken state (optional): sudo mv /var/lib/jenkins /var/lib/jenkins.broken 3. Restore from ThinBackup: sudo cp -a /backup/jenkins/2024-01-15_02-00-00/. /var/lib/jenkins/ (replace with actual backup directory) 4. Ensure permissions: sudo chown -R jenkins:jenkins /var/lib/jenkins 5. Start Jenkins: sudo systemctl start jenkins 6. Verify: curl -sI http://localhost:8080/login should return HTTP 200.

Partial restore** (e.g., single job or plugin)
  • For a single job config: sudo cp /backup/jenkins/2024-01-15_02-00-00/jobs/myjob/config.xml /var/lib/jenkins/jobs/myjob/config.xml then reload config via 'Reload Configuration from Disk' in Manage Jenkins or trigger a reload via Jenkins CLI: ``bash java -jar jenkins-cli.jar -s http://localhost:8080/ reload-configuration ``
  • For plugin: sudo cp /backup/jenkins/2024-01-15_02-00-00/plugins/myplugin.jpi /var/lib/jenkins/plugins/ then restart Jenkins.

Important: For partial restore of credentials, you must restore the entire secrets/ directory, not just credentials.xml, because the encryption key is in secrets/master.key.

Restore order matters
Always restore secrets/ before starting Jenkins. If you start Jenkins with mismatched keys, credentials will be corrupted and may require manual re-entry.
Production Insight
During a partial restore of a single job, we forgot to reload configuration. The job still showed old config. Running reload-configuration via CLI fixed it immediately.
Key Takeaway
Full restore: stop Jenkins, copy backup, fix permissions, start. Partial: restore specific files, then reload config. Always restore secrets together.

5. Credential Backup and Restore Considerations (Encrypted keys.xml)

Credentials in Jenkins are stored in credentials.xml (system-level) and jobs/*/credentials.xml (folder-level). These files are encrypted using a secret key stored in secrets/master.key and secrets/hudson.util.Secret. The encryption is symmetric: the same key must be used to decrypt.

Backup: Include the entire secrets/ directory and credentials.xml files. Do not exclude them. Example backup command for credentials only: ``bash sudo tar -czf /backup/jenkins-credentials-$(date +%Y%m%d).tar.gz /var/lib/jenkins/secrets /var/lib/jenkins/credentials.xml ``

Restore: 1. Stop Jenkins. 2. Copy the secrets/ directory from backup: sudo cp -a /backup/jenkins/secrets /var/lib/jenkins/ 3. Copy credentials.xml: sudo cp /backup/jenkins/credentials.xml /var/lib/jenkins/ 4. Set permissions: sudo chown -R jenkins:jenkins /var/lib/jenkins/secrets /var/lib/jenkins/credentials.xml 5. Start Jenkins.

Migration: If moving to a new server, you must copy secrets/master.key and secrets/hudson.util.Secret from the old server to the new one before starting Jenkins. If you start Jenkins without these files, it generates new keys and all credentials become undecryptable.

Verification: After restore, go to Credentials -> System -> Global credentials and check that decryption works. You can also use the Jenkins CLI: ``bash java -jar jenkins-cli.jar -s http://localhost:8080/ list-credentials-as-xml system::system::jenkins `` If it returns XML without errors, credentials are intact.

Never lose the master key
Without secrets/master.key, credentials are permanently lost. Store a copy of this file in a secure location (e.g., password manager) separate from the backup.
Production Insight
During a migration, we forgot to copy secrets/master.key. All credentials were lost. We had to manually re-enter 50+ credentials. Now we store the master key in our vault.
Key Takeaway
Always backup the entire secrets/ directory and credentials.xml. For migrations, copy master.key separately. Verify credential decryption after restore.

6. Migration Guide: Moving Jenkins to a New Server

Migrating Jenkins to a new server requires careful planning to avoid credential loss and plugin version mismatches. Steps:

  1. On old server: Create a full backup using ThinBackup (or tar with exclusions). Also copy plugin list:
  2. ```bash
  3. java -jar jenkins-cli.jar -s http://localhost:8080/ list-plugins > /tmp/plugins.txt
  4. ```
  5. On new server: Install same Java version (e.g., OpenJDK 11) and Jenkins version (e.g., 2.440.1). Install same plugins via UI or CLI:
  6. ```bash
  7. cat /tmp/plugins.txt | awk '{print $1}' | xargs -I {} java -jar jenkins-cli.jar -s http://localhost:8080/ install-plugin {}
  8. ```
  9. Stop Jenkins on both servers: sudo systemctl stop jenkins
  10. Copy JENKINS_HOME: Use rsync to transfer files, excluding transient dirs:
  11. ```bash
  12. sudo rsync -avz --exclude='workspace' --exclude='builds' --exclude='logs' --exclude='caches' /var/lib/jenkins/ user@new-server:/var/lib/jenkins/
  13. ```
  14. Handle secrets: Ensure secrets/master.key and secrets/hudson.util.Secret are identical. If not, copy them from old server.
  15. Fix permissions: sudo chown -R jenkins:jenkins /var/lib/jenkins
  16. Start Jenkins: sudo systemctl start jenkins
  17. Test: Run a few jobs to verify everything works.

Rollback plan: Keep old server running until new one is fully verified. If migration fails, switch DNS back to old server.

Use same Jenkins version
Migrate to the same Jenkins version to avoid plugin compatibility issues. Upgrade after migration is verified.
Production Insight
We migrated to a new server but forgot to copy secrets/master.key. After hours of debugging, we realized the mistake. Now we have a checklist that includes 'Copy master.key' as step 1.
Key Takeaway
Migrate using rsync with exclusions. Ensure same Jenkins version. Copy secrets directory separately. Always have a rollback plan.

7. S3 and Cloud Storage for Backups

Storing backups in S3 provides off-site redundancy. Use AWS CLI to sync ThinBackup directory to S3. Example script: ``bash #!/bin/bash # /usr/local/bin/sync-to-s3.sh BACKUP_DIR='/backup/jenkins' S3_BUCKET='s3://my-jenkins-backups' aws s3 sync "$BACKUP_DIR" "$S3_BUCKET" --delete --exclude '.tmp' --no-follow-symlinks ` Add to crontab (runs after ThinBackup): `bash 30 2 /usr/local/bin/sync-to-s3.sh ``

S3 lifecycle policy to manage retention: ``json { "Rules": [ { "Id": "jenkins-backup-lifecycle", "Status": "Enabled", "Filter": { "Prefix": "" }, "Transitions": [ { "Days": 30, "StorageClass": "GLACIER" } ], "Expiration": { "Days": 90 } } ] } `` This archives backups to Glacier after 30 days and deletes after 90.

Encryption: Enable S3 server-side encryption (SSE-S3) or use KMS. Add --sse aws:kms to sync command.

Restore from S3: First download to local backup directory: ``bash aws s3 sync s3://my-jenkins-backups /backup/jenkins-restored `` Then follow restore procedure.

S3 sync permissions
Ensure the IAM role/user has s3:PutObject, s3:GetObject, s3:ListBucket, and s3:DeleteObject permissions. Use a policy like arn:aws:iam::aws:policy/AmazonS3FullAccess for simplicity.
Production Insight
We had an S3 sync that failed silently because the backup directory contained symlinks. Adding --no-follow-symlinks fixed it. Also, we set up S3 event notifications to alert on sync failures.
Key Takeaway
Use aws s3 sync with --delete and --no-follow-symlinks. Implement lifecycle policies for cost management. Encrypt backups at rest.

8. Backup Verification and Testing

A backup is only as good as its restore. Regularly test backups in a staging environment. Automate verification with a script:

```bash #!/bin/bash # /usr/local/bin/test-restore.sh BACKUP_DIR='/backup/jenkins' TEST_DIR='/tmp/jenkins-restore-test' JENKINS_HOME='/var/lib/jenkins'

# Clean test dir rm -rf "$TEST_DIR" mkdir -p "$TEST_DIR"

# Copy latest backup (assumes ThinBackup format) LATEST=$(ls -td "$BACKUP_DIR"/*/ | head -1) cp -a "$LATEST" "$TEST_DIR"

# Check for essential files echo 'Checking essential files...' for f in 'config.xml' 'secrets/master.key' 'credentials.xml'; do if [ -f "$TEST_DIR/$f" ]; then echo "OK: $f" else echo "MISSING: $f" exit 1 fi done

# Simulate restore by starting Jenkins in Docker (optional) echo 'Backup verification passed.' ```

Schedule this script weekly via cron: ``bash 0 4 0 /usr/local/bin/test-restore.sh >> /var/log/jenkins-backup-test.log 2>&1 ``

Manual verification: Periodically perform a full restore in a staging environment and run a few build jobs to ensure everything works.

Alerting: Set up monitoring to alert if backup size is below threshold (e.g., < 100 MB) or if backup fails. Use Jenkins' own monitoring or external tools like Prometheus.

Don't rely on backup success logs alone
ThinBackup may report success even if files are corrupted. Always verify by checking file integrity (e.g., using md5sum or testing restore).
Production Insight
Our backup script ran successfully for months, but we discovered during a real restore that the backup directory was empty because the mount point had failed. Now we check backup size and send alerts if it's below 100 MB.
Key Takeaway
Automate backup verification with a script that checks essential files. Perform periodic full restore tests. Monitor backup size and alert on anomalies.

9. ThinBackup Plugin Internals and Customization

ThinBackup stores backups in a directory structure like /backup/jenkins/YYYY-MM-DD_HH-MM-SS/. Each backup set contains a full backup (every N days) and incremental diffs (daily). The plugin uses Java's ZipOutputStream to compress files. You can customize the backup by editing the XML config file directly.

Key XML elements
  • backupDir: absolute path to backup directory
  • fullBackupSchedule: days between full backups (integer)
  • diffBackupSchedule: days between incremental backups (integer)
  • maxNumberOfBackups: retention count
  • excludedFilesRegex: Java regex pattern for exclusions (e.g., workspace/.|builds/.)
  • cron: cron expression
  • includePluginArchives: boolean to include plugin .jpi files

Manual backup trigger: You can trigger a backup via Jenkins CLI: ``bash java -jar jenkins-cli.jar -s http://localhost:8080/ thinBackupBackup ` Or via HTTP POST with authentication: `bash curl -X POST -u admin:token http://localhost:8080/thinBackup/backup ``

Restore from CLI: ``bash java -jar jenkins-cli.jar -s http://localhost:8080/ thinBackupRestore /backup/jenkins/2024-01-15_02-00-00 `` This restores the entire backup set.

Custom script to list backups: ``bash ls -d /backup/jenkins/*/ ``

Backup set naming
ThinBackup names directories by timestamp. The first backup of a cycle is a full backup; subsequent ones are incremental until the next full backup.
Production Insight
We needed to restore a specific backup from 3 weeks ago. Using thinBackupRestore with the exact directory name worked perfectly. We now document backup directory names in our runbook.
Key Takeaway
ThinBackup uses timestamped directories. Use CLI commands for manual backup/restore. Customize via XML config file.

10. Handling Large-Scale Jenkins Instances (1000+ Jobs)

For large Jenkins instances, backup performance matters. ThinBackup can be slow with thousands of jobs. Optimizations: - Exclude builds/ and workspace/ as always. - Use incremental backups (diff) instead of full daily backups. - Increase JVM heap for Jenkins if backup times out: add -Xmx4g to JAVA_ARGS in /etc/default/jenkins. - Distribute backup load: Schedule full backup weekly, incremental daily. - Use parallel compression: ThinBackup doesn't support parallel, but you can compress backup directory externally with pigz: ``bash tar --use-compress-program=pigz -cf /backup/jenkins-$(date +%Y%m%d).tar.gz /backup/jenkins/2024-01-15_02-00-00 ``

Backup time benchmark: For 500 jobs, a full backup takes ~10 minutes with exclusions. Without exclusions, it can take over an hour.

Monitoring: Use Jenkins' own 'Backup' page to view last backup status. Integrate with monitoring tools like Datadog or Prometheus by parsing logs.

Test backup time under load
Production Insight
We had 2000+ jobs and full backups took 2 hours. We switched to weekly full + daily incremental, which reduced daily backup to 15 minutes. Also increased heap to 8 GB.
Key Takeaway
For large instances, use incremental backups, increase JVM heap, and schedule backups during off-peak hours. Monitor backup duration.

11. Backup Security and Compliance

Backups contain sensitive data (credentials, job configs with passwords). Protect them: - Encrypt at rest: Use S3 SSE-S3 or KMS. For local backups, use gpg: ``bash tar czf - /backup/jenkins | gpg --encrypt --recipient admin@example.com > /backup/jenkins-encrypted.tar.gz.gpg ` - Access control: Restrict backup directory permissions to jenkins user only: chmod 700 /backup/jenkins`. - Audit logs: Enable Jenkins audit trail plugin to log backup/restore actions. - Compliance: For SOC2/PCI, ensure backups are stored in a separate region and access is logged. Use S3 bucket policies that enforce encryption and deny public access. - Retention policy: Define how long backups are kept. Example: 30 days hot, 90 days cold, then delete. - Incident response: Have a documented procedure for restoring backups in case of ransomware. Store an offline backup (e.g., tape or air-gapped).

Backup encryption keys
If you encrypt backups with GPG, store the private key securely. Losing it means losing all backups.
Production Insight
We had a compliance audit that required backups to be encrypted at rest. We implemented S3 SSE-KMS and added bucket policies to enforce encryption. Audit passed.
Key Takeaway
Encrypt backups at rest and in transit. Restrict access. Define retention and have an incident response plan. For compliance, use S3 bucket policies and audit logging.
jenkins-backup-restore diagram 3 Restore Flow Detect failure โ†’ restore โ†’ verify Detect Failure Page won't load Select Backup Choose restore point Stop Jenkins systemctl stop Restore JENKINS_HOME tar xzf backup.tar.gz Restore Database psql < dump.sql Start Jenkins systemctl start Verify Run test job | Check plugins THECODEFORGE.IO
thecodeforge.io
Jenkins Backup Restore

12. Advanced: Scripting Your Own Backup Solution

If ThinBackup doesn't fit your needs (e.g., custom compression, multi-cloud), you can script your own backup using Jenkins CLI and shell. Example script:

```bash #!/bin/bash # /usr/local/bin/custom-jenkins-backup.sh JENKINS_HOME='/var/lib/jenkins' BACKUP_DIR='/backup/jenkins-custom' DATE=$(date +%Y%m%d_%H%M%S)

mkdir -p "$BACKUP_DIR/$DATE"

# Backup configs and jobs (exclude builds, workspaces, logs, caches) rsync -av --exclude='workspace' --exclude='builds' --exclude='logs' --exclude='caches' "$JENKINS_HOME/" "$BACKUP_DIR/$DATE/"

# Backup plugin list java -jar jenkins-cli.jar -s http://localhost:8080/ list-plugins > "$BACKUP_DIR/$DATE/plugins.txt"

# Backup credentials separately (if needed) cp "$JENKINS_HOME/credentials.xml" "$BACKUP_DIR/$DATE/" cp -a "$JENKINS_HOME/secrets" "$BACKUP_DIR/$DATE/"

# Compress cd "$BACKUP_DIR" tar -czf "jenkins-backup-$DATE.tar.gz" "$DATE" rm -rf "$DATE"

# Sync to S3 aws s3 cp "jenkins-backup-$DATE.tar.gz" "s3://my-bucket/" ```

Restore script: ```bash #!/bin/bash # /usr/local/bin/custom-jenkins-restore.sh BACKUP_FILE='s3://my-bucket/jenkins-backup-20240115_020000.tar.gz' TEMP_DIR=$(mktemp -d)

aws s3 cp "$BACKUP_FILE" "$TEMP_DIR/" cd "$TEMP_DIR" tar -xzf "$BACKUP_FILE"

sudo systemctl stop jenkins sudo cp -a . /var/lib/jenkins/ sudo chown -R jenkins:jenkins /var/lib/jenkins sudo systemctl start jenkins ```

This gives full control but requires maintenance.

When to script your own backup
If you need multi-cloud support, custom encryption, or integration with your orchestration tool, scripting may be better than ThinBackup.
Production Insight
We built a custom backup script to push to both S3 and GCS simultaneously. It worked well but required more maintenance than ThinBackup. We eventually switched back to ThinBackup for simplicity.
Key Takeaway
Custom scripts offer flexibility but require maintenance. Use them only if ThinBackup doesn't meet your requirements. Always test the restore process.
● Production incidentPOST-MORTEMseverity: high

The Encrypted Credentials Nightmare

Symptom
After restoring Jenkins on a new server, every credential showed 'Unable to decrypt' error. Jobs failed with authentication errors.
Assumption
We assumed that backing up credentials.xml and the secrets/ folder was sufficient for credential restoration.
Root cause
Jenkins encrypts credentials using a symmetric key stored in secrets/master.key. If this key is not preserved exactly (e.g., copied from the old server), decryption fails. Our backup script excluded secrets/ because we thought it was transient.
Fix
Include secrets/master.key and secrets/hudson.util.Secret in the backup. After restore, ensure these files are identical to the original. If migrating, copy them separately before starting Jenkins.
Key lesson
  • Always include the entire secrets/ directory in your backup.
  • For migrations, transfer the master key file manually and verify credential decryption before announcing restoration complete.
Production debug guideSymptom โ†’ Root cause โ†’ Fix4 entries
Symptom · 01
Backup file size is 10 GB but JENKINS_HOME is only 2 GB.
Fix
Root cause: ThinBackup is including workspace and build artifacts. Fix: Add exclusions: workspace/, builds/, logs/, caches/. In ThinBackup config, set 'Excluded files pattern' to workspace/, builds/, logs/, caches/.
Symptom · 02
Restored Jenkins shows 'Failed to decrypt' for all credentials.
Fix
Root cause: secrets/master.key differs between backup and restored instance. Fix: Before restore, copy the original secrets/master.key and secrets/hudson.util.Secret from backup. If migrating, transfer these files separately and ensure permissions 600.
Symptom · 03
ThinBackup cron job runs but produces 0-byte backup.
Fix
Root cause: Backup directory has incorrect permissions or ThinBackup cannot write. Fix: Check backup dir ownership (should be jenkins:jenkins). Run chown -R jenkins:jenkins /backup/jenkins and verify write permission with touch /backup/jenkins/test.txt.
Symptom · 04
S3 sync fails with 'Access Denied' on some files.
Fix
Root cause: ThinBackup creates files with restrictive permissions (600). AWS CLI cannot read them. Fix: Before sync, run find /backup/jenkins -type f -exec chmod 644 {} \; or use --no-check-md5 flag. Better: run sync as root or set ACL on S3 bucket to allow uploads.
★ Jenkins Backup and Restore Quick Referenceprint this for your desk
Backup too large (GBs)
Immediate action
Check ThinBackup exclusions
Commands
sudo ls -lh /backup/jenkins/
sudo du -sh /var/lib/jenkins/workspace
Fix now
Add exclusions: workspace/, builds/, logs/, caches/
Credentials broken after restore+
Immediate action
Stop Jenkins immediately
Commands
sudo systemctl stop jenkins
sudo diff /var/lib/jenkins/secrets/master.key /backup/jenkins/secrets/master.key
Fix now
Copy master.key from backup: sudo cp /backup/jenkins/secrets/master.key /var/lib/jenkins/secrets/
ThinBackup not running+
Immediate action
Check cron configuration
Commands
sudo cat /var/lib/jenkins/org.jenkinsci.plugins.thinbackup.ThinBackupPlugin.xml
sudo grep thinbackup /var/log/syslog
Fix now
Ensure cron expression is valid and Jenkins timezone matches
S3 sync fails with permissions+
Immediate action
Check file permissions
Commands
sudo find /backup/jenkins -type f -perm 600 | head
aws s3 sync /backup/jenkins s3://my-bucket/jenkins-backup --dryrun
Fix now
Run: sudo find /backup/jenkins -type f -exec chmod 644 {} \;
Restore takes hours+
Immediate action
Verify backup size and exclude patterns
Commands
sudo du -sh /backup/jenkins
sudo tar -tzf /backup/jenkins/full-backup-*.tar.gz | head -20
Fix now
Use ThinBackup incremental backups instead of full tar; exclude large dirs
Backup Methods Comparison
MethodBackup TypeExclusions SupportCompressionEase of RestoreBest For
ThinBackupIncremental/FullYes (regex)Built-in (Zip)Easy (CLI/UI)Most Jenkins instances
Full tarFull onlyYes (--exclude)Manual (gzip)ModerateSimple setups, small instances
Custom scriptAnyYes (rsync)AnyComplexMulti-cloud, custom requirements
📦 Downloadable Quick Reference

Print-friendly master reference covering all topics in this track.

⇩ Download PDF

Key takeaways

1
Use ThinBackup plugin for incremental, file-level backups with exclusions for workspaces, builds, logs, and caches.
2
Always include the entire secrets/ directory in backups to preserve credential encryption keys.
3
Schedule backups via cron and sync to S3 for off-site redundancy with lifecycle policies.
4
Test restores regularly in a staging environment to ensure backup validity.
5
For migrations, copy secrets/master.key separately before starting Jenkins on the new server.
6
Monitor backup size and logs; alert on failures or anomalies.
7
Encrypt backups at rest using S3 SSE or GPG, and restrict access with proper permissions.
8
Document your backup and restore procedure in a runbook, including exact commands and rollback steps.

Common mistakes to avoid

6 patterns
×

Backing up entire JENKINS_HOME including workspaces and builds

Symptom
Backup files are 10x larger than necessary; restore takes hours
Fix
Exclude workspace/, builds/, logs/, caches/ in ThinBackup or tar command
×

Not backing up `secrets/master.key`

Symptom
After restore, all credentials show 'Unable to decrypt'
Fix
Always include secrets/ directory in backup; for migration, copy master.key separately
×

Using ThinBackup without testing restore

Symptom
When disaster strikes, restore fails due to missing files or permissions
Fix
Regularly test restore in a staging environment; automate verification script
×

Setting cron schedule that overlaps with Jenkins load

Symptom
Backup takes too long and Jenkins becomes slow during peak hours
Fix
Schedule backup during low-activity windows (e.g., 2 AM); use incremental backups
×

Storing backups only on the same server as Jenkins

Symptom
If server dies, backups are lost too
Fix
Sync backups to S3 or another remote location; use lifecycle policies
×

Ignoring backup logs

Symptom
Backup fails silently for weeks
Fix
Monitor backup logs and set up alerts for failures; check backup file size regularly
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does Jenkins encrypt credentials, and what must be backed up to ensu...
Q02SENIOR
What is the difference between ThinBackup full backup and diff backup? H...
Q03SENIOR
You are migrating Jenkins to a new server. What steps do you take to ens...
Q04SENIOR
How would you automate backup verification for Jenkins?
Q05SENIOR
What are the pros and cons of using ThinBackup vs a custom rsync script ...
Q06SENIOR
How do you handle backup retention and cost optimization for S3 backups?
Q07JUNIOR
What happens if you lose the `secrets/master.key` file? How can you reco...
Q08SENIOR
How do you back up Jenkins job configurations selectively?
Q01 of 08SENIOR

How does Jenkins encrypt credentials, and what must be backed up to ensure they are restorable?

ANSWER
Jenkins encrypts credentials using a symmetric key stored in secrets/master.key and secrets/hudson.util.Secret. The encrypted credentials are in credentials.xml. To restore, you must backup the entire secrets/ directory and credentials.xml. Without the master key, decryption fails.
FAQ · 8 QUESTIONS

Frequently Asked Questions

01
What is the ThinBackup plugin?
02
How often should I back up Jenkins?
03
Can I restore a single job from a ThinBackup backup?
04
What files should I exclude from Jenkins backup?
05
How do I migrate Jenkins to a new server?
06
Why are my credentials broken after restore?
07
How do I store Jenkins backups in S3?
08
How do I verify a Jenkins backup is valid?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Written from production experience, not tutorials.

Follow
Verified
production tested
July 09, 2026
last updated
230
articles · all by Naren
🔥

That's Jenkins. Mark it forged?

7 min read · try the examples if you haven't

Previous
Jenkins Supply Chain Security
33 / 39 · Jenkins
Next
Jenkins Kubernetes Integration