How to move Docker containers between different hosts?
Asked Answered
G

8

160

I cannot find a way of moving docker running containers from one host to another.

Is there any way I can push my containers to repositories like we do for images ? Currently, I am not using data volumes to store the data associated with applications running inside containers. So some data resides inside containers, which I want to persist before redesigning the setup.

Gdynia answered 26/2, 2015 at 3:43 Comment(4)
Have a look at flocker github.com/ClusterHQ/flockerJacklighter
Note that you may wish to use save/load instead of export/import, as save preserves metadata and history.Clarindaclarine
Should this be a comment to @aholt's answer?Stile
docker save is for saving images, not containers. docs.docker.com/engine/reference/commandline/saveResumption
N
95

You cannot move a running docker container from one host to another.

You can commit the changes in your container to an image with docker commit, move the image onto a new host, and then start a new container with docker run. This will preserve any data that your application has created inside the container.

NB: It does not preserve data that is stored inside volumes; you need to move data volumes manually to new host.

Nephology answered 26/2, 2015 at 3:50 Comment(6)
docker-checkpoint could let you move a "running" container between hosts, if they both support CRIU.Rafael
@DaveJarvis if you want to make that extensive of an edit I would suggest simply posting a new answer.Nephology
I moved Lau's helpful comment into a more visible location. I thought the idea of a wiki was that anyone could edit an answer to improve it?Confine
This isn't a wiki, and when you make major changes to someone else's answer you're putting words into their mouth. Editing a question to make minor correction is just fine, but if you need to add substantial new information it's generally better to just post a new answer (and consider adding a comment on the accepted answer pointing at the additional information).Nephology
So, "Here's an answer, with no steps on how to accomplish it, and a vague warning that there's something else you may need to do, also with no steps on how to do that."Apul
@JohnSmith I'm glad this almost-10-year-old answer was moving enough to inspire a comment!Nephology
F
136

Alternatively, if you do not wish to push to a repository:

  1. Export the container to a tarball

    docker export <CONTAINER ID> > /home/export.tar
    
  2. Move your tarball to new machine

  3. Import it back

    cat /home/export.tar | docker import - some-name:latest
    
Fireplace answered 26/2, 2015 at 20:7 Comment(4)
Also does not preserve data that is stored inside volumes.Resumption
How is this supposed to work? After the import I get new image, and then what? Just do a new run command?Zigzag
This is actually a really bad suggestion, especially for containers running database. I tried this suggestion and it didn't work. Could it maybe work with stopping container first?Zigzag
This suggestion was only really meant for an alternative. It might work for your situation, it might not. For me, I was setting up database replication docker containers at the time, and for the export/import, did not care about preserving the data, as I was running backups of the database data regularly out to a different tarball. For that, this worked perfectly.Fireplace
N
95

You cannot move a running docker container from one host to another.

You can commit the changes in your container to an image with docker commit, move the image onto a new host, and then start a new container with docker run. This will preserve any data that your application has created inside the container.

NB: It does not preserve data that is stored inside volumes; you need to move data volumes manually to new host.

Nephology answered 26/2, 2015 at 3:50 Comment(6)
docker-checkpoint could let you move a "running" container between hosts, if they both support CRIU.Rafael
@DaveJarvis if you want to make that extensive of an edit I would suggest simply posting a new answer.Nephology
I moved Lau's helpful comment into a more visible location. I thought the idea of a wiki was that anyone could edit an answer to improve it?Confine
This isn't a wiki, and when you make major changes to someone else's answer you're putting words into their mouth. Editing a question to make minor correction is just fine, but if you need to add substantial new information it's generally better to just post a new answer (and consider adding a comment on the accepted answer pointing at the additional information).Nephology
So, "Here's an answer, with no steps on how to accomplish it, and a vague warning that there's something else you may need to do, also with no steps on how to do that."Apul
@JohnSmith I'm glad this almost-10-year-old answer was moving enough to inspire a comment!Nephology
U
69

What eventually worked for me, after lot's of confusing manuals and confusing tutorials, since Docker is obviously at time of my writing at peak of inflated expectations, is:

  1. Save the docker image into archive:
    docker save image_name > image_name.tar
  2. copy on another machine
  3. on that other docker machine, run docker load in a following way:
    cat image_name.tar | docker load

Export and import, as proposed in another answers does not export ports and variables, which might be required for your container to run. And you might end up with stuff like "No command specified" etc... When you try to load it on another machine.

So, difference between save and export is that save command saves whole image with history and metadata, while export command exports only files structure (without history or metadata).

Needless to say is that, if you already have those ports taken on the docker hyper-visor you are doing import, by some other docker container, you will end-up in conflict, and you will have to reconfigure exposed ports.

Note: In order to move data with docker, you might be having persistent storage somewhere, which should also be moved alongside with containers.

Update 10/2023
Another very good way to migrate docker containers You can actually follow this upgrade script, but modified for moving instead of upgrading. You will also need docker compose on target machine.

  1. Use autocompose.py from https://github.com/Red5d/docker-autocompose/ you can use it as docker container also
    cd ~
    mkdir ~/dockercontainers
    sudo docker container list -a > ~/dockercontainers/containers.txt
    cat  ~/dockercontainers/containers.txt
    
    CIDS=$(docker container list -a | sed '1d' | awk '{print $1}')
    for c in $CIDS; do mkdir ~/dockercontainers/$c ; docker run --rm -v /var/run/docker.sock:/var/run/docker.sock ghcr.io/red5d/docker-autocompose $c > ~/dockercontainers/$c/docker-compose.yml ; done 
  1. Inspect composer files and move volume folders with data on new machine

  2. Export Images and tags as txt files Images: mkdir dockersave && docker images > dockersave/images.txt tags: cat dockersave/images.txt | sed '1d' | awk '{ print "docker tag "$3" "$1":"$2 }'>> tags.txt

  3. Perform actual Images export (you can commit them before this step if required) IDS=$(docker images | sed '1d' | awk '{print $3}') for c in $IDS; do docker save -o dockersave/$c.tar $c; done

  4. Copy everything from dockersave and dockercontainers to target machine.

  5. Load images onto new docker: cd dockersave/ IDS=$(ls *.tar) for c in $IDS; do docker load -i $c; done

  6. Restore containers CIDS=$(cat ~/dockercontainers/containers.txt | sed '1d' | awk '{print $1}'); for c in $CIDS; do cd ~/dockercontainers/$c ; docker-compose up -d --no-deps --build ; done

