In this blog post, we'll look at how to get bash shell on a Docker container running in the background. It will also cover how to ssh into a docker container that was started and left running in the background without an active console session.
Docker adoption has been tremendous, especially in the world of microservices and development. Most Docker containers running for long periods of time don't have active shell console. You'll likely connect to bash shell on demand, i.e when you want to run some commands on the terminal. An alternative to this will be ssh to the container using an IP address.
Getting bash of a container running in the background can be achieved in two ways
1) Using docker exec command
Docker engine has a command line tool docker which is used to interact with containers. The command option execis used to run a command in a running container. By passing some parameters, we should be able to get bash session. The command syntax used is:
docker exec [OPTIONS] CONTAINER COMMAND [ARG...]
Below is a list of options which can be used with this.
-d, --detach Detached mode: run command in the background
-i, --interactive Keep STDIN open even if not attached
-t, --tty Allocate a pseudo-TTY
-u, --user string Username or UID (format: <name|uid>[:<group|gid>])
-w, --workdir string Working directory inside the container
Our interest is on the options -t and -i since bash has to run in an interactive mode. Let's consider an example to make this clear.
Pull Nginx Docker image:
# docker pull nginx
Using default tag: latestlatest: Pulling from library/nginx
f2aa67a397c4: Pull complete 3c091c23e29d: Pull complete 4a99993b8636: Pull complete
Digest: sha256:0edf702c890e9518b95b2da01286509cd437eb994b8d22460e40d72f6b79be49Status:
Downloaded newer image for nginx:latest
Start a test container in the background based on downloaded docker image.
# docker run --name nginx-bg -d nginx
3bd76e19ad6ce2ff15657ebf4de4cc42eb503c55f608071a438de6ca709ba73b
This will start a container named nginx-bg in the background from nginx docker image. Check to confirm that the container is running:
# docker ps
img
Now run the following command to get bash console on this container.
# docker exec -it nginx-bg /bin/bash
root@3bd76e19ad6c:/# apt-get update
Get:2 http://security.debian.org/debian-security stretch/updates InRelease [94.3 kB]
Ign:1 http://cdn-fastly.deb.debian.org/debian stretch InRelease
Get:3 http://cdn-fastly.deb.debian.org/debian stretch-updates InRelease [91.0 kB]
Hit:4 http://cdn-fastly.deb.debian.org/debian stretch Release
Fetched 185 kB in 2s (83.4 kB/s)
Reading package lists... Done
where nginx-bg is container name and /bin/bash is the path to bash binary on the container. Once done executing commands on bash shell, you can exit by typing exit command.
root@3bd76e19ad6c:/# exit
2) Using docker attach command
An alternative method to docker exec is docker attach. Syntax is
# docker attach <container-name>
So in our case, we'll run:
# docker attach nginx-bg
This should drop you into bash shell by default.
ssh into a running container
If you want to ssh to a running Docker container, you need container IP address or hostname configured on /etc/hosts or valid DNS record in your network.
If you don't know the IP address of the container, you can get it using the command below:
export INSTANCE_NAME="nginx-bg"
docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_NAME
Example:
# export INSTANCE_NAME="nginx-bg"
# docker inspect --format='{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $INSTANCE_NAME
172.17.0.7
Note that you can replace container name with its ID. We got the IP address to be 172.17.0.7, try ping it to see if responsive.
# ping -c 2 172.17.0.7
PING 172.17.0.7 (172.17.0.7) 56(84) bytes of data.
64 bytes from 172.17.0.7: icmp_seq=1 ttl=64 time=0.107 ms
64 bytes from 172.17.0.7: icmp_seq=2 ttl=64 time=0.058 ms
--- 172.17.0.7 ping statistics ---2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.058/0.082/0.107/0.026 ms
You need to have configured ssh on the container prior to running ssh command to it. Once configured, you can ssh to it using username and container's IP Address.
# ssh root@172.17.0.7
root@172.17.0.7's password:
Linux 672175da3a51 3.10.0-693.17.1.el7.x86_64 #1 SMP Thu Jan 25 20:13:58 UTC 2018 x86_64
The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.
Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
root@672175da3a51:~#
Passwordless SSH between containers
If you need passwordless authentication, consider copying your SSH public key to the container when running it. I don't recommend creating an image with the public key on it, but rather having the file on the host system that has all public keys authorized.
Let's create a file:
# mkdir ~/container-ssh-keys
# vim ~/container-ssh-keys/authorized_keys
# chmod 0600 ~/container-ssh-keys/authorized_keys
Then add your public SSH key to the file, you can add as many as you want. Now when starting the container, map this file to /root/.ssh/authorized_keys on the container, e.g
# docker run --name mycon -it -v $HOME/container-ssh-keys/authorized_keys:/root/.ssh/authorized_keys \
ubuntu:16.04 /bin/bash
You should then be able to ssh from your host system with the private key pair for the copied public key without being prompted for the password.
# ssh root@container-ip
Read also :
This marks the end of the guide. I hope this has been helpful and a good reference when working with Docker containers.