Short tutorial teaching an essential skill for every DevOps engineer
Today, one of the most popular container technology is Docker, which is widely used for running all different kinds of applications.
An essential skill while working with Docker containers is knowing how to connect to a running container to modify data, debug, or execute commands.
Within this short article, I describe two different methods for connecting to a running Docker container.
The most helpful command for accessing a container through a shell is done by executing
docker exec -it.
This works because of the following:
docker exec runs a new command in a Docker environment
-i: Keep STDIN open even if not attached
-t: Allocate a pseudo-TTY
-t to enable interacting with the process
To test this, start a new test container with the following command:
docker run --name nginx --rm -p 8080:80 -d nginx
After the container starts successfully, you can execute the earlier explained command and add the container name
bash to execute a bash.
docker exec -it nginx bash# the shell will be opened as root user
You can exit the attached shell anytime by pressing
control + d or by typing
exit within the shell.
Often, if you are using Alpine Docker images
bash is not installed by default. You can either access the container by using a
docker exec -it nginx sh
Another approach is to create a new Dockerfile and add the following:
FROM nginx:alpineRUN apk update && apk add bash
Then you have to build and tag the image, as shown below:
docker build -t nginx-2
And then run it (use different name/ports)
docker run — name nginx2 — rm -p 81801:80 -d nginx-2
Afterward, you can attach to the container with
docker exec -it nginx bash
Sometimes, you will use containers that did not have any shell installed. Therefore, there is no way to get a shell in that container in a plain Docker environment. If you still want to have a shell, you should create a new container by creating a new Dockerfile and use it instead of the base image.
docker attachcommand attaches your terminal’s standard input, output, and error to a running container using the container’s
name. (Source docker.com)
This means that everything you enter in the opened shell is forwarded to the container and everything from the container will be shown in your console.
If you still have the earlier created container running, you can attach your console to it with this command:
docker attach nginx
If you did not touch the Nginx web server yet, you will not see any output in your console.
http://localhost:8080 in your browser and there will be some log generated by the Nginx. It should look like the following:
10.100.128.1 - - [26/Apr/2022:07:42:56 +0000] "GET / HTTP/1.1" 200 615 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36 OPR/85.0.4341.72" "-"2022/04/26 07:42:56 [error] 33#33: *2 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 10.100.128.1, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "localhost:8080", referrer: "http://localhost:8080/"10.100.128.1 - - [26/Apr/2022:07:42:56 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://localhost:8080/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/99.0.4844.84 Safari/537.36 OPR/85.0.4341.72" "-"
Normally, you would now press
control+c to detach from the window to start working in your shell again. As you used the
docker attach command here your input is forwarded to the container and pressing
control + c will also trigger a kill signal within the container that will be shut down.
10.100.128.1 - - [26/Apr/2022:07:46:35 +0000] [notice] 1#1: signal 2 (SIGINT) received, exiting10.100.128.1 - - [26/Apr/2022:07:46:35 +0000] [notice] 32#32: exiting
Detaching from an attached container can be tricky because
control + c is used for detaching and killing a container. To be able to detach without stopping a container you can disable forwarding signals while attaching the container.
First, start the container again because it was killed using this command:
docker run --name nginx --rm -p 8080:80 -d nginx
Then attach to the container again and disable forwarding signals.
docker attach --sig-proxy=false nginx
Now, you can detach the container with
control + c without killing it.
I hope you found this tutorial helpful and now know two different commands to connect to a container:
docker exec and
docker attach is very restrictive because it attaches your console and forwards the input to the container. Also, you cannot access files or operate within the container.
docker exec is more powerful and popular because you can run a new command that allows spawning a new shell. Then you can check processes, open or edit files, and operate within the shell as you do in your local environment.
Furthermore, you can use
docker exec to execute other commands. This is not restricted to use
sh. I will explain this in another article.
Also, if you have any questions, ideas, recommendations, or want to share cool Docker commands or tools, please jot them down below. I’ll try to answer your questions and test your recommendations.