Migrating Jenkins Containers
Jenkins Installation Overview
Jenkins was installed on a docker host, provided with two docker volumes for data, a discrete network, exposed network ports, and a custom image. It can be started by running the following command:
sudo docker run --name jenkins-blueocean-jdk21 --restart=on-failure --detach --network jenkins --env DOCKER_HOST=tcp://docker:2376 --env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 --publish 8080:8080 --publish 50000:50000 --dns 10.20.1.1 --volume jenkins-data:/var/jenkins_home --volume jenkins-docker-certs:/certs/client:ro myjenkins-blueocean:21-latest
Above command was created following the official Jenkins Guide here. That was great, until the docker host became severely corrupted, and I needed to migrate to a new host.
Jenkins Persistent Data
Persistent data on the Jenkins container is handled by two docker volumes:
- jenkins-data
- jenkins-docker-certs
Technically, these data volumes exist on the docker host through little obfuscation, and can be foound by running the docker volume [volume-name] inspect command:
[
{
"CreatedAt": "2025-05-03T00:58:23Z",
"Driver": "local",
"Labels": null,
"Mountpoint": "/var/lib/docker/volumes/jenkins-data/_data",
"Name": "jenkins-data",
"Options": null,
"Scope": "local"
}
]Jenkins BlueOcean Image
Jenkins Docker installation guide listed earlier is all you need, but I recommend using the latest image instead of a blind copy-paste. Or at the very minimum, make sure the version you use is equal to the version you were on:
FROM jenkins/jenkins:latest-jdk21
USER root
RUN apt-get update && apt-get install -y lsb-release
RUN curl -fsSLo /usr/share/keyrings/docker-archive-keyring.asc \
https://download.docker.com/linux/debian/gpg
RUN echo "deb [arch=$(dpkg --print-architecture) \
signed-by=/usr/share/keyrings/docker-archive-keyring.asc] \
https://download.docker.com/linux/debian \
$(lsb_release -cs) stable" > /etc/apt/sources.list.d/docker.list
RUN apt-get update && apt-get install -y docker-ce-cli
USER jenkins
RUN jenkins-plugin-cli --plugins "blueocean docker-workflow"Recreate this Docker file on the target host to help you rebuild your image:
sudo docker image build -t myjenkins-blueocean:21-latest .
Migration Plan
Step by step plan to migrate the Docker volumes from one host to another.
- Backup Jenkins persistent data volumes
- Create a temporary directory on the docker host:
sudo mkdir /backup - Creat tarball of data from
jenkins-data:sudo docker run --rm --mount type=bind,src=/backup,dst=/backup --volume jenkins-data:/jenk-backup busybox tar --create --verbose --file /backup/jenkins-data-backup.tar --numeric-owner /jenk-backup - Creat tarball of data from
jenkins-docker-certs:sudo docker run --rm --mount type=bind,src=/backup,dst=/backup --volume jenkins-docker-certs:/jenk-backup busybox tar --create --verbose --file /backup/jenkins-docker-certs-backup.tar --numeric-owner /jenk-backup
- Create a temporary directory on the docker host:
- Copy data backups from one docker host to another using
scp- Create a temporary directory on the docker host:
sudo mkdir /backup - Copy backups to temporary directory
- Recreate
jenkins-datavolume:sudo docker volume create jenkins-data - Recreate
jenkins-docker-certsvolume:sudo docker volume create jenkins-docker-certs
- Create a temporary directory on the docker host:
- Restore tarball backups to the volumes
- Restore the tarball of data from the
jenkins-data:sudo docker run --rm --mount type=bind,src=/backup,dst=/backup --volume jenkins-data:/jenk-backup busybox tar xvf /backup/jenkins-data-backup.tar -C / - Restore the tarball of data from the
jenkins-docker-certs:sudo docker run --rm --mount type=bind,src=/backup,dst=/backup --volume jenkins-docker-certs:/jenk-backup busybox tar xvf /backup/jenkins-docker-certs-backup.tar -C / - Create Docker image on target host:
sudo docker image build -t myjenkins-blueocean:21-latest .
- Restore the tarball of data from the
- Create the jenkins bridge network:
sudo docker network create jenkins - Start the jenkins host on the new node:
sudo docker run --name jenkins-blueocean-jdk21 --restart=on-failure --detach --network jenkins --env DOCKER_HOST=tcp://docker:2376 --env DOCKER_CERT_PATH=/certs/client --env DOCKER_TLS_VERIFY=1 --publish 8080:8080 --publish 50000:50000 --dns 10.20.1.1 --volume jenkins-data:/var/jenkins_home --volume jenkins-docker-certs:/certs/client:ro myjenkins-blueocean:21-latest - Update the Jenkins IP Address within System -> Jenkins Location -> Jenkins URL.
Lessons Learned
- The permissions for files on the data volumes matter. By default, tar will not preserve these during compression, or will replace them with the user executing the extract commands.
- Jenkins installation guide will have you version lock by default. This will hurt you when you go to deploy a new controller and you've accidentally downgraded yourself and your plugins fail.
- Jenkins will still function without the correct URL configured in System, but will be very slow until you do.
- Ensure any agents have their IP Addresses updated.