How to SSH into Docker?

DockerContainersLxc

Docker Problem Overview


I'd like to create the following infrastructure flow:

How can that be achieved using Docker?

Docker Solutions


Solution 1 - Docker

Firstly you need to install a SSH server in the images you wish to ssh-into. You can use a base image for all your container with the ssh server installed. Then you only have to run each container mapping the ssh port (default 22) to one to the host's ports (Remote Server in your image), using -p <hostPort>:<containerPort>. i.e:

docker run -p 52022:22 container1 
docker run -p 53022:22 container2

Then, if ports 52022 and 53022 of host's are accessible from outside, you can directly ssh to the containers using the ip of the host (Remote Server) specifying the port in ssh with -p <port>. I.e.:

ssh -p 52022 myuser@RemoteServer --> SSH to container1

ssh -p 53022 myuser@RemoteServer --> SSH to container2

Solution 2 - Docker

Notice: this answer promotes a tool I've written.

The selected answer here suggests to install an SSH server into every image. Conceptually this is not the right approach (https://docs.docker.com/articles/dockerfile_best-practices/).

I've created a containerized SSH server that you can 'stick' to any running container. This way you can create compositions with every container. The only requirement is that the container has bash.

The following example would start an SSH server exposed on port 2222 of the local machine.

$ docker run -d -p 2222:22 \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -e CONTAINER=my-container -e AUTH_MECHANISM=noAuth \
  jeroenpeeters/docker-ssh

$ ssh -p 2222 localhost

For more pointers and documentation see: https://github.com/jeroenpeeters/docker-ssh

> Not only does this defeat the idea of one process per container, it is also a cumbersome approach when using images from the Docker Hub since they often don't (and shouldn't) contain an SSH server.

Solution 3 - Docker

These files will successfully open sshd and run service so you can ssh in locally. (you are using cyberduck aren't you?)

Dockerfile

FROM swiftdocker/swift
MAINTAINER Nobody

RUN apt-get update && apt-get -y install openssh-server supervisor
RUN mkdir /var/run/sshd
RUN echo 'root:password' | chpasswd
RUN sed -i 's/PermitRootLogin without-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

COPY supervisord.conf /etc/supervisor/conf.d/supervisord.conf

EXPOSE 22
CMD ["/usr/bin/supervisord"]

supervisord.conf

[supervisord]
nodaemon=true

[program:sshd]
command=/usr/sbin/sshd -D

to build / run start daemon / jump into shell.

docker build -t swift3-ssh .  
docker run -p 2222:22 -i -t swift3-ssh
docker ps # find container id
docker exec -i -t <containerid> /bin/bash

enter image description here

Solution 4 - Docker

I guess it is possible. You just need to install a SSH server in each container and expose a port on the host. The main annoyance would be maintaining/remembering the mapping of port to container.

However, I have to question why you'd want to do this. SSH'ng into containers should be rare enough that it's not a hassle to ssh to the host then use docker exec to get into the container.

Solution 5 - Docker

Create docker image with openssh-server preinstalled:

Dockerfile
FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd
RUN echo 'root:screencast' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config

# SSH login fix. Otherwise user is kicked off after login
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

ENV NOTVISIBLE "in users profile"
RUN echo "export VISIBLE=now" >> /etc/profile

EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]

Build the image using:

$ docker build -t eg_sshd .

Run a test_sshd container:

$ docker run -d -P --name test_sshd eg_sshd
$ docker port test_sshd 22

0.0.0.0:49154

Ssh to your container:

$ ssh root@192.168.1.2 -p 49154
# The password is ``screencast``.
root@f38c87f2a42d:/#

Source: https://docs.docker.com/engine/examples/running_ssh_service/#build-an-eg_sshd-image

Solution 6 - Docker

It is a short way but not permanent

first create a container

docker run  ..... -p 22022:2222 .....

port 22022 on your host machine will map on 2222, we change the ssh port on container later , then on your container executing the following commands

apt update && apt install  openssh-server # install ssh server
passwd #change root password

in file /etc/ssh/sshd_config change these : uncomment Port and change it to 2222

Port 2222

uncomment PermitRootLogin to

PermitRootLogin yes

and finally restart ssh server

/etc/init.d/ssh start

you can login to your container now

ssh -p 2022 root@HostIP

Remember : if you restart the container you need to restart ssh server again

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKamil LelonekView Question on Stackoverflow
Solution 1 - DockerJavier CortejosoView Answer on Stackoverflow
Solution 2 - DockerJeroen PeetersView Answer on Stackoverflow
Solution 3 - DockerjohndpopeView Answer on Stackoverflow
Solution 4 - DockerAdrian MouatView Answer on Stackoverflow
Solution 5 - DockerusernameView Answer on Stackoverflow
Solution 6 - DockerMehdi AlisoltaniView Answer on Stackoverflow