Is it possible to ssh directly into docker container running on remote machine

Yes, it is possible to SSH directly into a Docker container running on a remote machine, but it is not the recommended or most common approach. The standard method is to first SSH into the remote host machine and then use the docker exec command to access the running container. 

The primary reason to avoid direct SSH is that it goes against Docker’s core philosophy of running a single, minimal service per container. Installing and running an SSH server increases the container’s size and complexity and expands its attack surface. 

Method 1: The standard approach (SSH to host, then docker exec)

This is the most common and safest method.

  1. SSH into the remote host: Use your terminal to connect to the machine where your container is running.shssh user@remote_host_ip Use code with caution.
  2. Find the container ID or name: Once connected to the host, list the running containers to find the one you want to access.shdocker ps Use code with caution.
  3. Execute a shell inside the container: Use docker exec to start an interactive shell session.shdocker exec -it <container_name_or_id> /bin/bash Use code with caution.
    • -i: Keeps STDIN open for an interactive session.
    • -t: Allocates a pseudo-terminal (TTY).
    • /bin/bash: Specifies the shell to use. For Alpine-based images, you might need to use /bin/sh

Method 2: The direct SSH approach (not recommended)

This method requires you to modify your container image to include and run an SSH server.

  1. Build a custom Docker image:
    • Create a Dockerfile that installs an OpenSSH server and sets a password or configures SSH keys.dockerfileFROM ubuntu:latest RUN apt-get update && apt-get install -y openssh-server RUN mkdir /var/run/sshd RUN echo 'root:your_password' | chpasswd <em># Or configure key-based auth</em> RUN sed -i 's/PermitRootLogin prohibit-password/PermitRootLogin yes/' /etc/ssh/sshd_config EXPOSE 22 CMD ["/usr/sbin/sshd", "-D"] Use code with caution.
    • Build the image:shdocker build -t custom-ssh-image . Use code with caution.
  2. Run the container and map the SSH port:
    • Start the container, mapping the container’s SSH port (22) to a port on the host machine (e.g., 2222). This is necessary to make the port accessible from outside the host.shdocker run -d -p 2222:22 --name my-ssh-container custom-ssh-image Use code with caution.
  3. SSH directly into the container:
    • From your local machine, you can now connect directly to the container via the remote host’s IP address and the mapped port.shssh -p 2222 root@remote_host_ip Use code with caution. 

Alternatives and best practices

  • Use Visual Studio Code’s Remote – SSH extension: This extension allows you to open a folder on a remote machine and work within a container from there, providing a seamless development experience.
  • Manage the Docker daemon remotely: For situations where you need to manage Docker on the remote machine, you can configure your local Docker CLI to connect directly to the remote Docker daemon using SSH. This involves using docker context to set up a new context pointing to the remote host.shdocker context create remote-host --docker "host=ssh://user@remote_host_ip" docker context use remote-host Use code with caution. 

Would ansible be another way?

Yes, Ansible is an excellent way to manage Docker containers on a remote machine, but it is primarily an automation tool, not an interactive shell. Instead of using Ansible to manually “SSH into” the container for a single session, you use it to run commands and perform tasks on the container non-interactively. 

Ansible leverages the remote machine’s existing SSH connection to issue Docker commands, such as docker exec, behind the scenes. This is a far more robust and repeatable approach than manually logging in. 

How Ansible manages remote Docker containers

Step 1: Set up the inventory

Your Ansible inventory file (e.g., inventory.yml) needs to list the remote machine as a host. This is the machine that Ansible will connect to via SSH. 

yaml

all:
  hosts:
    remote_host:
      ansible_host: 192.168.1.50
      ansible_user: your_username

Step 2: Use the community.docker collection

Ansible uses modules to perform tasks. The community.docker collection contains the modules needed to interact with Docker. You can install it with the following command: 

ansible-galaxy collection install community.docker

Step 3: Run ad-hoc commands with docker_container_exec

For simple, one-off tasks, you can use an ad-hoc command with the docker_container_exec module. This module uses the same functionality as the docker exec command. 

For example, to list the files in the /app directory of a container named my_container:

ansible remote_host -m community.docker.docker_container_exec -a 'container=my_container command="ls -lah /app"'

Step 4: Automate tasks with a playbook

For more complex or repeatable actions, create a playbook (execute.yml). This is the standard, best-practice way to use Ansible. 

yaml

---
- name: Execute a command inside a remote Docker container
  hosts: remote_host
  tasks:
    - name: Run a database migration command
      community.docker.docker_container_exec:
        container: my_database_container
        command: "/usr/local/bin/migrate.sh"
      register: migration_output

    - name: Display the migration output
      ansible.builtin.debug:
        var: migration_output.stdout

Ansible is for automation, not for interaction

While the docker_container_exec module can execute a command and return its output, it is not designed for interactive shells. For example, you cannot use Ansible to start a shell and then manually type commands. 

If you need a human-driven, interactive session, your best option remains:

  1. ssh your_username@remote_host
  2. docker exec -it my_container /bin/bash

Leave a Reply