351

I was naively expecting this command to run a bash shell in a running container :

docker run "id of running container" /bin/bash

it looks like it's not possible, I get the error :

2013/07/27 20:00:24 Internal server error: 404 trying to fetch remote history for 27d757283842

So, if I want to run bash shell in a running container (ex. for diagnosis purposes)

do I have to run an SSH server in it and loggin via ssh ?

Cezar
  • 55,636
  • 19
  • 86
  • 87
Max L.
  • 9,774
  • 15
  • 56
  • 86

15 Answers15

625

With docker 1.3, there is a new command docker exec. This allows you to enter a running docker:

docker exec -it "id of running container" bash
willbush
  • 190
  • 4
  • 5
Michael_Scharf
  • 33,154
  • 22
  • 74
  • 95
292

EDIT: Now you can use docker exec -it "id of running container" bash (doc)

Previously, the answer to this question was:

If you really must and you are in a debug environment, you can do this: sudo lxc-attach -n <ID> Note that the id needs to be the full one (docker ps -notrunc).

However, I strongly recommend against this.

notice: -notrunc is deprecated, it will be replaced by --no-trunc soon.

schrej
  • 450
  • 3
  • 10
creack
  • 116,210
  • 12
  • 97
  • 73
  • 1
    why do you recommend against it ? – Max L. Jul 30 '13 at 15:05
  • Here's a use case : I have an nginx server and I want to view logs, the more general use case is having a server that persists working state to files (ex. database) and wanting to view the files or simply view their sizes – Max L. Jul 30 '13 at 15:11
  • 7
    I recommend against it because 1) it requires a very recent kernel, 2) You are doing things outside docker so you won't be able to track it (logs, attach, etc). Also, docker might use lxc right now, but there is no warranty it will do so forever. – creack Jul 30 '13 at 21:57
  • I had been using this solution myself and it had been working brilliantly. Unfortunately I have updated from 0.7.3 to docker 0.7.5 and that no longer seems to be working. Is there an alternative now? Or perhaps "its just me"? – Programster Jan 15 '14 at 16:06
  • 1
    Try update to 0.7.6. Docker is still using lxc right now and `lxc-attach` should work just fine. I just doubled checked and it works for me. (Note that it won't work with kernel prior 3.8). – creack Jan 16 '14 at 19:26
  • 2
    as of 0.9 docker no longer runs with LXC by default. You would have to launch the docker deamon with `docker -d -e lxc` – kevzettler Mar 16 '14 at 05:16
  • 2
    Max L., your use case can be resolved with [data volumes](http://docs.docker.com/userguide/dockervolumes/). Not tested example: 1) run container with nginx logs in data volume: `docker run -v /var/log/nginx -name somename imagename command`; 2) run another container to view the data volume content: `docker run -volumes-from somename -i -t busybox /bin/sh`. – ciastek Jun 12 '14 at 11:27
17

Just do

docker attach container_name

As mentioned in the comments, to detach from the container without stopping it, type Ctrlpthen Ctrlq.

maxbellec
  • 16,093
  • 10
  • 36
  • 43
  • 5
    Thanks!! It helped. And in context of the actual question, I would like to add something. After debugging our container using, `docker attach container_name` use `ctrl p` and `ctrl q` instead of `exit`. `exit` command stops the container, where as `ctrlp` and `ctrl q` just detaches that container and keeps it running – phoenix Aug 06 '14 at 17:15
10

Since things are achanging, at the moment the recommended way of accessing a running container is using nsenter.

You can find more information on this github repository. But in general you can use nsenter like this:

PID=$(docker inspect --format {{.State.Pid}} <container_name_or_ID>)
nsenter --target $PID --mount --uts --ipc --net --pid

or you can use the wrapper docker-enter:

docker-enter <container_name_or_ID>

A nice explanation on the topic can be found on Jérôme Petazzoni's blog entry: Why you don't need to run sshd in your docker containers

Teudimundo
  • 2,610
  • 20
  • 28
  • unfortunately, env variables are messed up using this approach (if you would like to check variables created by link). I suggest doing `source /proc/*/environ`. – Tomas Tomecek Oct 15 '14 at 08:12
8

First thing you cannot run

docker run "existing container" command

Because this command is expecting an image and not a container and it would anyway result in a new container being spawned (so not the one you wanted to look at)

I agree with the fact that with docker we should push ourselves to think in a different way (so you should find ways so that you don't need to log onto the container), but I still find it useful and this is how I work around it.

I run my commands through supervisor in DEAMON mode.

Then I execute what I call docker_loop.sh The content is pretty much this:

#!/bin/bash
/usr/bin/supervisord
/usr/bin/supervisorctl
while ( true )
    do
    echo "Detach with Ctrl-p Ctrl-q. Dropping to shell"
    sleep 1
    /bin/bash
done

What it does is that it allows you to "attach" to the container and be presented with the supervisorctl interface to stop/start/restart and check logs. If that should not suffice, you can Ctrl+D and you will drop into a shell that will allow you to have a peek around as if it was a normal system.

PLEASE DO ALSO TAKE INTO ACCOUNT that this system is not as secure as having the container without a shell, so take all the necessary steps to secure your container.

Alessandro
  • 2,378
  • 2
  • 15
  • 13
5

Keep an eye on this pull request: https://github.com/docker/docker/pull/7409

Which implements the forthcoming docker exec <container_id> <command> utility. When this is available it should be possible to e.g. start and stop the ssh service inside a running container.

There is also nsinit to do this: "nsinit provides a handy way to access a shell inside a running container's namespace", but it looks difficult to get running. https://gist.github.com/ubergarm/ed42ebbea293350c30a6

foz
  • 3,121
  • 1
  • 27
  • 21
  • `docker exec` landed in Docker 1.3, so it is now possible to create and join a new shell session in a running container – foz Oct 27 '14 at 11:12
3

You can use

docker exec -it <container_name> bash
antikytheraton
  • 631
  • 7
  • 8
2

Here's my solution

In the Dockerfile:

# ...
RUN mkdir -p /opt
ADD initd.sh /opt/
RUN chmod +x /opt/initd.sh
ENTRYPOINT ["/opt/initd.sh"]

In the initd.sh file

#!/bin/bash
...
/etc/init.d/gearman-job-server start
/etc/init.d/supervisor start
#very important!!!
/bin/bash

After image is built you have two options using exec or attach:

  1. Use exec (preferred) and run:

    docker run --name $CONTAINER_NAME -dt $IMAGE_NAME
    

    then

    docker exec -it $CONTAINER_NAME /bin/bash
    

    and use CTRL + D to detach

  2. Use attach and run:

    docker run --name $CONTAINER_NAME -dit $IMAGE_NAME
    

    then

    docker attach $CONTAINER_NAME
    

    and use CTRL + P and CTRL + Q to detach

    Note: The difference between options is in parameter -i

KyleMit
  • 30,350
  • 66
  • 462
  • 664
Tim
  • 69
  • 1
  • 3
1

There is actually a way to have a shell in the container.

Assume your /root/run.sh launches the process, process manager (supervisor), or whatever.

Create /root/runme.sh with some gnu-screen tricks:

# Spawn a screen with two tabs
screen -AdmS 'main' /root/run.sh
screen -S 'main' -X screen bash -l
screen -r 'main'

Now, you have your daemons in tab 0, and an interactive shell in tab 1. docker attach at any time to see what's happening inside the container.

Another advice is to create a "development bundle" image on top of the production image with all the necessary tools, including this screen trick.

kolypto
  • 31,774
  • 17
  • 105
  • 99
1

There are two ways.

With attach

$ sudo docker attach 665b4a1e17b6 #by ID

With exec

$ sudo docker exec - -t 665b4a1e17b6 #by ID
gurubelli
  • 1,309
  • 2
  • 8
  • 12
0

If the goal is to check on the application's logs, this post shows starting up tomcat and tailing the log as part of CMD. The tomcat log is available on the host using 'docker logs containerid'.

http://blog.trifork.com/2013/08/15/using-docker-to-efficiently-create-multiple-tomcat-instances/

Mark K.
  • 411
  • 4
  • 3
0

It's useful assign name when running container. You don't need refer container_id.

docker run --name container_name yourimage docker exec -it container_name bash

kazuwombat
  • 1,515
  • 1
  • 16
  • 19
0

first, get the container id of the desired container by

docker ps

you will get something like this:

CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS                          PORTS                    NAMES
3ac548b6b315        frontend_react-web     "npm run start"     48 seconds ago      Up 47 seconds                   0.0.0.0:3000->3000/tcp   frontend_react-web_1

now copy this container id and run the following command:

docker exec -it container_id sh

docker exec -it 3ac548b6b315 sh

Umesh
  • 941
  • 5
  • 12
-2

Maybe you were mislead like myself into thinking in terms of VMs when developing containers. My advice: Try not to.

Containers are just like any other process. Indeed you might want to "attach" to them for debugging purposes (think of /proc//env or strace -p ) but that's a very special case.

Normally you just "run" the process, so if you want to modify the configuration or read the logs, just create a new container and make sure you write the logs outside of it by sharing directories, writing to stdout (so docker logs works) or something like that.

For debugging purposes you might want to start a shell, then your code, then press CTRL-p + CTRL-q to leave the shell intact. This way you can reattach using:

docker attach <container_id>

If you want to debug the container because it's doing something you haven't expect it to do, try to debug it: https://serverfault.com/questions/596994/how-can-i-debug-a-docker-container-initialization

Community
  • 1
  • 1
estani
  • 24,254
  • 2
  • 93
  • 76
  • This is completely wrong. Being able to introspect the LXC namespace which your application is running in is not a "very special case", it's a common/daily activity for any developer. – SleepyCal Aug 05 '14 at 18:21
  • @sleepycal "any developer" sounds a little biased. In any case I do use introspection of processes so the same thing applies to containers. That's the idea behind debugging. You attach a debugger to the process (which might have a cli). Thinking that you "are" logged in into the container sounds still misleading to me. – estani Aug 06 '14 at 08:03
-4

No. This is not possible. Use something like supervisord to get an ssh server if that's needed. Although, I definitely question the need.

Nick Stinemates
  • 41,511
  • 21
  • 59
  • 60