Exploring Docker container's file system

Viewed 976228

I've noticed with docker that I need to understand what's happening inside a container or what files exist in there. One example is downloading images from the docker index - you don't have a clue what the image contains so it's impossible to start the application.

What would be ideal is to be able to ssh into them or equivalent. Is there a tool to do this, or is my conceptualisation of docker wrong in thinking I should be able to do this.

32 Answers

In my case no shell was supported in container except sh. So, this worked like a charm

docker exec -it <container-name> sh

Only for LINUX

The most simple way that I use was using proc dir, the container must be running in order to inspect the docker container files.

  1. Find out the process id (PID) of the container and store it into some variable

    PID=$(docker inspect -f '{{.State.Pid}}' your-container-name-here)

  2. Make sure the container process is running, and use the variable name to get into the container folder

    cd /proc/$PID/root

If you want to get through the dir without finding out the PID number, just use this long command

cd /proc/$(docker inspect -f '{{.State.Pid}}' your-container-name-here)/root

Tips:

After you get inside the container, everything you do will affect the actual process of the container, such as stopping the service or changing the port number.

Hope it helps

Note:

This method only works if the container is still running, otherwise, the directory wouldn't exist anymore if the container has stopped or removed

None of the existing answers address the case of a container that exited (and can't be restarted) and/or doesn't have any shell installed (e.g. distroless ones). This one works as long has you have root access to the Docker host.

For a real manual inspection, find out the layer IDs first:

docker inspect my-container | jq '.[0].GraphDriver.Data'

In the output, you should see something like

"MergedDir": "/var/lib/docker/overlay2/03e8df748fab9526594cfdd0b6cf9f4b5160197e98fe580df0d36f19830308d9/merged"

Navigate into this folder (as root) to find the current visible state of the container filesystem.

This will launch a bash session for the image:

docker run --rm -it --entrypoint=/bin/bash

I wanted to do this, but I was unable to exec into my container as it had stopped and wasn't starting up again due to some error in my code.

What worked for me was to simply copy the contents of the entire container into a new folder like this:

docker cp container_name:/app/ new_dummy_folder

I was then able to explore the contents of this folder as one would do with a normal folder.

If you are using Docker v19.03, you follow the below steps.

# find ID of your running container:

  docker ps

# create image (snapshot) from container filesystem

  docker commit 12345678904b5 mysnapshot

# explore this filesystem 

  docker run -t -i mysnapshot /bin/sh

My preferred way to understand what is going on inside container is:

  1. expose -p 8000

    docker run -it -p 8000:8000 image
    
  2. Start server inside it

    python -m SimpleHTTPServer
    

If you are using the AUFS storage driver, you can use my docker-layer script to find any container's filesystem root (mnt) and readwrite layer :

# docker-layer musing_wiles
rw layer : /var/lib/docker/aufs/diff/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f
mnt      : /var/lib/docker/aufs/mnt/c83338693ff190945b2374dea210974b7213bc0916163cc30e16f6ccf1e4b03f

Edit 2018-03-28 :
docker-layer has been replaced by docker-backup

The docker exec command to run a command in a running container can help in multiple cases.


Usage:  docker exec [OPTIONS] CONTAINER COMMAND [ARG...]

Run a command in a running container

Options:
  -d, --detach               Detached mode: run command in the background
      --detach-keys string   Override the key sequence for detaching a
                             container
  -e, --env list             Set environment variables
  -i, --interactive          Keep STDIN open even if not attached
      --privileged           Give extended privileges to the command
  -t, --tty                  Allocate a pseudo-TTY
  -u, --user string          Username or UID (format:
                             [:])
  -w, --workdir string       Working directory inside the container

For example :

1) Accessing in bash to the running container filesystem :

docker exec -it containerId bash 

2) Accessing in bash to the running container filesystem as root to be able to have required rights :

docker exec -it -u root containerId bash  

This is particularly useful to be able to do some processing as root in a container.

3) Accessing in bash to the running container filesystem with a specific working directory :

docker exec -it -w /var/lib containerId bash 

Often times I only need to explore the docker filesystem because my build won't run, so docker run -it <container_name> bash is impractical. I also do not want to waste time and memory copying filesystems, so docker cp <container_name>:<path> <target_path> is impractical too.

While possibly unorthodox, I recommend re-building with ls as the final command in the Dockerfile:

CMD [ "ls", "-R" ]

I had an unknown container, that was doing some production workload and did not want to run any command.

So, I used docker diff.

This will list all files that the container had changed and therefore good suited to explore the container file system.

To get only a folder you can just use grep:

docker diff <container> | grep /var/log

It will not show files from the docker image. Depending on your use case this can help or not.

I've found the easiest, all-in-one solution to View, Edit, Copy files with a GUI app inside almost any running container.

mc editing files in docker

  1. inside the container install mc and ssh: docker exec -it <container> /bin/bash, then with prompt install mc and ssh packages
  2. in same exec-bash console, run mc
  3. press ESC then 9 then ENTER to open menu and select "Shell link..."
  4. using "Shell link..." open SCP-based filesystem access to any host with ssh server running (including the one running docker) by it's IP address
  5. do your job in graphical UI

this method overcomes all issues with permissions, snap isolation etc., allows to copy directly to any machine and is the most pleasant to use for me

Late to the party, but in 2022 we have VS Code

Practically all containers I use have Python, so I attach to the container,

pip install jupyterlab
cd /
jupyter lab --allow-root

I ^click the link that the Jupyter Lab server offers and in the host's browser I have the perfect GUI for the file system and can open all kinds of files (ipnb, py, md (in preview),...)

Cheers
G.

Related