Can't run docker as a normal user - linux

I can't run docker commands as my own user. But I know that the service is running because I can run commands as sudo:
$ docker ps
Cannot connect to the Docker daemon at unix:///run/user/1000/docker.sock. Is the docker daemon running?
$ sudo docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
(snip) (snip) (snip) 13 days ago Up 2 hours (healthy) 9000/tcp (snip)
I am successfully running a few containers, and they each work, but I have another not listed in 👆 that I need to run as my own user.
I am part of the docker group:
$ groups
docker www-data video tim
I'm not sure what else to check. I do have this:
$ echo $DOCKER_HOST
unix:///run/user/1000/docker.sock
Also:
$ uname -r
5.4.0-65-generic
$ docker --version
Docker version 19.03.6, build 369ce74a3c
This is on Ubuntu 18.04.5 LTS

As you followed all the post installation steps correctlly, as far as I can tell, my best guess is that has to do with the DOCKER_HOST environment variable.
Does it help if you unset DOCKER_HOST? (Perhaps you need to log out, so it has an effect.)
On my system, docker ps works with sudo, but once I set DOCKER_HOST=unix:///run/user/1000/docker.sock, I get the same error as you.
For some background, here is a question about the DOCKER_HOST variable. In essence, that variable should normally not be set.

Return to the default sock path (unix:///var/run/docker.sock), by unsetting DOCKER_HOST and removing an errant config files:
unset DOCKER_HOST
rm -r ~/.docker
The Docker Daemon must be restarted after creating the “docker” group:
sudo services docker restart
Then, ensure you add your current user to the group:
sudo usermod -a -G docker $USER
This will ensure your user has access to the socket file.
UPDATE: 12/2022
Recently had to do this on Ubuntu 22.04 LTS and ran into the login shell persisting the previous group.
Since the UI manages the login shell, a restart is either required, or you need to replace the process with exec. You can work around this issue, until you restart, by replacing your current shell process: (use $0 instead, if $SHELL doesn't match your preferred shell)
exec sudo -u $USER -E $SHELL

Related

How to Find The User Who Stopped Docker Container

I want to know what is the user who stopped a docker container.
There are several user accounts on my server. I suspect that one of them sometimes stops the container.
How can I find the user that performed this operation?
You can use su -c history username to check command history of a user, I don't know how many users you have but you could loop through them and grep for commands taking docker containers down.
You can install GNU Accounting Utilities, to be able to see commands executed by users:
#centos
yum install psacct
# ubuntu:
apt-get install acct
#Also make sure that the cooresponding service is enabled:
/etc/init.d/psacct status
Then, after you realize that the container is stopped execute:
lastcomm --command docker
# or
lastcomm --command kill
to see which executed the above command(s).
You can use the above in combination with:
docker container logs <name-of-the-container>
to see what is the exact time on which the container was stopped. (E.g. you may see a message on the logs: "stopping service..") and match it with lastcomm output.
Other useful commands that come with the above package:sa, ac

default user not added to docker group, have to do su $USER?

I have Ubuntu 18.04. and after installing docker i added my user to docker group with the command
sudo usermod -aG docker ${USER}
and logged in
su - ${USER}
and if I check id, my user is added to docker group.
But when I reopen the terminal i cant do docker commands without sudo unless i explicitly do su ${USER}
also, I can't find docker group with the default user.
What am I missing here?
#larsks already replied to the main question in a comment, however I would like to elaborate on the implications of that change (adding your default user to the docker group).
Basically, the Docker daemon socket is owned by root:docker, so in order to use the Docker CLI commands, you need either to be in the docker group, or to prepend all docker commands by sudo.
As indicated in the documentation of Docker, it is risky to follow the first solution on your personal workstation, because this just amounts to providing the default user with root permissions without sudo-like password prompt protection. Indeed, users in the docker group are de facto root on the host. See for example this article and that one.
Instead, you may want to follow the second solution, which can be somewhat simplified by adding to your ~/.bashrc file an alias such as:
alias docker="sudo /usr/bin/docker"
Thus, docker run --rm -it debian will be automatically expanded to sudo /usr/bin/docker run --rm -it debian, thereby preserving sudo’s protection for your default user.

Docker command can't connect to Docker daemon

I want to make a move to Docker, so I've just started to mess around with it. I've installed Docker on a VirtualBox Ubuntu 15.10 (Wily Werewolf) installation and as suggested here I then tried running a basic nginx Docker image:
$ docker run --name mynginx1 -P -d nginx
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
So I checked out whether Docker was running:
$ sudo service docker status
â—Ź docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since vr 2015-11-06 08:41:48 CET; 15min ago
Docs: https://docs.docker.com
Main PID: 7542 (docker)
CGroup: /system.slice/docker.service
└─7542 /usr/bin/docker daemon -H fd://
nov 06 08:41:47 kramer65-VirtualBox systemd[1]: Starting Docker Application Container Engine...
nov 06 08:41:47 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:47.900410966+01:00" level=info msg="API ...ock"
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.033514149+01:00" level=info msg="Fire...lse"
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.141594321+01:00" level=info msg="Defa...ess"
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.416294436+01:00" level=warning msg="Y...it."
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.565507576+01:00" level=info msg="Load...rt."
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.567907022+01:00" level=info msg="Load...ne."
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.567945214+01:00" level=info msg="Daem...ion"
nov 06 08:41:48 kramer65-VirtualBox docker[7542]: time="2015-11-06T08:41:48.567969891+01:00" level=info msg="Dock....9.0
nov 06 08:41:48 kramer65-VirtualBox systemd[1]: Started Docker Application Container Engine.
Hint: Some lines were ellipsized, use -l to show in full.
This suggests that the Docker daemon is actually already running, but to be sure I just started the Docker daemon manually:
$ sudo docker daemon
INFO[0000] API listen on /var/run/docker.sock
INFO[0000] [graphdriver] using prior storage driver "aufs"
INFO[0000] Firewalld running: false
INFO[0000] Default bridge (docker0) is assigned with an IP address XXX.XX.X.X/XX. Daemon option --bip can be used to set a preferred IP address
WARN[0000] Your kernel does not support swap memory limit.
INFO[0000] Loading containers: start.
INFO[0000] Loading containers: done.
INFO[0000] Daemon has completed initialization
INFO[0000] Docker daemon commit=76d6bc9 execdriver=native-0.2 graphdriver=aufs version=1.9.0
I then tried running the image again, but with the same result:
$ docker run --name mynginx1 -P -d nginx
Cannot connect to the Docker daemon. Is the docker daemon running on this host?
I tried sudo'ing the command, but to no avail. What am I doing wrong here?
You need to add your current user to the docker group as follows:
sudo usermod -aG docker $(whoami)
then logout & login again into the system or restart the system.
test by docker version
for further info how to install docker-engine follow docker documentation
Add the user to the docker group
Add the docker group if it doesn't already exist:
sudo groupadd docker
Add the connected user "${USER}" to the docker group:
sudo gpasswd -a ${USER} docker
Restart the Docker daemon:
sudo service docker restart
Either do a newgrp docker or log out/in to activate the changes to
groups.
Usually, the following command does the trick:
sudo service docker restart
This, instead of docker start for the cases where Docker seems to already be running.
If that works then, as suggested and in another answer and on this GitHub issue, if you haven't added yourself in the docker group do it by running:
sudo usermod -aG docker <your-username>
And you're most likely good to go.
As for anybody else bumping into this, in some OS's docker doesn't start right after you install it and, as a result, the same can't connect to daemon message appears. In this case you can first verify that Docker is indeed not running by checking the status of your docker service by executing:
sudo service docker status
If the output looks something like: docker stop/waiting instead of docker start/running, process 15378 then it obviously means Docker is not active. In this case make sure you start it with:
sudo service docker start
And, as before, you'll most likely be good to go.
note to self: I get the error from the question's title when I forget to run docker command with sudo:
sudo docker run ...
[Ubuntu 15.10]
Had the same issue and what worked for me was:
Checking the ownership of /var/run/docker.sock
ls -l /var/run/docker.sock
If you're not the owner then change ownership with the command
sudo chown *your-username* /var/run/docker.sock
Then you can go ahead and try executing the docker commands hassle-free :D
After installing docker on Ubuntu, I ran the following command:
sudo service docker start
Have you tried it?
After install everything and start the service, try close your terminal and open it again, then try pull your image
Edit
I also had this issue again, if the solution above won't worked, try this solution that is the command bellow
sudo mv /var/lib/docker/network/files/ /tmp/dn-bak
Considerations
If command above works you probably are with network docker problems, anyway this resolves it, to confirm that, see the log with the command bellow
tail -5f /var/log/upstart/docker.log
If the output have something like that
FATA[0000] Error starting daemon: Error initializing network controller: could not delete the default bridge network: network bridge has active endpoints
/var/run/docker.sock is up
You really are with network problems, however I do not know yet if the next time you restart(update, 2 months no issue again) your OS will get this problem again and if it is a bug or installation problem
My docker version
Client:
Version: 1.9.1
API version: 1.21
Go version: go1.4.2
Git commit: a34a1d5
Built: Fri Nov 20 13:12:04 UTC 2015
OS/Arch: linux/amd64
Server:
Version: 1.9.1
API version: 1.21
Go version: go1.4.2
Git commit: a34a1d5
Built: Fri Nov 20 13:12:04 UTC 2015
OS/Arch: linux/amd64
I had the same problem. Been struggling for two days to solve it.
It only worked when I did:
According to Docker's Tutorial, you need to add the Docker key if not already added using:
$ sudo wget -qO- https://get.docker.com/gpg | sudo apt-key add -
Then make sure you grant docker privileges to yourself using:
$ sudo usermod -aG docker $USER
Hope this helps you too.
enter as root (sudo su) and try this:
unset DOCKER_HOST
docker run --name mynginx1 -P -d nginx
I've the same problem here, and the docker command only worked running as root, and also with this DOCKER_HOST empty
PS: also beware that the correct and official way to install on Ubuntu is to use their apt repositories (even on 15.10), not with that "wget" thing.
For OSX:
After opening docker and starting the 'default' machine via the Quickstart Terminal (https://docs.docker.com/engine/installation/mac/), you try docker commands and get this "can't connect to docker daemon" message, it turns out you need some env variables set:
eval "$(docker-machine env default)"
Then try it out with docker run hello-world to see if everything is peachy.
For the ones who already tried restarting your machine, unsetting the environment variable DOCKER_HOST as told in the docker env documentation and all the rest just try to go with the
sudo service docker restart
Only this did the trick for me even after restarting the machine.
Giving non-root access - from docker
Add the docker group if it doesn't already exist.
$ sudo groupadd docker
Add the connected user "${USER}" to the docker group.
Change the user name to match your preferred user.
You may have to logout and log back in again for
this to take effect.
$ sudo gpasswd -a ${USER} docker
Restart the Docker daemon.
$ sudo service docker restart
This question is currently number 3 on a Google search. After doing some research into solving this problem on my Linux system I thought I would write this answer. The original post states the problem is on Ubuntu but I also experienced the issue using Fedora. With that in mind, here is what I did to fix the problem.
On Fedora 22
Installing Docker:
$> curl -fsSL https://get.docker.com/ | sh
After installing Docker:
A user needs to be added to the docker group.
$> sudo usermod -aG docker
The docker daemon needs to be started
$> sudo service docker start
You can set the daemon to start at boot
$> sudo chkconfig docker on
You can verify the docker service is running
$> service docker status
And one last final check
$> docker run hello-world
Tested in Ubuntu 16.04
# Create the docker group and add your user to the docker group
groupadd docker
usermod -aG docker $USER
newgrp docker
# Configure docker service to be exposed
mkdir -p /etc/systemd/system/docker.service.d
echo -e '[Service]\nExecStart=\nExecStart=/usr/bin/dockerd -H fd:// -H tcp://0.0.0.0:2376' >> /etc/systemd/system/docker.service.d/override.conf
# restart service
systemctl daemon-reload
service docker restart
Try to use "sudo" with the command you are running.
I have same issue while running docker.
you can run commands as sudo user:
sudo docker ***your command here***
For Ubuntu:
Happened with me when I updated docker.
You need to unmask the service and socket and then restart the service.
Following worked for me:
systemctl unmask docker.service
systemctl unmask docker.socket
systemctl start docker.service
What happend behind the scenes
systemd also has the ability to mark a unit as completely unstartable, automatically or manually, by linking it to /dev/null. This is called masking the unit, and is possible with the mask command.
sudo systemctl mask docker.service
You can check the list of masked services using:
sudo systemctl list-unit-files
To enable auto/manual start of service you need to unmask it using:
sudo sytemctl unmask docker.service
Now the service will be enabled as shown below
As docker binds to a unix socket which is owned by root while starting up, using 'sudo' along with the docker commands will work.
I also had the same issue. The problem was in sockets allocated to docker-daemon and docker-client.
First, permission was not set for the docker-client on docker.sock You can set it using "sudo usermod -aG docker $USER"
Then check your bash file where the docker-client is running, For me it was on 0.0.0.0:2375, while docker-daemon was running on unix socket.(It was set in the configuration file of dockerd).
Just comment the bash-line and it'll work fine.
But if you want to make it work on TCP port instead of unix socket, change the configuration file of dockerd and set it on 0.0.0.0.2375 and keep the line in bash as it is if present or set it to 0.0.0.0:2375.
Perhaps this will help someone, as the error message is extremely unhelpful, and I had gone through all of the standard permission steps numerous times to no avail.
Docker occasionally leaves ghost environment variables in place that block access, despite your system otherwise being correctly set up. The following shell commands may make it accessible again, if you have had it running at one point and it just stopped cooperating after a reboot:
unset DOCKER_HOST
unset DOCKER_TLS_VERIFY
unset DOCKER_TLS_PATH
docker ps
I had a previously working docker install, and after rebooting my laptop it simply refused to work. Was correctly added to the docker user group, had the correct permissions on the socket, etc, but could still not run docker login, docker run ..., etc. This fixed it for me. Unfortunately I have to run this on each reboot. This is mentioned on a couple of github issues also as a workaround, although it seems like a bug that this is a persistent barrier to correct operation of Docker (note: I am on Arch Linux, not OSX, but this was the same issue for me).
I was able to fix that by running the following command:
sudo mv /var/lib/dpkg/info/docker-ce* /tmp
I have faced same error on Amazon EC2 instance. The issue got fixed after restarting the instance.
Add current user to docker group:
sudo usermod -aG docker $(whoami)
For Ubuntu 16.04
Inside file /lib/systemd/system/docker.service change:
ExecStart=/usr/bin/dockerd fd://
with:
ExecStart=/usr/bin/dockerd -H tcp://0.0.0.0:2375
Inside file /etc/init.d/docker change:
DOCKER_OPTS=
with:
DOCKER_OPTS="-H tcp://0.0.0.0:2375"
and then restart your computer.

"Is your docker daemon up and running?" Problems with docker hello world tutorial on Linux

I am running the installation tutorial for Docker on Linux - Ubuntu 14.04
Going step by step through the tutorial, I get the following error message:
docker run hello-world
Post http:///var/run/docker.sock/v1.20/containers/create: dial unix /var/run/docker.sock: no such file or directory.
* Are you trying to connect to a TLS-enabled daemon without TLS?
* Is your docker daemon up and running?
The similar question docker error: /var/run/docker.sock: no such file or directory refers to boot2docker which I am not using
Had the same issue, solved:
docker-machine start default
eval "$(docker-machine env default)"
I got the same problem today. you just have to start the service.
sudo service docker start
It works on linux. I don't know if it works on mac
I had the same problem running docker on ubuntu 14.04.
Trying running Docker as root:
sudo docker run hello-world
Type in password when prompted.
Check the ownership of the file /var/run/docker.sock:
ls -l /var/run/docker.sock
srw-rw----. 1 root root 0 Nov 18 16:17 /var/run/docker.sock
Change the group settings to dockerroot:
sudo chown root:dockerroot /var/run/docker.sock
ls -l /var/run/docker.sock
srw-rw----. 1 root dockerroot 0 Nov 18 16:17 /var/run/docker.sock
Then it should work.
Both the solution here are tried and tested on linux only
Solution 1:
I was Having the same issue, Login with root privilege solved my problem
Solution 2:
The solution here works only with root user because root user has full access to linux socket similarly docker group has full access to linux socket.
if you want to run this with non root user you need to add user to docker group, you can do this with following command -
sudo usermod -aG docker $(whoami)
Now logout and login you should be able to work with non-root user :)
After getting stuck I turned off the computer and went on a road trip. One Monday I turned the computer on and docker run hello-world runs just as the tutorial indicated.
Had exactly the same problem on Windows 8.1
Answer was to open the Oracle VM Virtual Box, right click on the default instance and then click on "Show" icon. Then saw BootLocker logo.
Then back to the Docker Quickstarter "> whale" icon, double click and ascii docker appears.
In linux, after installation, though docker version was giving a proper output, docker run hello-world was not working because the service was not up.
I tried service docker restart in SLES 12 SP3 Linux machine. It worked. So probably your docker daemon needs a restart.
Try the same command service docker restart and it should work.
So, is the Docker daemon running? What troubleshooting did you already do?
The tutorial doesn't mention starting Docker or adding yourself to the docker group so that you can run Docker command without sudo (although, this should have been mentioned when you installed Docker). You need to do both of these things first.

Exploring Docker container's file system

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.
Here are a couple different methods...
A) Use docker exec (easiest)
Docker version 1.3 or newer supports the command exec that behave similar to nsenter. This command can run new process in already running container (container must have PID 1 process running already). You can run /bin/bash to explore container state:
docker exec -t -i mycontainer /bin/bash
see Docker command line documentation
B) Use Snapshotting
You can evaluate container filesystem this way:
# find ID of your running container:
docker ps
# create image (snapshot) from container filesystem
docker commit 12345678904b5 mysnapshot
# explore this filesystem using bash (for example)
docker run -t -i mysnapshot /bin/bash
This way, you can evaluate filesystem of the running container in the precise time moment. Container is still running, no future changes are included.
You can later delete snapshot using (filesystem of the running container is not affected!):
docker rmi mysnapshot
C) Use ssh
If you need continuous access, you can install sshd to your container and run the sshd daemon:
docker run -d -p 22 mysnapshot /usr/sbin/sshd -D
# you need to find out which port to connect:
docker ps
This way, you can run your app using ssh (connect and execute what you want).
D) Use nsenter
Use nsenter, see Why you don't need to run SSHd in your Docker containers
The short version is: with nsenter, you can get a shell into an
existing container, even if that container doesn’t run SSH or any kind
of special-purpose daemon
UPDATE: EXPLORING!
This command should let you explore a running docker container:
docker exec -it name-of-container bash
The equivalent for this in docker-compose would be:
docker-compose exec web bash
(web is the name-of-service in this case and it has tty by default.)
Once you are inside do:
ls -lsa
or any other bash command like:
cd ..
This command should let you explore a docker image:
docker run --rm -it --entrypoint=/bin/bash name-of-image
once inside do:
ls -lsa
or any other bash command like:
cd ..
The -it stands for interactive... and tty.
This command should let you inspect a running docker container or image:
docker inspect name-of-container-or-image
You might want to do this and find out if there is any bash or sh in there. Look for entrypoint or cmd in the json return.
NOTE: This answer relies on commen tool being present, but if there is no bash shell or common tools like ls present you could first add one in a layer if you have access to the Dockerfile:
example for alpine:
RUN apk add --no-cache bash
Otherwise if you don't have access to the Dockerfile then just copy the files out of a newly created container and look trough them by doing:
docker create <image> # returns container ID the container is never started.
docker cp <container ID>:<source_path> <destination_path>
docker rm <container ID>
cd <destination_path> && ls -lsah
see docker exec documentation
see docker-compose exec documentation
see docker inspect documentation
see docker create documentation
In case your container is stopped or doesn't have a shell (e.g. hello-world mentioned in the installation guide, or non-alpine traefik), this is probably the only possible method of exploring the filesystem.
You may archive your container's filesystem into tar file:
docker export adoring_kowalevski > contents.tar
Or list the files:
docker export adoring_kowalevski | tar t
Do note, that depending on the image, it might take some time and disk space.
Before Container Creation :
If you to explore the structure of the image that is mounted inside the container you can do
sudo docker image save image_name > image.tar
tar -xvf image.tar
This would give you the visibility of all the layers of an image and its configuration which is present in json files.
After container creation :
For this there are already lot of answers above. my preferred way to do
this would be -
docker exec -t -i container /bin/bash
The most upvoted answer is working for me when the container is actually started, but when it isn't possible to run and you for example want to copy files from the container this has saved me before:
docker cp <container-name>:<path/inside/container> <path/on/host/>
Thanks to docker cp (link) you can copy directly from the container as it was any other part of your filesystem.
For example, recovering all files inside a container:
mkdir /tmp/container_temp
docker cp example_container:/ /tmp/container_temp/
Note that you don't need to specify that you want to copy recursively.
The file system of the container is in the data folder of docker, normally in /var/lib/docker. In order to start and inspect a running containers file system do the following:
hash=$(docker run busybox)
cd /var/lib/docker/aufs/mnt/$hash
And now the current working directory is the root of the container.
you can use dive to view the image content interactively with TUI
https://github.com/wagoodman/dive
Try using
docker exec -it <container-name> /bin/bash
There might be possibility that bash is not implemented. for that you can use
docker exec -it <container-name> sh
On Ubuntu 14.04 running Docker 1.3.1, I found the container root filesystem on the host machine in the following directory:
/var/lib/docker/devicemapper/mnt/<container id>/rootfs/
Full Docker version information:
Client version: 1.3.1
Client API version: 1.15
Go version (client): go1.3.3
Git commit (client): 4e9bbfa
OS/Arch (client): linux/amd64
Server version: 1.3.1
Server API version: 1.15
Go version (server): go1.3.3
Git commit (server): 4e9bbfa
In my case no shell was supported in container except sh. So, this worked like a charm
docker exec -it <container-name> sh
The most voted answer is good except if your container isn't an actual Linux system.
Many containers (especially the go based ones) don't have any standard binary (no /bin/bash or /bin/sh). In that case, you will need to access the actual containers file directly:
Works like a charm:
name=<name>
dockerId=$(docker inspect -f {{.Id}} $name)
mountId=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$dockerId/mount-id)
cd /var/lib/docker/aufs/mnt/$mountId
Note: You need to run it as root.
I use another dirty trick that is aufs/devicemapper agnostic.
I look at the command that the container is running e.g. docker ps
and if it's an apache or java i just do the following:
sudo -s
cd /proc/$(pgrep java)/root/
and voilá you're inside the container.
Basically you can as root cd into /proc/<PID>/root/ folder as long as that process is run by the container. Beware symlinks will not make sense wile using that mode.
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.
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)
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
On newer versions of Docker you can run docker exec [container_name] which runs a shell inside your container
So to get a list of all the files in a container just run docker exec [container_name] ls
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.
For me, this one works well (thanks to the last comments for pointing out the directory /var/lib/docker/):
chroot /var/lib/docker/containers/2465790aa2c4*/root/
Here, 2465790aa2c4 is the short ID of the running container (as displayed by docker ps), followed by a star.
For docker aufs driver:
The script will find the container root dir(Test on docker 1.7.1 and 1.10.3 )
if [ -z "$1" ] ; then
echo 'docker-find-root $container_id_or_name '
exit 1
fi
CID=$(docker inspect --format {{.Id}} $1)
if [ -n "$CID" ] ; then
if [ -f /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id ] ; then
F1=$(cat /var/lib/docker/image/aufs/layerdb/mounts/$CID/mount-id)
d1=/var/lib/docker/aufs/mnt/$F1
fi
if [ ! -d "$d1" ] ; then
d1=/var/lib/docker/aufs/diff/$CID
fi
echo $d1
fi
This answer will help those (like myself) who want to explore the docker volume filesystem even if the container isn't running.
List running docker containers:
docker ps
=> CONTAINER ID "4c721f1985bd"
Look at the docker volume mount points on your local physical machine (https://docs.docker.com/engine/tutorials/dockervolumes/):
docker inspect -f {{.Mounts}} 4c721f1985bd
=> [{ /tmp/container-garren /tmp true rprivate}]
This tells me that the local physical machine directory /tmp/container-garren is mapped to the /tmp docker volume destination.
Knowing the local physical machine directory (/tmp/container-garren) means I can explore the filesystem whether or not the docker container is running. This was critical to helping me figure out that there was some residual data that shouldn't have persisted even after the container was not running.
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
For an already running container, you can do:
dockerId=$(docker inspect -f {{.Id}} [docker_id_or_name])
cd /var/lib/docker/btrfs/subvolumes/$dockerId
You need to be root in order to cd into that dir. If you are not root, try 'sudo su' before running the command.
Edit: Following v1.3, see Jiri's answer - it is better.
another trick is to use the atomic tool to do something like:
mkdir -p /path/to/mnt && atomic mount IMAGE /path/to/mnt
The Docker image will be mounted to /path/to/mnt for you to inspect it.
My preferred way to understand what is going on inside container is:
expose -p 8000
docker run -it -p 8000:8000 image
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'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
inside the container install mc and ssh: docker exec -it <container> /bin/bash, then with prompt install mc and ssh packages
in same exec-bash console, run mc
press ESC then 9 then ENTER to open menu and select "Shell link..."
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
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
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.
Late to the party, but in 2022 we have VS Code

Resources