Duplicating docker container for debugging
currently broken again
below only works with version from around Dec 20 '17. I have not yet looked into this after Jan 18.
docker commit
is fine for saving file changes into a new image, but it will not preserve changes in memory, open processes etc. Contrary to the popular opinion, the latter is feasible with docker checkpoint
. Documentation and example.
Note: right now, the --checkpoint-dir
option is broken: issue, pull. That is why a workaround like checkpoint_dir
(see code) is necessary here. This answer should probably be updated in a few weeks.
It is not possible to checkpoint a TTY. This might change soon. However, you can attach a new TTY after the restoring process using exec.
You need to have criu installed. After, first,
echo "{\"experimental\": true}" >> /etc/docker/daemon.json
systemctl restart docker
, then
#!/bin/bash
# tty (-t) not supported
docker run -i -d --name sleeper\
busybox sh -c 'sleep 10000'
# Makes a snapshot and stops the container (except if --leave-running is active). --checkpoint-dir is broken.
docker checkpoint create sleeper cp
# sleeper container exited
# Create the clone
docker create -i --rm --name clone\
busybox
# Start the clone
checkpoint_dir="/var/lib/docker/containers/$(docker ps -aq --no-trunc -f name=sleeper)/checkpoints"
docker start --checkpoint-dir=$checkpoint_dir --checkpoint=cp clone
# Attach new TTY
docker exec -it clone sh
Now in the tty, type ps -e
and you will see the process which started in the sleeper
container and now continues in the clone
.
checkpoint
makes a complete blueprint of the container to hard drive, exchangable between machines. This feature uses criu and is experimental. Criu cannot create a blueprint of X11 applications natively.
pause
on the other hand only freezes the container internally. There is nothing you can do with a paused container other than unpause it.
Create a base image and run it
docker run -it <base_image> /bin/bash
Make necessary changes
yum install ping
Commit it with a new name
docker commit <hash tag of running container> new_image
Now if you open new_image by running
docker run -it new_image /bin/bash
You can see ping
is installed in it.
Open base_image and there is no ping
installed in it.
Hope it answered your question.
If you want to save your modifications, you can use docker commit
, see the doc http://docs.docker.com/reference/commandline/cli/#commit and you can also save a container, http://docs.docker.com/reference/commandline/cli/#save