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
Now, let us run the image and build the docker container
$ docker run --name nginx-exec nginx
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
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
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
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