Question

I use docker on OSX with boot2docker.

I want to get an Ssh connection from my terminal into a running container.

But I can't do this :(

I think it's because Docker is running in a virtual machine.

Was it helpful?

Solution

There are several things you must do to enable ssh'ing to a container running in a VM:

  1. install and run sshd in your container (example). sshd is not there by default because containers typically run only one process, though they can run as many as you like.
  2. EXPOSE a port as part of creating the image, typically 22, so that when you run the container, the daemon connects to the EXPOSE'd port inside the container and something can be exposed on the outside of the container.
  3. When you run the container, you need to decide how to map that port. You can let Docker do it automatically or be explicit. I'd suggest being explicit: docker run -p 42222:22 ... which maps port 42222 on the VM to port 22 in the container.
  4. Add a portmap to the VM to expose the port to your host. e.g. when your VM is not running, you can add a mapping like this: VBoxManage modifyvm "boot2docker-vm" --natpf1 "containerssh,tcp,,42222,,42222"

Then from your host, you should be able to ssh to port 42222 on the host to reach the container's ssh daemon.

Here's what happens when I perform the above steps:

$ VBoxManage modifyvm "boot2docker-vm" --natpf1 "containerssh,tcp,,42222,,42222"
$ ./boot2docker start
[2014-04-11 12:07:35] Starting boot2docker-vm...
[2014-04-11 12:07:55] Started.
$ docker run -d -p 42222:22 dhrp/sshd
Unable to find image 'dhrp/sshd' (tag: latest) locally
Pulling repository dhrp/sshd
2bbfe079a942: Download complete 
c8a2228805bc: Download complete 
8dbd9e392a96: Download complete 
11d214c1b26a: Download complete 
27cf78414709: Download complete 
b750fe79269d: Download complete 
cf7e766468fc: Download complete 
082189640622: Download complete 
fa822d12ee30: Download complete 
1522e919ec9f: Download complete 
fa594d99163a: Download complete 
1bd442970c79: Download complete 
0fda9de88c63: Download complete 
86e22a5fdce6: Download complete 
79d05cb13124: Download complete 
ac72e4b531bc: Download complete 
26e4b94e5a13b4bb924ef57548bb17ba03444ca003128092b5fbe344110f2e4c
$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS                   NAMES
26e4b94e5a13        dhrp/sshd:latest    /usr/sbin/sshd -D      6 seconds ago       Up 3 seconds        0.0.0.0:42222->22/tcp   loving_einstein     
$ ssh root@localhost -p 42222
The authenticity of host '[localhost]:42222 ([127.0.0.1]:42222)' can't be established.
RSA key fingerprint is ....
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '[localhost]:42222' (RSA) to the list of known hosts.
root@localhost's password: screencast
Welcome to Ubuntu 12.04 LTS (GNU/Linux 3.12.1-tinycore64 x86_64)

 * Documentation:  https://help.ubuntu.com/

The programs included with the Ubuntu system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Ubuntu comes with ABSOLUTELY NO WARRANTY, to the extent permitted by
applicable law.

root@26e4b94e5a13:~# exit
logout

So that shows ssh->localhost 42222->VM port 42222->container port 22.

OTHER TIPS

Docker has added the docker exec command to Docker 1.3.0. You can connect to a running container using the following:

docker exec -it <container id> /bin/bash

That will connect to a bash prompt on the running container.

If you just want to get into the running container, you may consider using nsenter. Here is a simple bash script (suggested by Chris Jones) that you can use to enter into a docker container. Save it somewhere in your $PATH as docker-enter and chmod +x

#!/bin/bash
set-e
# Check for nsenter. If not found, install it
boot2docker ssh '[ -f /var/lib/boot2docker/nsenter ] || docker run --rm -v /var/lib/boot2docker/:/target jpetazzo/nsenter'
# Use bash if no command is specified
args=$@
if[[ $# = 1 ]]; then
    args+=(/bin/bash)
fi

boot2docker ssh -t sudo /var/lib/boot2docker/docker-enter "${args[@]}"

Then you can run docker-enter 89af3d (or whatever configuration you want to enter)

A slightly modified variant of Michael's answer that just requires the container you want to enter be named (APPNAME):

boot2docker ssh '[ -f /var/lib/boot2docker/nsenter ] || docker run --rm -v /var/lib/boot2docker/:/target jpetazzo/nsenter'

boot2docker ssh -t sudo /var/lib/boot2docker/docker-enter $(docker ps | grep $APPNAME | awk '{ print $1 }')

I've tested this for an Ubuntu 16.04 image running on a host with the same OS, Docker 18.09.2, it should also work for boot2Docker with minor modifications.

Build the image. Run it in background container (youruser may be root):

$ docker run -ditu <youruser> <imageId>

Attach to it with a shell:

$ docker exec -it <containerId> /bin/bash

Install the openssh-server (sudo only needed if youruser is not root, the command may differ for boot2Docker):

$ sudo apt-get install -y openssh-server

Run it:

$ sudo service ssh start

(The following step is optional, if youruser has a password, you can skip it and provide the password at each ssh connection).

Create a RSA key on the client host:

$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/youruser/.ssh/id_rsa):
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/youruser/.ssh/id_rsa.
Your public key has been saved in /home/youruser/.ssh/id_rsa.pub.

On the docker image, create a directory $HOME/.ssh:

$ cd
$ mkdir .ssh && cd .ssh
$ vi authorized_keys

Copy and paste the content of $HOME/.ssh/id_rsa.pub on the client machine to authorized_keys on the docker image and save the file.

(End of optional step).

Jot down your image's IP address:

$ cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  63448863ac39
^^^^^^^^^^ this

Now the connection from the client host should be effective:

$ ssh 172.17.0.2
Enter passphrase for key '/home/youruser/.ssh/id_rsa': 
Welcome to Ubuntu 16.04.6 LTS (GNU/Linux 4.15.0-46-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Fri Apr  5 09:50:30 2019 from 172.17.0.1

Of course you can apply the above procedure non-interactively in your Dockerfile.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top