How to Connect to a running Docker Container

Sometimes you need to get down and dirty with your containers and that means connecting the container's terminal via Docker:

docker exec -it <container-id> bash

Let's break this down:

docker exec

Tell Docker we want to run a command in a running container.

-it

This is two separate switches on the exec command, combined for quick typing. It's the equivalent of -i and -t separately. -i tells Docker we want to have an interactive terminal and keep STDIN open even if not attached. -t tells Docker we want to start a TTY session.

<container-id>

Get this value from performing a docker ps on the command line to see your running container. It'll be in the Container ID column and if you can't see it then the container isn't running. You can't connect to containers that are stopped or dead, it needs to be running.

bash

This is the part where we actually get round to telling Docker what we want to execute in the container. In this instance we're asking for a bash shell. (Basically a command line).

bash, sh, ash

This is an important note that caught me out (as I'm quite new to Linux). Depending on the underlying version of Linux that your container is using you may need to swap out bash with sh, /bin/sh, /bin/ash or ash (for Alpine based images). This is because bash is an application like anything else and it might not be installed on the base Linux image. If you don't know what base image you're using then swap them around until it works.

Okay, I'm in.

If all goes well you should see a shell prompt like so:

/ #

And you'll be inside the container and able to do all sorts of Linux stuff, like ls -la

drwxr-xr-x    1 root     root          4096 May 29 22:24 .
drwxr-xr-x    1 root     root          4096 May 29 22:24 ..
-rwxr-xr-x    1 root     root             0 May 29 22:24 .dockerenv
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 bin
drwxr-xr-x    5 root     root           360 May 29 22:24 dev
drwxr-xr-x    1 root     root          4096 May 29 22:24 etc
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 home
drwxr-xr-x    5 root     root          4096 Jan  9 19:37 lib
drwxr-xr-x    5 root     root          4096 Jan  9 19:37 media
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 mnt
dr-xr-xr-x  131 root     root             0 May 29 22:24 proc
drwx------    1 root     root          4096 May 29 22:29 root
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 run
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 sbin
drwxr-xr-x    2 root     root          4096 Jan  9 19:37 srv
dr-xr-xr-x   13 root     root             0 May 29 22:24 sys
drwxrwxrwt    2 root     root          4096 Jan  9 19:37 tmp
drwxr-xr-x    7 root     root          4096 Jan  9 19:37 usr
drwxr-xr-x   11 root     root          4096 Jan  9 19:37 var

Awesome!

Installed applications

Docker images in general are designed to be very lightweight, so they might not have all the tools installed that you'd expect from a developer machine or workstation. Sometimes you need to install some apps to provide some extra functionality. The best way to do this is to check out the package manager for your distribution and install applications via that.

For example, creating a new Alpine container with docker run -it --rm alpine sh and attempting to run curl (A well known Linux application for making HTTP requests) we'll see that it isn't installed:

curl https://www.google.com
sh: curl: not found

Gah! Not a problem. We'll just update the registry and install it via apk the Alpine Package Manager.

apk update
apk add curl

Boom! Now we're ready to get curlin'...

curl https://www.google.com
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage"...

There we go, simples.

Troubleshooting

Input device is not a TTY

If you see an error along the lines of:

the input device is not a TTY. If you are using mintty, try prefixing the command with 'winpty'

Then you just need to stick winpty infront of the command so winpty docker exec -it <container-id> bash instead.

OCI runtime create failed

If you get something like this:

Error response from daemon: OCI runtime create failed: containe
r_linux.go:348: starting container process caused "exec: "C:/Program Files/Git/usr/bin/ash": stat C:/Program Files/Git
/usr/bin/ash: no such file or directory": unknown.

Then it means that your execution failed because it couldn't find the application and the container exited. This is most likely due to the base Linux image you're using not having the application (in this case bash) installed. Try some of the other variations above such as sh and ash.

Enjoy!