36

I want to be able to inspect the contents of a Docker container (read-only). An elegant way of doing this would be to mount the container's contents in a directory. I'm talking about mounting the contents of a container on the host, not about mounting a folder on the host inside a container.

I can see that there are two storage drivers in Docker right now: aufs and btrfs. My own Docker install uses btrfs, and browsing to /var/lib/docker/btrfs/subvolumes shows me one directory per Docker container on the system. This is however an implementation detail of Docker and it feels wrong to mount --bind these directories somewhere else.

Is there a proper way of doing this, or do I need to patch Docker to support these kinds of mounts?

6
  • Why would it be wrong to bind mount these somewhere else? Aug 18, 2014 at 16:17
  • 2
    Because the storage location is an implementation detail. The day docker adds another storage driver, the location will move. I need to make this semi-automatic and it would be nice to use public APIs for that reason.
    – dflemstr
    Aug 18, 2014 at 17:22
  • 2
    It might be worth considering working over nsenter (or docker-enter) to achieve your goals; there is of course the constraint of having to rnu the inspection code/tools inside the container.
    – VladFr
    Sep 7, 2014 at 8:53
  • Is there no way of instructing Linux to mount across a container border?
    – dflemstr
    Sep 7, 2014 at 21:45
  • @dflemstr yes, there is, --volumes-from kinda does that, it appears to mount a union of the directory from the other container's base image and the volume, but this behaviour is not documented afaik Sep 29, 2014 at 3:21

6 Answers 6

20

Take a look at docker export.

To quickly list the files in your container:

docker export CONTAINER|tar -t

To export:

docker export CONTAINER>snapshot.tar
docker export CONTAINER|tar x PATH-IN-CONTAINER

Or to look at a file:

docker export CONTAINER|tar x --to-stdout PATH-IN-CONTAINER
# e.g. 
docker export consul|tar x --to-stdout etc/profile

Docker 1.8 supports cp:

https://docs.docker.com/engine/reference/commandline/cp/

Usage:  docker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH|-
        docker cp [OPTIONS] SRC_PATH|- CONTAINER:DEST_PATH

update: you should ssh to your docker machine when you run this.

6
  • 2
    My images are fairly big (many hundred MiB) so doing this to fetch individual files is too much overhead. It will create the multi-hundred-megabyte file every time.
    – dflemstr
    Aug 3, 2015 at 14:46
  • @dflemstr use the line with tar x PATH-IN-CONTAINER, it will only extract the files you need.
    – laktak
    Aug 3, 2015 at 14:58
  • ...but the entire tar archive is still created in the Docker daemon, and it takes multiple minutes to create...
    – dflemstr
    Aug 3, 2015 at 14:58
  • @dflemstr not sure what your setup is but e.g. docker export ubuntu|tar -t|grep etc/network takes 3 seconds for me.
    – laktak
    Aug 3, 2015 at 15:03
  • You are probably running that on the same machine as the Docker daemon so you don't need to do a network transfer, and the ubuntu image is really small...
    – dflemstr
    Aug 3, 2015 at 15:04
3

You can use docker commit to persist the current state of your container in a new image, and start an interactive container from this image to inspect the contents.

From the documentation :

It can be useful to commit a container’s file changes or settings into a new image. This allows you debug a container by running an interactive shell, or to export a working dataset to another server.

Hope this helps.

2

You can use nsenter to run your inspection program (that probably must be included in the container already) inside a container/namespace. But to mount the container filesystem as is seen inside it you must mount the original image and all the layers if is aufs, or the equivalent action for device mapper, btrfs and the other (future) storage engines used, different in each case. Probably would be more efficient to let docker do the work for you, exactly as is supposed to do, and use nsenter to do the inspection inside the container.

There are other approachs. docker diff will shows what files changed in that container, if you want to see what changed instead of what was in the original image.

And for data that must be persistent and inspectionable, probably a better pattern would be to have it in a volume in the container, and have it either mounted on the real filesystem, or in a pure data container, or in the same container, but that you can launch another container with the inspection program mounting those volumes from it.

2

EDIT: I tried the solution below and unfortunately it did not work well for me in practice. The mounted filesystem did not accurately reflect the container's filesystem (even with cache=no). I'm not sure if this is a fundamental problem or me doing something wrong.

You can install sshd in the docker image and use docker exec to run an ssh service (/usr/sbin/sshd -D) on the docker container (note that the SSH port 22 of the docker container needs to be exposed).

Then, use docker cp to copy your public ssh key to the /root/.ssh/authorized_keys directory of the docker container.

Finally, use docker inspect to find the container's IP address and mount the container's filesystem using

sudo sshfs -o allow_other,default_permissions,IdentityFile=/path/to/identityfile  [email protected]:/ /mnt/my_container

You'd have to write a script to make this work comfortably in practice.

2
  • This looks very promising, should work but I will have to try it. If it does work, this should be marked the answer, based on the OP.
    – Oliver
    Sep 30, 2021 at 9:02
  • @Oliver I also found this tool that allows you to ssh into any running container, without the need to install ssdh on it: github.com/jeroenpeeters/docker-ssh. It's quite old by now, and I don't know if it still works (I guess it does), it worked great.
    – mnieber
    Oct 1, 2021 at 11:27
2

Podman can run and work with Docker images. You could use it to mount a running or stopped container:

prompt:~ # mnt=`podman mount 26e8b85f7a5c`
prompt:~ # ls $mnt
bin  boot  dev  etc  home  lib  ...  tmp  usr  var

where 26e8b85f7a5c is the ID of the container to be mounted.

0

This is an ancient question, but if someone is still looking for a way to mount (and inspect) a docker filesystem from an arbitrary host, there are 2 projects allowing exactly that:

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .