Docker is a widely adopted container technology. Nowadays, we can see a variety of applications running in containers. Just like other web applications deployed in other application servers, we can also interact with containerized applications. In such cases, we need to connect to a running container via the shell prompt. We often need to do this activity to debug application issues.
This tutorial will discuss how to attach and detach from a running Docker container.
1. Container Modes
We can run a Docker container in different modes: default, interactive, and detached. Let us understand them.
1.1. Default Mode
We can create a container using a container run child command. By default, it starts the container in the foreground. Additionally, it also attaches the host terminal with the container’s standard output(stdout) and standard error(stderr) streams.
$ docker container run --name web-server-01 nginx:alpine
This command starts an NGINX web server in a container. However, all the container output and error messages are displayed on the terminal only. It is important to note that in default mode we cannot return to the shell prompt till the container process is running. We can stop the container by pressing the CTRL + c key combination.
$ docker container ls -a --filter 'name=web-server-01'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
350e362d8d7f nginx:alpine "/docker-entrypoint.…" 29 minutes ago Exited (0) 7 seconds ago web-server-01
Here, we can see that the status of the container is Exited. It happens because the CTRL + c sends a SIGKILL signal to the container, which terminates the container.
1.2. Interactive Mode
Similarly, we can use the container run child command to start the container in an interactive mode using the -i and -t options:
- The -i option attaches the standard input stream(stdin) of the terminal to the container, and
- The -t option allocates a pseudo-terminal. This allows us to interact with the container from the terminal.
$ docker container run -it --name web-server-02 nginx:alpine sh
Let’s execute the hostname command in the container and exit from it:
/ # hostname
630b92379f37
/ # exit
Now, let’s check the status of the web-server-02 container:
$ docker container ls -a --filter 'name=web-server-02'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
630b92379f37 nginx:alpine "/docker-entrypoint.…" 3 minutes ago Exited (0) 2 seconds ago web-server-02
We can see that the container is in the Exited state.
1.3. Detached Mode
Docker allows us to run a container in the background, too, using the -d option.
$ docker container run -d --name web-server-03 -p 80:80 nginx:alpine
This command runs a container in the background, prints its id, and returns a shell. Note that we have used the -p option to publish a port in this example. This maps TCP port 80 in the container to port 80 on the Docker host.
Let’s verify it by checking the status of the container:
$ docker container ls -a --filter 'name=web-server-03'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
600fcaac734d nginx:alpine "/docker-entrypoint.…" 16 seconds ago Up 15 seconds 0.0.0.0:80->80/tcp, :::80->80/tcp web-server-03
This time we can see that the container is running in the background.
2. Interacting With a Running Container
Most of the time, containers are started in a detached mode. This runs a container in the background and returns a terminal to perform other tasks. However, sometimes we need to connect to a container to perform a few tasks.
Let’s see how to connect and interact with a running container.
2.1. Attach to a Running Container using 'docker attach'
We can use the docker attach child command to connect to a running container.
$ docker attach web-server-03
This command attaches local standard input, output, and error streams to the web-server-03 container. Now that, we have established a session with the container. So let’s verify that logs are visible on the terminal.
Now, from the web browser visit http://localhost/ URL and monitor the container logs. We can see the following log on the terminal:
172.17.0.1 - - [24/Sep/2022:08:55:43 +0000] "GET / HTTP/1.1" 304 0 "-" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/105.0.0.0 Safari/537.36" "-"
Finally, let’s exit from the container by pressing the CTRL + c key combination and check its status:
$ docker container ls -a --filter 'name=web-server-03'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
600fcaac734d nginx:alpine "/docker-entrypoint.…" 2 minutes ago Exited (0) 2 seconds ago web-server-03
Here, we can observe that the container goes into the Exited state due to the SIGKILL signal.
2.2. Execute Commands into a Running Container using ‘docker exec
‘
Sometimes, we need to execute commands in a container without attaching to it. It helps to interact with the container without affecting its running status. In such cases, we can use the docker exec child command.
For demo, first, let’s start a container in a detached mode using the -d
option as discussed earlier.
$ docker container run -d --name web-server-04 nginx:alpine
Now, we can execute any command in the container without connecting it using docker exec. For example, we are getting hostname in the following example. This command prints the hostname of the container and returns the shell immediately.
$ docker exec web-server-04 hostname
d19212022103
We can also use the -i and -t options with it to execute commands in an interactive way. Let’s create an interactive shell session with the container:
$ docker exec -it web-server-04 /bin/sh
Now, execute the hostname command and exit from it:
/ # hostname
d19212022103
/ # exit
Finally, check the status of the container:
$ docker container ls -a --filter 'name=web-server-04'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
d19212022103 nginx:alpine "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 80/tcp web-server-04
Here, we can see that the web-server-04 container is in a running state. Because earlier we created an interactive session with the shell, not the NGINX. The exit command terminated the shell session. Hence the state of the container does not get affected.
3. Detaching From a Running Container
In the earlier section, we saw how to attach and interact with a running container. Now, let’s see how to detach from the container without affecting its state.
The method to detach from the container depends on the mode in which the container is running. Let’s understand more about it with an example.
3.1. In Default Mode
In the first section, we saw that we can use the CTRL + c key combination to detach from the container. However, this sends a SIGKILL signal to the container. The side-effect of this is that the container goes into the Exited state instead of disconnecting the session.
We can override this default behavior using the –sig-proxy option that proxies all received signals to the container.
First, start the container in a default mode with the –sig-proxy option:
$ docker container run --name web-server-05 --sig-proxy=false nginx:alpine
Now, let’s detach from it by pressing CTRL + c key and check its status:
$ docker container ls -a --filter 'name=web-server-05'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
31345af4f3e6 nginx:alpine "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp web-server-05
Here, we can see that we are detached from the container without affecting its running state.
3.2. In Interactive Mode
Unlike the default mode, we cannot use the Ctrl + c key combination to detach from the container. Because it acts as a command to the current interactive session. In this mode, we have to use the combination of the Ctrl + p + q key as a detach key.
Let’s start the container in an interactive mode:
$ docker container run -it --name web-server-06 nginx:alpine sh
Now, detach from it by pressing the Ctrl + p + q keys and check its status:
$ docker container ls -a --filter 'name=web-server-06'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98b9587db45c nginx:alpine "/docker-entrypoint.…" 19 seconds ago Up 18 seconds 80/tcp web-server-06
In this example, the detach key combination just terminates the current interactive session and keeps the container in a running state.
3.3. In Detached Mode
Similar to the default mode, we can use the Ctrl + c key combination in this mode to detach from the container. However, there is a minor change. We must disable the –sig-proxy option while attaching to the container. Let’s understand this with an example.
First, start the container in a detached mode:
$ docker container run -d --name web-server-07 nginx:alpine
Now, let’s attach to it with –sig-proxy=false value and exit from it by pressing the ctrl + c keys:
$ docker container attach --sig-proxy=false web-server-07
Lastly, check the status of the container:
$ docker container ls -a --filter 'name=web-server-07'
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
9d1f6ef11373 nginx:alpine "/docker-entrypoint.…" About a minute ago Up About a minute 80/tcp web-server-07
Here, we can see that we are able to detach from the container without affecting its running state.
4. Conclusion
This Docker tutorial discussed different container modes and how to attach and detach from a running container. At first, we discussed the different modes of the containers. Then we saw how to attach and interact with the container. Finally, we discussed how to detach from the container without affecting its state.
Happy Learning !!
Leave a Reply