0

I created a tar file of my container using the following method.

On the first or source Docker host:

docker commit -p  78727078a04b  jenkins
docker save -o ~/jenkins.tar jenkins

Then on the new Docker host (it's a different machine)

docker load -i ~/jenkins.tar
docker run -p 8080:8080 -p 50000:50000 jenkins

However, I got this error

docker: Error response from daemon: cannot mount volume over existing file, file exists /var/lib/docker/overlay2/e668ec2b2a563f692e4511352a0db2989791281cc8d13f04f36f02106ceebb0c/merged/run/docker.sock.
halfer
  • 19,824
  • 17
  • 99
  • 186
devwannabe
  • 3,160
  • 8
  • 42
  • 79

2 Answers2

3

Usual practice is to not try to "move" or "save" or "export" or "commit" containers. Just create a new container on the new machine.

For this to work you need to store all of the critical data your container needs outside the container. The Jenkins image documentation discusses this. It has a strong recommendation for using named volumes, which are harder to manage in several ways; the Docker documentation on backing up named volumes is relevant to this.

I'll assume you've created a named volume to hold the content. If you haven't, the Jenkins Dockerfile declares a VOLUME so there should be an anonymous volume holding the Jenkins home directory. I'd look for its volume ID using docker volume ls or docker inspect and try using that.

# when you initially started Jenkins; copied from
# https://github.com/jenkinsci/docker/blob/master/README.md
docker run \
  -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts

You need to export the data from the volume. (docker stop Jenkins might be a good idea first.) You can use a temporary container to do this:

docker run \
  --rm \
  -v jenkins_home:/jenkins_home \
  -v $PWD:/export \
  -w /jenkins_home \
  busybox \
  tar cf /export/jenkins_home.tar .
gzip jenkins_home.tar
scp jenkins_home.tar.gz elsewhere:

Now you've gotten the data the container needs on to the remote host. You need to recreate the data volume:

ssh elsewhere
gunzip jenkins_home.tar.gz
docker run \
  --rm \
  -v jenkins_home:/jenkins_home \
  -v $PWD:/import \
  -w /jenkins_home \
  busybox \
  tar xf /import/jenkins_home.tar .

Now the remote host has a volume named jenkins_home that has a copy of the exported data, and you can run the same Jenkins command you initially ran

ssh elsewhere
docker run \
  -p 8080:8080 -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts

This approach keeps the application and its data separate. Since you're still using an unmodified upstream image, if there's ever a security issue and you need to upgrade Jenkins, you can docker pull jenkins/jenkins:lts to get a newer version and restart the container.

docker commit is almost never a best practice. Say you do need to update Jenkins; if you committed an image as in the question, you need to remember exactly what you did to create the image and repeat it, but the nature of a committed image is that there's no record of this. If a custom image is useful for your application, write a Dockerfile for it and commit it to source control. Also note that docker commit doesn't include volume content and the actual data you want to preserve is always in a volume (possibly anonymous) so the approach you're proposing in the question won't bring across the data you need anyways.

David Maze
  • 130,717
  • 29
  • 175
  • 215
  • OK, I will try this today. Thank you. – devwannabe Feb 13 '20 at 14:10
  • Question. Why do I have to create a container to extract the tar file if I can extract it manually? One thing I see why we want to do that is preserve ownership and not use the local account where I'll be running `tar xf ....` – devwannabe Feb 13 '20 at 17:01
  • I got it working. I used --volumes-from {container} to create a tar backup then also used --volumes-from on the new container on the other docker_host to extract it. Then I followed your jenkins:lts – devwannabe Feb 13 '20 at 17:53
  • You can’t directly read or write to or from a named volume from the host, so you need to unpack the tar file inside a container on the target system to get its contents into a named volume there. – David Maze Feb 13 '20 at 17:57
  • I was able to extract my backup.tar from the host machine. It's a regular tar file. However, I deleted it again and extracted it within the container. – devwannabe Feb 13 '20 at 21:18
0

you are missing to provide volume which docker image expect here, start this with a mounting volume -v on expected location in the container.

not exact but for reference: Docker - cannot mount volume over existing file, file exists

anand
  • 741
  • 5
  • 11
  • This is how I remember I created the container last year - https://hub.docker.com/_/jenkins/ specifically the command I executed before was `docker run -p 8080:8080 -p 50000:50000 jenkins`. I didn't specify any volume back then. – devwannabe Feb 13 '20 at 08:42
  • I just tried this command, I still got the same error message: `docker run -p 8080:8080 -p 50000:50000 -v $home:/var/jenkins_home jenkins` – devwannabe Feb 13 '20 at 08:45
  • I still believe there is issue with your volume mounting, what is in $home, is there anything you have set as variable? – anand Feb 13 '20 at 10:31
  • I meant $HOME and not $home since I just typed my previous response and copy+pasted the command. I'll redo it using the above instructions given by David Maze. – devwannabe Feb 13 '20 at 14:10