Attach and Detach from a Docker Container

Narendra K

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 !!

Comments

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments

About Us

HowToDoInJava provides tutorials and how-to guides on Java and related technologies.

It also shares the best practices, algorithms & solutions and frequently asked interview questions.

Our Blogs

REST API Tutorial

Dark Mode

Dark Mode