How To Access A Docker Container — Secure Shell vs Docker Attach

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.

1. Attach to a running container using docker exec

The most helpful command for accessing a container through a shell is done by executing docker exec -it.

This is working because

docker exec runs a new command in a Docker environment

-i: Keep STDIN open even if not attached

-t: Allocate a pseudo-TTY

-it: Combines -i and -t to enable interacting with the process

To test this start a new test container with

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 nginx and bash to execute a bash.

docker exec -it nginx bash
# the shell will be opened as root user
root@b24af25732a2:/#

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 sh-shell:

docker exec -it nginx sh

Another approach will be to create a new Dockerfile and add:

FROM nginx:alpine
RUN apk update && apk add bash

Then you have to build and tag the image:

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 bash

docker exec -it nginx bash

Sometimes you will be using 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.

2. Attach to a running container using docker attach

The docker attach command attaches your terminal’s standard input, output, and error to a running container using the container’s id or 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:

docker attach nginx

If you did not touch the Nginx web server yet you will not see any output in your console.

Open http://localhost:8080 in your browser and there will be some log generated by the Nginx:

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", referre
r: "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, exiting
10.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:

docker run --name nginx --rm -p 8080:80  -d nginx

Now you can detach the container with control + c without killing it.

Conclusion

I hope you find this tutorial helpful and now know two different commands to connect to a container: docker exec and docker attach.

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 bash or 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 try to answer your question if possible and will test your recommendations.

Connect with me on Medium, Twitter, LinkedIn, and GitHub!