Quickie: Move docker container to a new machine
Recently I re-organized Prantas’s servers, abandoning the old one-box-to-rule-them-all setup. That meant some Docker containers had to move from machines scheduled for deletion to their new homes. For anyone facing the same headache, here’s the quick(ish) way I did it.
Prerequisites
Before we start, it is presumed that you have
- two servers (the source and the destination) up and running
- docker installed on both machines
- set up the source server to have
sshaccess to the destination server
On the SOURCE server
1. Get the image name
docker inspect my-awesome-container --format 'IMAGE={{.Config.Image}}'
Response:
IMAGE=httpd:latest
2. Get the bound ports
docker inspect my-awesome-container --format 'PORTS={{json .HostConfig.PortBindings}}'
Response:
PORTS={"80/tcp":[{"HostIp":"","HostPort":""}]}
3. Get the enviroment variables
docker inspect my-awesome-container --format 'ENV={{json .Config.Env}}'
Response
TH=/usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","HTTPD_PREFIX=/usr/local/apache2","HTTPD_VERSION=2.4.62","HTTPD_SHA256=674188e7bf44ced82da8db522da946849e22080d73d16c93f7f4df89e25729ec","HTTPD_PATCHES="]
4. Get the volumes
docker inspect my-awesome-container --format '{{range .Mounts}}{{println .Type}} {{println .Source}} {{println .Destination}}{{end}}'
Response:
volume
/var/lib/docker/volumes/258869c20bedb3e8c63950e6d92805fcdbb67f27999fb76168403baa824c3c10/_data
/usr/local/apache2/htdocs
5. Stop the container if running
docker stop my-awesome-container
6. Create a temp image to stream to the destination
docker commit my-awesome-container my-awesome-container-temp
7. Stream the image to the destination
docker save my-awesome-container-temp | ssh 192.168.0.1 'docker load'
Response
Loaded image: my-awesome-container-temp:latest
8. Archive the volumes
Remember the command that returned the volume? For my case the response was:
volume
/var/lib/docker/volumes/258869c20bedb3e8c63950e6d92805fcdbb67f27999fb76168403baa824c3c10/_data
/usr/local/apache2/htdocs
which means that the /var/lib/docker/volumes/258869c20bedb3e8c63950e6d92805fcdbb67f27999fb76168403baa824c3c10/_data path in the host machine (the one the docker runs) is linked as a volume to the /usr/local/apache2/htdocs path in the guest machine (the docker container)
We want to archive this volume, stream it to the destination server and then bind it to the new container created in the destination server.
To do so, run:
docker run --rm -v 258869c20bedb3e8c63950e6d92805fcdbb67f27999fb76168403baa824c3c10:/v \
busybox tar -C /v -czf - . \
> my-awesome-container-data.tar.gz
this command will temporarily create a container named busybox to run the tar that creates the topiki-istoria-data.tar.gz archive
Response
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
80bfbb8a41a2: Pull complete
Digest: sha256:d82f458899c9696cb26a7c02d5568f81c8c8223f8661bb2a7988b269c8b9051e
Status: Downloaded newer image for busybox:latest
9. Copy the archive to destination server
scp my-awesome-container-data.tar.gz pandor1an@10.0.0.4:/home/pandor1an
Response
my-awesome-container-data.tar.gz 100% 195 126.5KB/s 00:00
On the Destination Server
10. Create a new volume
I am going to give it a sane name instead of the hash
docker volume create my-awesome-container-data
11. Extract the backup into the new volume
cat /home/pandor1an/my-awesome-container-data.tar.gz | docker run --rm -i -v my-awesome-container-data:/v busybox tar -C /v -xzf -
Response
Unable to find image 'busybox:latest' locally
latest: Pulling from library/busybox
80bfbb8a41a2: Pull complete
Digest: sha256:d82f458899c9696cb26a7c02d5568f81c8c8223f8661bb2a7988b269c8b9051e
Status: Downloaded newer image for busybox:latest
12. Run the container
docker run -d --name my-awesome-container \
-p 1080:80 \
-v my-awesome-container:/usr/local/apache2/htdocs \
my-awesome-container-temp
Mission accomplished!
