In the article on how to fix the Docker “permission denied” error, we saw that we can use docker to easily set up pre-configured instances of applications so that we don’t have to know too much about setting it up and running it ourselves. Long-running applications like database servers and web servers that require complex configuration are excellent candidates for a docker application. But what if you need to connect to a docker server and perform some maintenance on it? Wouldn’t we need to SSH into the docker container first?
Well, no. A common misconception is that we need to use SSH to connect directly to a Docker container so we can run commands against it. While we certainly need to interact with the container, using SSH is a bad idea.
Why SSH’ing into a Docker Container is Unwise
Here are some reasons why we don’t need to SSH into a docker container.
A Docker Container Isn’t a VM
The most common misconception is that an instance of docker is like a Virtual Machine (VM), and that you need to use SSH to access that VM just like you would any other server. The truth is that a docker instance is more like an isolated process that’s meant to be ephemeral. They’re not meant to have persistent states like file systems unless specifically designed for that. So the way we interact with a docker instance is very different.
You Don’t Need to Run a Command “Inside” a Container
Another reason why you might think that you need to use SSH to connect to a docker instance is that you feel that you need to be “in” a container to run commands against it. In reality, you can use a command like:
docker exec -it <container_id> <command>
To run commands against the container specified by the ID. For example, I’m running the “ps aux” command against a particular container on my Ubuntu system:
In this example, I’m running a docker container with a long-running process – a server that listens on a specific port. I’m not “inside” the container at the moment. But if I want, I can run a command like this:
ps aux
This command shows me all the processes running inside the container without actually needing to go into it.
No Need to Connect Directly from Another Server
What if you want to access a docker container directly from another server? As seen above, you can run commands against a container on your server, but this obviously won’t work on another machine. Don’t you need SSH in that case?
Nope! Instead, you can simply SSH into the server containing the docker instance and then run commands against it as before. That’s more efficient than trying to set up an SSH server inside the container.
An SSH Service is Very Resource-Inefficient
Probably the most important reason for not trying to SSH into a docker container is that it’s an incredibly inefficient way to go about things. If you were to try and set it up, you’d need to create an SSH server on the container to begin with, create an SSH key or password, expose the port to the server, and then connect with credentials.
This whole process would be a huge waste of resources because the purpose of a docker application is simplicity and efficiency. Imagine having a constantly running server inside every docker application! It goes against the whole philosophy of docker in the first place.
Docker instances are meant to be quickly spun up and down with minimal configuration. Maintaining an SSH server like this defeats the purpose.
Most Docker Images Have Built-in Shells
We’ve seen that the purpose of docker is to containerize applications and allow them to be used across installations with minimum configuration requirements or experience required. However, this doesn’t mean that the container will have only the application and nothing else. Most docker containers, at least in the debugging phase, have other tools and at least a minimal shell included with them.
So, for example, the following command will execute the “sh” command inside a docker container that has shells:
docker exec -it 3301e55a5d9c sh
This opens the “sh” shell inside the container and allows us to execute commands against it like this:
As you can see, the command drops me into a stripped-down shell from which I can execute the commands that the creator of the container has included with the docker image. Not all commands will be available, and you’ll have to check and see which ones you can use.
You can see, though, that with a functionality like this, you don’t need to SSH into a docker container to run commands. With an in-built shell, you can go “into” it and run commands from there.
Containers without Shells
Not all docker containers have a shell included with them. Particularly those that are deployed in production often come with just the application and nothing else. This is because during the development and debugging phase, having a shell allows you to go into a container, see what’s happening, add and remove files, debug stuff, check logs, and more.
But once the development phase is done, many developers remove all other utilities, including the shell from the docker container. This has two benefits – first, it makes the container smaller and more efficient. The fewer things a container has in it, the more streamlined it becomes and the lesser the chances of something going wrong. The second reason for leaving a shell out of a docker container is to reduce security risks. With a shell, if the wrong person gains access, they can make any changes they want, including changing files. This way, they can’t execute any commands other than interacting with the application itself.
Executing Command Directly to Docker
For images without a shell, you still don’t need SSH to connect to a docker container. Instead, you can execute commands directly to the docker container using the “exec” keyword like this:
docker exec -it mydb mysql -u root -p
The above command assumes that you have a MySQL database set up as a docker container. Here’s what it looks like:
You can see that even though I haven’t SSH’d into the docker container, nor have I activated a shell, I’m still able to connect to the MySQL database inside the docker container by executing the “mysql” command inside it. The container then asks for the root password I set up when I created the container, then drops me into the mysql interface.
This container also happens to contain a shell. But if it didn’t, then you could fully interact with your databases even without requiring a shell. And if you want to connect from another remote machine, then it’s easier to SSH into the server containing the docker image and run commands against the container as shown above.
Conclusion
While docker containers run applications, there’s no need to explicitly SSH into them. A container isn’t a server, and even though many containers include a basic shell like sh, plenty of production-ready containers are bare and contain nothing but the application, so you wouldn’t be able to SSH to them like a regular server, anyway. Instead, docker has a rich suite of tools you can use to interact with containers, without ever requiring SSH.

I’m a NameHero team member, and an expert on WordPress and web hosting. I’ve been in this industry since 2008. I’ve also developed apps on Android and have written extensive tutorials on managing Linux servers. You can contact me on my website WP-Tweaks.com!
Leave a Reply