38

I have a running docker container. I have done some useful works in the running docker container. I have done these works not part of dockerfile, i have done it inside the container.[Eg: I have installed ping inside the container, not from docker file]

Now, i got stuck at a place. I am not sure if i debug in the same container, i may loose the thing that i have done so far inside that container.

So i would like to create a duplicate copy of it with all the things available in that running container[like i don't want to build a container from image and repeat all the suucessful steps achieved in the running container and then start my debuggging. I don't want to re-install ping in my second container].

Totally, How can i duplicate a container? If not what are all the possibilities?

Gibbs
  • 21,904
  • 13
  • 74
  • 138

5 Answers5

58
  1. Create a base image and run it

    docker run -it <base_image> /bin/bash
    
  2. Make necessary changes

    yum install ping
    
  3. 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.

Ryan Foley
  • 115
  • 2
  • 5
Pratik
  • 1,216
  • 11
  • 18
  • 3
    Just to clarify a bit: the relevant command here is `docker commit`; the rest is there to recreate the situation the OP ended up in. – Joost Jan 30 '17 at 11:05
  • 2
    As I see, this doesn't clone data from origin container to new one – vladkras Apr 11 '18 at 17:45
3

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

user2915097
  • 30,758
  • 6
  • 57
  • 59
  • ok Fine. If i do a commit or save and then i do my debugging, can i revert back to my saved state. Shouldn't i use pull again since it is committed. – Gibbs Feb 12 '15 at 07:43
  • If you commit, you will tag it with another name, and of course you can go back to the saved statse (that is what commit is designed for). You will have another image, so you will have to pull it if you want to use it. Pull can be almost instant if you have a cache or a local registry. – user2915097 Feb 12 '15 at 08:04
  • Let me check this. I 'll tel you – Gibbs Feb 12 '15 at 08:05
2

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.

Community
  • 1
  • 1
phil294
  • 10,038
  • 8
  • 65
  • 98
1

As of docker implementation 1.0.1 (Server /client API 1.12), there is only support for pause/resume operations.

But as far as snapshotting of processes (in commits + push) are concerned, these don't work (not supported, though I've not checked documentation)

In summary, 1) Preserving state of running processes is not possible! 2) All changes being made to file system (persistent storage) can be saved (and can be committed + pushed to repository).

khelender
  • 61
  • 6
0

If you have a container my-cont and you want to debug it, there is no need to install debugging tools inside it. What you can do instead is to use another container from a debug image e.g. xyz_docker_img then let it shares the same namespaces with my-cont container with extra capabilities you need for debugging.

$ docker run -it \
                --pid=container:my-cont 
                --net:container:my-cont
                --cap-add NET_RAW 
                --cap-add NET_ADMIN 
                --cap-add SYS_PTRACE
                xyz_docker_image bash
alshaboti
  • 643
  • 8
  • 18