SSH into Docker Container [3 Simple Methods]


Docker

The developers need to understand and troubleshoot the issues that arise while developing the application. Most of us know that SSH is used to obtain remote shell access to the system in order to debug any issues or perform some execution. In the context of dockers, there are a lot of ways to SSH into the docker container and perform some execution or troubleshoot the issue.

In this article let us learn how to SSH  into a Docker Container.

There are several ways in which you can ssh into a docker container. Let us go through various methods to do so.

Method 1: Using docker exec 

We can do a docker exec using the docker CLI command and enter inside a running container. Further, you can execute any commands inside the container with the help of the docker exec command.

 

Docker exec syntax

docker exec [options]  [container] [command]

where options can be the following

Options Usage
-i or –interactive Interactive Shell
-t or –tty Allocate a pseudo-TTY
-d or –detach Run the command in the background

Let us understand more about this with an example. Pull the Nginx docker from the public docker hub

$ docker pull nginx

SSH into Docker Container [3 Simple Methods]
Now, let us run the image and build the docker container

$ docker run --name nginx-exec nginx 

SSH into Docker Container [3 Simple Methods]

Now, let us check if the container is up and running with the docker ps command

Output

CONTAINER ID   IMAGE              COMMAND                  CREATED              STATUS              PORTS     NAMES
a1ae5df25793   nginx              "/docker-entrypoint.…"   About a minute ago   Up About a minute   80/tcp    nginx-exec

Now that we have the container up and running, let us enter the container by running the command below.

$ docker exec -it nginx /bin/bash

Once you hit the above command, you will be inside the Nginx docker container and can execute any other command.

Output

root@a1ae5df25793:/# 
root@a1ae5df25793:/# ls
bin   dev		   docker-entrypoint.sh  home  lib64  mnt  proc  run   srv  tmp  var
boot  docker-entrypoint.d  etc			 lib   media  opt  root  sbin  sys  usr
root@a1ae5df25793:/#

So, with docker exec, we will be able to check the processes running inside the container, list the files and perform other operations as if you are doing it on the local system.

 

Method 2: Using docker attach

Another alternative to using docker exec is to use Docker attach command which typically lets you attach the standard input and output to the running docker container.

This means that whatever you enter into the terminal is forwarded to the running container and anything that is printed will be shown in the console.

Docker attach syntax

docker attach [OPTIONS] CONTAINER

where options can be the following

Options Usage
--no-stdin Do not attach STDIN
--sig-proxy Proxy all received signals to the process

Default: True

 

Lets us take a look at this scenario to understand better.

Let us run the Nginx container using the command given below.

$ docker run --name nginx --rm -p 8080:80  -d nginx

This will result in creating the container

e2fcdb7720f3397c55c1bae49f6337fc68407701cd7766b8e084b66b0e8d2bb7

Now let us attach to the running container using the docker attach command

$ docker attach --sig-proxy=false nginx

After you run the command, hit the URL http://localhost:8080/ which shall open up the Nginx page and also observe the terminal output which is shown below.

Browser Output

SSH into Docker Container [3 Simple Methods]

 

Terminal Output