If everything is fine, you will get bunch of OK messages and docker ps will display all of your containers.

Underpay answered 11/5, 2018 at 22:17 Comment(8)
Hugely helpful. The "No command specified" message was driving me crazy.Mimesis
The "No command specified" message was driving me crazy too. I use docker commit <container-id> stackstorm-local:2.9, and docker pull stackstorm-local:2.9 from another host.Lamellicorn
same here, you just saved my container and my time !Molton
It should be noted that before doing the docker save and docker load, one should commit the container to the image sudo docker commit <container_id> image_nameJostle
No, no, no. All the save/load procedure above did was create an unusably broken container on the destination machine. It loads, starts, runs, all without any errors, and then, when you try to use it, it's like it's not even there, it just plain doesn't work at all, it's like it's not running. It works 100% as expected on the machine saved from, and not at all on the destination.Apul
What did work, though, was zipping the /var/lib/docker folder into an archive, copying, expanding it on the destination machine. Boom, done, everything works. Why people give all sorts of nonworking hoops to jump through and never mention this simple working solution, I have no idea.Apul
@JohnSmith I guess that your solution works if there are no containers on target host already running...Beating
This never uses the created tags.txt, resulting in refetching of the imagesLuddite
G
33

Use this script: https://github.com/ricardobranco777/docker-volumes.sh

This does preserve data in volumes.

Example usage:

# Stop the container   
docker stop $CONTAINER

# Create a new image   
docker commit $CONTAINER $CONTAINER

# Save image
docker save -o $CONTAINER.tar $CONTAINER

# Save the volumes (use ".tar.gz" if you want compression)
docker-volumes.sh $CONTAINER save $CONTAINER-volumes.tar

# Copy image and volumes to another host
scp $CONTAINER.tar $CONTAINER-volumes.tar $USER@$HOST:

# On the other host:
docker load -i $CONTAINER.tar
docker create --name $CONTAINER [<PREVIOUS CONTAINER OPTIONS>] $CONTAINER

# Load the volumes
docker-volumes.sh $CONTAINER load $CONTAINER-volumes.tar

# Start container
docker start $CONTAINER
Guanabara answered 30/10, 2018 at 15:52 Comment(7)
Didn't work for me on AWS Linux (Centos). In the endi I took the low tech approach of using docker inspect to find the volume dir, then manually copying that over.Enzymology
@Enzymology Maybe something related to SELinux? Do you have SELinux enabled?Guanabara
Got this: tar: Removing leading `/' from member namesArriola
@Arriola That's a typical tar message. Not an error and not an even a warning.Guanabara
This worked very well, however I would recommend renaming the $CONTAINER to different names for the example. This is because the $CONTAINER name may not be the same as the actual CONTAINER image name. Also as a side note, You dont need to use docker start or docker create if using docker-compose. You can just use docker-compose up with the same config from the original system, then continue with the instructions.Thanasi
Is this works on Raspberrypi os?Penton
What is "<previous container options>"? Is there some way to find this out? I can't remember exactly how I created the container, it was years ago.Apul
H
20

From Docker documentation:

docker export does not export the contents of volumes associated with the container. If a volume is mounted on top of an existing directory in the container, docker export will export the contents of the underlying directory, not the contents of the volume. Refer to Backup, restore, or migrate data volumes in the user guide for examples on exporting data in a volume.

Hugibert answered 8/8, 2015 at 10:52 Comment(1)
cluster hq shutdown... and BTW to migrate container the container should run on ZFS / any supported storage lunHygienic
M
3

I tried many solutions for this, and this is the one that worked for me :

1.commit/save container to new image :

  1. ++ commit the container:
    # docker stop
    # docker commit CONTAINER_NAME
    # docker save --output IMAGE_NAME.tar IMAGE_NAME:TAG


ps:"Our container CONTAINER_NAME has a mounted volume at '/var/home'" ( you have to inspect your container to specify its volume path : # docker inspect CONTAINER_NAME )

  1. ++ save its volume : we will use an ubuntu image to do the thing.
    # mkdir backup
    # docker run --rm --volumes-from CONTAINER_NAME -v ${pwd}/backup:/backup ubuntu bash -c “cd /var/home && tar cvf /backup/volume_backup.tar .”

Now when you look at ${pwd}/backup , you will find our volume under tar format.
Until now, we have our conatainer's image 'IMAGE_NAME.tar' and its volume 'volume_backup.tar'.

Now you can , recreate the same old container on a new host.

Maggs answered 17/7, 2019 at 17:1 Comment(0)
G
-1

docker export | gzip > .tar.gz

#new host gunzip < /mnt/usb/.tar.gz | docker import -

docker run -i -p 80:80 /bin/bash

Greenaway answered 22/3, 2021 at 1:3 Comment(0)
S
-1

if you are using docker desktop you can use this extension

or you can see this link and describe How does it work behind the scenes? and do it by your self.

Spital answered 18/4, 2023 at 14:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.