977

I want to ssh or bash into a running docker container. Please, see example:

$ sudo docker run -d webserver
webserver is clean image from ubuntu:14.04
$ sudo docker ps
CONTAINER ID  IMAGE            COMMAND    CREATED STATUS  PORTS          NAMES
665b4a1e17b6  webserver:latest /bin/bash  ...     ...     22/tcp, 80/tcp loving_heisenberg 

Now I want to get something like this (go into the running container):

$ sudo docker run -t -i webserver (or maybe 665b4a1e17b6 instead)
$ root@665b4a1e17b6:/#

However when I run the line above I get new CONTAINER ID:

$ root@42f1e37bd0e5:/#

I used Vagrant and I'd like to get a similar behaviour as vagrant ssh.

Gryu
  • 7,559
  • 9
  • 33
  • 52
Timur Fayzrakhmanov
  • 24,775
  • 10
  • 26
  • 35

15 Answers15

1349

The answer is Docker's attach command. So for my example above, the solution will be:

$ sudo docker attach 665b4a1e17b6 #by ID
or
$ sudo docker attach loving_heisenberg #by Name
$ root@665b4a1e17b6:/#

For Docker version 1.3 or later: Thanks to user WiR3D who suggested another way to get a container's shell. If we use attach we can use only one instance of the shell. So if we want open a new terminal with a new instance of a container's shell, we just need to run the following:

$ sudo docker exec -i -t 665b4a1e17b6 /bin/bash #by ID

or

$ sudo docker exec -i -t loving_heisenberg /bin/bash #by Name
$ root@665b4a1e17b6:/#
Timur Fayzrakhmanov
  • 24,775
  • 10
  • 26
  • 35
  • 5
    Alternatively, execute sudo docker attach loving_heisenberg – thiagowfx Sep 21 '14 at 19:59
  • 58
    the attach command does not work for me, it causes the docker to freeze.. any ideas why its happening? – Mo J. Mughrabi Oct 21 '14 at 08:32
  • 1
    first of all, try to find your active container by running: sudo docker ps. If nothing found, try docker ps -a, then copy the container id you like and start container docker start your_id and the last attach it docker attach your_id – Timur Fayzrakhmanov Oct 21 '14 at 08:50
  • 10
    A reminder for boot2docker users: remove sudo :) – Henno Dec 29 '14 at 13:56
  • This works for me running docker in OsX

    $ sudo docker exec -i -t 665b4a1e17b6 bash #by ID

    – Bhoom Suktitipat Aug 07 '15 at 08:49
  • 1
    @MoJ.Mughrabi Are you sure Docker is freezing? It connects you to the shell that is running the entrypoint, so when you attach to a i.e. mongo container you are actually in the shell than runs mongod in the foreground. See the update for creating a new shell. – mmlac Nov 15 '15 at 21:16
  • This is very cool -- two attachments mirror each other on the command line. Interesting for cloud based service tech support and a little unsettling for security. Does anyone know if there is an equivalent unattach or dissasociate command? Or would that just require killing the process that made the attachment? – dhj Dec 18 '15 at 17:18
  • Ps. What about this strange naming? I also see "loving_blabla", who is created this kind of docker container names? lol – Melroy van den Berg May 17 '16 at 10:41
  • @danger89, it is generated by docker like shortcuts in order to run (attach or whatever you want) a container by this name rather than loong ID. It's just convenient. – Timur Fayzrakhmanov May 17 '16 at 18:16
  • 19
    -i -t equals -it – pasha.zhukov Aug 12 '16 at 07:57
  • If you're using zsh you can use this gist to give you a docker-connect <container_name> function that has tab autocompletion on the container name https://gist.github.com/hailwood/beb377c588c41c9e93bacdca0fb3ff1d – Hailwood Jan 11 '17 at 03:04
  • 52
    This is a dangerous answer to be selected and so highly voted. docker attaching to a MongoDB instance, for example, will kill the instance. As explained in more detail in this question attach and exec are different animals. – fred271828 May 10 '17 at 18:27
  • @MoJ.Mughrabi see next answer: if the container was started using bash we can access it using attach, if not then we need to execute the command to create a shell to interact with using exec. – wranvaud Jul 27 '17 at 14:41