172.17.0.1 - - [07/Oct/2022:18:23:58 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" "-"
2022/10/07 18:23:58 [error] 31#31: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 172.17.0.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"
172.17.0.1 - - [07/Oct/2022:18:23:58 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost:8080/" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" "-"

With this approach, we understand that the docker attach command allows you to view the ongoing output or control the docker interactively similar to running the commands from the terminal.

 

Method 3: Using an open-ssh server

If you are running a container locally, it is always best to use docker exec to enter the container and debug. However, if you are running the container remotely, then it is necessary to install sshd inside the container.

Let us take a look at this case where we install the open-ssh server as part of the existing base image and run the container.

Setup Lab Environment

Let us create a docker file that installs the open-ssh server and build the image.

FROM ubuntu:16.04

RUN apt-get update && apt-get install -y openssh-server
RUN mkdir /var/run/sshd

RUN echo 'root:mypassword' | chpasswd
RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config
RUN sed 's@session\s*required\s*pam_loginuid.so@session optional pam_loginuid.so@g' -i /etc/pam.d/sshd

EXPOSE 22

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

 

Now, let us create a docker image with the name as

$ docker build -t ubuntu-ssh:1.0 .

 

Output
SSH into Docker Container [3 Simple Methods]
Further, let us run the docker container in the background using the -d option and also expose the ports defined in the dockerfile and see that the container is created as shown below.

Command

$ docker run -d -P --name ubuntussh ubuntu-ssh:1.0

When you run the command, you will see that port 22 which is exposed as part of dockerfile, will be mapped to some port on the host system.

Output

CONTAINER ID   IMAGE              COMMAND                  CREATED          STATUS          PORTS                                     NAMES
7f5101007671   ubuntu-ssh:1.0     "/usr/sbin/sshd -D"      28 seconds ago   Up 23 seconds   0.0.0.0:49153->22/tcp, :::49153->22/tcp   ubuntussh

In this case, the docker container's port 22 is mapped to the Host port 49153.

Up next, let us find the IP address of the docker container which can be used for SSH using the docker inpect command.

docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' ubuntussh

Output

172.17.0.5

With the IP address of the docker container, let us now try to SSH into the docker container with the command mentioned below.

$ ssh root@172.17.0.5

This shall ask for the password and you will have to enter the password which you have specified in the dockerfile and you will be logged into the container as shown below.

Output

root@172.17.0.5's password: 
Welcome to Ubuntu 16.04.7 LTS (GNU/Linux 5.15.0-48-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage
Last login: Fri Oct  7 18:07:47 2022 from 172.17.0.1
root@7f5101007671:~# 

 

Troubleshooting

In case you have connectivity issues with respect to sshd, please make sure you have root access to containers and you have updated permissions to sshd_config file appropriately as shown below for /etc/ssh/sshd_config

Below is the snapshot of the config file.

# Authentication:
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes

 

NOTE:
The method of enabling SSH into the docker is highly not recommended as it involves security risks and requires additional capabilities since you have to manage the keys and protect them from wrong edits or changes. Hence, please think twice before using this approach and if you are not sure of having it, then avoid it. Although there is a way to start SSHD service without any capabilities inside a container so you may also try that approach.

 

Conclusion

As a developer, it is important that we know our applications are running as expected, and in case of any issues, we should be able to access the system to troubleshoot the issues that arise.

In this article, we have learned about how to SSH into the docker containers. I hope this article makes it clear to you and I suggest everyone try it out.

In case you have any doubts, please feel free to add your questions in the comment section below and I shall try to respond at the earliest.

Happy learning!!

References

https://docs.docker.com/engine/reference/commandline/attach/
https://docs.docker.com/engine/reference/commandline/exec/
https://forums.docker.com/t/connection-refused-when-trying-to-ssh-into-docker-containers-but-port-22-is-not-blocked-pings-work/8970/4

 

Deepak Prasad

Deepak Prasad

He is the founder of GoLinuxCloud and brings over a decade of expertise in Linux, Python, Go, Laravel, DevOps, Kubernetes, Git, Shell scripting, OpenShift, AWS, Networking, and Security. With extensive experience, he excels in various domains, from development to DevOps, Networking, and Security, ensuring robust and efficient solutions for diverse projects. You can connect with him on his LinkedIn profile.

Can't find what you're searching for? Let us assist you.

Enter your query below, and we'll provide instant results tailored to your needs.

If my articles on GoLinuxCloud has helped you, kindly consider buying me a coffee as a token of appreciation.

Buy GoLinuxCloud a Coffee

For any other feedbacks or questions you can send mail to admin@golinuxcloud.com

Thank You for your support!!

Leave a Comment