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:
Tell Docker we want to run a command in a running container.
This is two separate switches on the exec command, combined for quick typing. It's the equivalent of
-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.
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.
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
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
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
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:
sh: curl: not found
Gah! Not a problem. We'll just update the registry and install it via
apk the Alpine Package Manager.
apk add curl
Boom! Now we're ready to get curlin'...
<!doctype html><html itemscope="" itemtype="http://schema.org/WebPage"...
There we go, simples.
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