709

From Docker 1.3 onwards:

docker exec -it <containerIdOrName> bash

Basically, if the Docker container was started using the /bin/bash command you can access it using attach. If not, then you need to execute the command to create a Bash instance inside the container using exec.

Also to exit Bash without leaving Bash running in a rogue process:

exit

Yep, it is that simple.

WiR3D
  • 7,280
  • 1
  • 13
  • 12
  • still havent figured out how to get nano to work. THink that may involve docker-ssh from phusion – WiR3D Oct 29 '14 at 13:46
  • Is there any way to set bash by default in dockers? – ipeacocks Apr 06 '15 at 13:13
  • @ipeacocks yes, if the RUN command in the dockerfile is /bin/bash. But depends what you mean. If you want to run the container and have bash available immediately in that same terminal then running with -it should do it – WiR3D Apr 07 '15 at 07:43
  • @WiR3D Can I set bash by default after attaching to container? I want launch docker attach some_id and then automatically I want to see working bash. Is it possible? – ipeacocks Apr 07 '15 at 08:12
  • A reminder for mac users, don't run as sudo or you'll get an error in boot2docker (http://stackoverflow.com/questions/25372781/docker-error-var-run-docker-sock-no-such-file-or-directory) – John David Five May 16 '15 at 20:45
  • 11
    Using docker group is bad practice. Any user which is in docker group is essentially used with root permissions without the need to use sudo. http://www.projectatomic.io/blog/2015/08/why-we-dont-let-non-root-users-run-docker-in-centos-fedora-or-rhel/ – Maiku Mori Mar 07 '16 at 17:48
  • @MaikuMori Agreed. Because this is an answer with so many votes, it should not include this advice. – r0estir0bbe Jul 07 '16 at 07:21
  • The annoyance of using sudo comes with much stricter access. Ideally, this is what you want; in practice, there may be situations where you knowingly want to / can safely give group access. For instance, containers which themselves contain / generate containers may want to bypass sudo (especially if you are running someone else's code and don't want to / can't add sudo if it is needed). Far fetched? Sure... In general, don't open your actual user account to DoBadThings by accident / maliciously, but if you know the risks, it does have valid use cases. – Ajax Nov 02 '16 at 10:42
  • 2
    I think it doesn't make much difference, from a host security standpoint, whether you use sudo vs docker group. Either way, there is a security hole built into docker which can provide full privileges in the host file system from the guest -- regardless of whether you use the docker group or sudo to launch the container. – Brent Bradburn Aug 11 '17 at 21:39
  • 1
    @nobar when your user is in the docker group, any program you run can access the entire filesystem. that's not true if you use sudo to run docker (you'd have to enter your password first) – Austin Adams Mar 16 '18 at 17:07
  • For everyone picking up on this conversation: I removed the advice regarding the docker group. For clarity I recommend that setup in a development environment. Original Comment: Note: you should try not to run commands as sudo. Rather add your user to the docker group and just run normally. – WiR3D Aug 06 '18 at 12:48
131

Although the author of the question specifically said they are interested in a running container, it's also worth noting that if the container is not running, but you'd like to run it to poke around you can run:

docker run -i -t --entrypoint /bin/bash <imageID>

Adam Kalnas
  • 1,411
  • 1
  • 9
  • 5
29

Try this:

sudo docker run -i -t webserver /bin/bash

Source: https://docs.docker.com/engine/reference/commandline/run/

Gryu
  • 7,559
  • 9
  • 33
  • 52
kraxor
  • 5,527
20

Based on @Timur's answer I've created the following handy script

Setup

Put docker-ssh file in your $PATH with the following contents

#!/bin/bash -xe

# docker container id or name might be given as a parameter
CONTAINER=$1

if [[ "$CONTAINER" == "" ]]; then
  # if no id given simply just connect to the first running container
  CONTAINER=$(docker ps | grep -Eo "^[0-9a-z]{8,}\b")
fi

# start an interactive bash inside the container
# note some containers don't have bash, then try: ash (alpine), or simply sh
# the -l at the end stands for login shell that reads profile files (read man)
docker exec -i -t $CONTAINER bash -l

Note: Some container do not contain bash, but ash, sh etc. In these cases bash shall be replaced in the above script.

Usage

If you have only one running instance, simply run

$> docker-ssh 

Otherwise, provide it with a docker id parameter that you get from docker ps (first col)

$> docker-ssh 50m3r4nd0m1d
Prajwal
  • 616
  • 1
  • 7
  • 13
Matyas
  • 526
18

If your container doesn't have bash installed you could try sh:

docker exec -it CONTAINER /bin/sh

Or look for shells in /bin first:

docker export CONTAINER|tar -t|egrep ^bin/
laktak
  • 559
  • 1
  • 6
  • 13
9

I've created a containerized SSH server that provides SSH capabilities to any running container. You don't need to change your container. The only requirement is that the container has bash.

If you have a container with name 'web-server1'. The following docker run command would start a second container that would provide SSH for the first container.

docker run -ti --name sshd-web-server1 -e CONTAINER=web-server1 -p 2222:22 \
-v /var/run/docker.sock:/var/run/docker.sock -v $(which docker):/usr/bin/docker \
jeroenpeeters/docker-ssh

For more pointers, checkout https://github.com/jeroenpeeters/docker-ssh

  • By the way, how can we have .bashrc auto loaded when starting a ssh session using your solution? Also posted an issue on github https://github.com/jeroenpeeters/docker-ssh/issues/30 – Nam G VU Jul 08 '17 at 06:05
6

@jpetazzo has an awesome post about this subject. The short answer would be to use nsenter:

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

P.S.: Don't forget to check the discussion in the comments of the post...

Cheers

A.L
  • 478
  • 7
  • 20
Richard
  • 61
4

You can also give the Docker container a routeable IP address with Pipework, and after that SSH into the machine with that new IP address.

This will be more "traditional" (ssh), instead of using an application-specific command like docker attach, and will eventually make it more 'portable' across systems and versions.

radriaanse
  • 481
  • 3
  • 15
  • Please, add the simples way how to do it. If to be honest, I really need it, but I have no time to search the simplest solution for that. Could you post your answer here? It would be great.. – Timur Fayzrakhmanov Oct 29 '14 at 12:08
  • 2
    There are 2 ways of accomplishing this, but it isn't simple, and would become a large post. You could check out this link by yourself, for using pipework or this link, witch essentially accomplishes the same as Pipework and is a bit more simple, but you need to do it manually. So it depends about how many servers where talking. If you can't figure out something more specific, let me know. But i also don't have the time to write an full tutorial. – radriaanse Oct 29 '14 at 12:30
  • You are right - there is no obvious and simple way to do it( Thanks for links, I think I will revisit it later. – Timur Fayzrakhmanov Oct 29 '14 at 12:57
3

Sometimes it will be handy to be able to ssh into a Docker container, especially during development. The following Docker image allows to ssh into a container using a private key:

UbuntuWithSSH-Docker

The gist of the Dockerfile is https://gist.github.com/devbkhadka/98792f7bca57f9778793b2db758b3d07.

2

GOINSIDE

install goinside command line tool with:

sudo npm install -g goinside

and go inside a docker container with a proper terminal size with:

goinside docker_container_name

for more details check this out.

Soorena
  • 201
2
docker run -it openjdk:8

This works :-)

edwinksl
  • 23,789
Kishan B
  • 121
1

To bash into a running container, type this:

docker exec -t -i container_name /bin/bash
0

Just for information. If you need to login in a simple container that is not a daemon, you need to use the following commands:

docker start {id}
docker attach {id}
Nek
  • 221
  • 4
  • 12
-1

if the container is stopped like for example a data-only container then a good solution is to run a throwaway container every time you want to attach to the data container. In this case the data container itself could be entirely empty, as the temporary container would have the OS tools.

$ docker run --rm --volumes-from mydata -it ubuntu bash
root@645045d3cc87:/# ls /mydata
root@645045d3cc87:/# touch /mydata/foo
root@645045d3cc87:/# exit
exit