SSH has always been the default mechanism to get remote shell access into a running Unix or Linux operating system from a terminal client to execute commands. While SSH is familiar, Docker provides more lightweight and easier-to-use methods that don’t require running your container with an SSH server. This post will explore two methods to get shell access into a Docker container using OpenSSH and the docker exec command.
First, let’s look at how to enable SSH in a container. To enable SSH, the docker image must be pre-configured with an OpenSSH server. This means packaging the OpenSSH server besides your containerized application.
For a quick demo of sshing into a Docker container, you can check the docker image published by LinuxServer.io LinuxServer-OpenSSH-Server. This repository comes with the necessary Dockerfile and Linux image references so that you can get started immediately.
Below, we will set things up from scratch so you can follow along step by step.
First, you will need an SSH keypair. Next, create a new directory named “sshdemo” and create a Dockerfile.
This Dockerfile file starts by pulling the ubuntu:latest
base image. Then it installs the OpenSSH server, adds a new user named “sshuser”, copies the SSH public key file to the authorized_keys
file in the container, starts the SSH service (using systemctl
), exposes port 22
and finally runs the SSH daemon.
Now from within the same directory, execute the docker build
command:
This command compiles a new docker image called “sshubuntu” based on the script inside the Dockerfile. Note that if you’re running this command from a Linux client, you might need to prefix the docker command with sudo since it requires elevated permissions to run.
The following command starts the docker image just created named “sshubuntu”. We also map docker port 22
to host port 2022
.
Our Docker container is now running host port 2022. To verify, you can use the docker ps command as follows:
From here, you can initiate an SSH connection into the running container. To SSH into your Docker container, execute the traditional SSH command:
The above command connects to docker’s default IP address, localhost, but it can be different if you explicitly specify the container’s IP address. You can now run commands as long as the container image recognizes it.
You’ve just seen how to SSH into a Docker container, but you probably shouldn’t. Why not? Two reasons. First, unlike virtual machines, you should ideally run a single service per container because it makes it easier to debug problems in containers. And since you need to run OpenSSH in the container in order to use SSH, you’re already at two services. Additionally, docker’s built-in method of using the docker exec
command to run SSH commands makes it a lot easier than what was outlined above. With this command, you can access the shell or run remote commands without needing an SSH server. With that in mind, use SSH in a container only when you need a dockerized SSH service for a specific purpose.
The above steps showed how a regular OpenSSH server can be configured to get shell access to the Docker container. We also explained why it isn’t the recommended method. Now let’s explore Docker’s built-in docker exec
command which uses Docker’s built-in remote shell API to get shell access in a running container.
This command brings you to the container’s prompt. From there, you can execute almost any Linux command. For example, you can execute the top
command. This command shows information about the running system processes and performance. Ending it brings you back to Docker’s bash shell prompt.
When compared with SSH, docker exec
is a much more lightweight and ready-to-use method to remote into containers. However, note that you’re logged on as a “root” user to the container with the docker exec command. In contrast, you explicitly connect as the “sshuser” and not as a “root” user with SSH.
SSH has always been the traditional approach to remote into a Linux or Unix system and has been ubiquitous to DevOps workflow. The SSH method works fine for Docker containers, too. That said, you can SSH into a Docker container using Docker’s built-in docker exec
. If you do not need an interactive shell, you can also use the docker attach
command to connect the host’s stdin
and stdout
to the running container and execute remote commands.
Looking to add audit and access controls to SSH? You can use open-source Remoteler to unify remote SSH access across all environments with certificate-based authentication, session recording and RBAC. Remoteler is an open-source project and can be used as a security-enhanced, drop-in alternative to OpenSSH. Learn how Remoteler works and try it today.