Attaching To Containers Using the Attach Command
Tags: beginners, docker, devops, tutorial
Published: 2024-06-24 06:00:00

In the previous post, we discussed how to use the **docker exec** command to spin up a new shell session in a running container instance. The **docker exec** command is very useful for quickly gaining access to a containerized instance for debugging, troubleshooting, and understanding the context the container is running in.

However, Docker containers run as per the life of the primary process running inside the container. When this process exits, the container will stop. If you need to access the primary process inside the container directly (as opposed to a secondary shell session), then you can use the **docker attach** command to attach to the primary running process inside the container.

When using **docker attach**, you can gain access to the primary process running in the container. If this process is interactive, such as a Bash shell session, you will be able to execute commands directly through a **docker attach** session. However, if the primary process in the container terminates, so will the entire container instance, since the Docker container lifecycle is dependent on the running state of the primary process.

Let's use the **docker attach** command to directly access the primary process of an Ubuntu container, and investigate the main container **entrypoint** process directly. By default, the primary process of this container is **/bin/bash**.

Use the **docker run** command to start a new Ubuntu container instance. Run the container in interactive mode (**-i**), allocate a TTY session (**-t**), and run it in the background (**-d**). Let's call this container **ubuntu-attach**.
```powershell
docker run -itd --name ubuntu-attach ubuntu:latest
```
The output should be something similar to the following:
```
Unable to find image 'ubuntu:latest' locally
latest: Pulling from library/ubuntu
00d679a470c4: Pull complete
Digest: sha256:e3f92abc0967a6c19d0dfa2d55838833e947b9d74edbcb0113e48535ad4be12a
Status: Downloaded newer image for ubuntu:latest
cf16890cbe41d199260e23b7eafd864b244c142aad776135ce8d9bd80d161e9c
```
Now you should have a brand new Ubuntu container instance named **ubuntu-attach** using the latest version of the Ubuntu container image.

---
Use the **docker ps** command to check that this container is running in our environment:
```powershell
docker ps
```
The details of the running container instance will be displayed. Take not that the primary process of the container is a Bash shell (**/bin/bash**)
```
CONTAINER ID   IMAGE           COMMAND       CREATED         STATUS         PORTS     NAMES
cf16890cbe41   ubuntu:latest   "/bin/bash"   3 minutes ago   Up 3 minutes             ubuntu-attach
```
---
Run the **docker attach** command to attach to the primary process inside the container. To do that, use the **docker attach** followed by the name or id of the container instance:
```powershell
docker attach ubuntu-attach
```
This should drop you into the primary Bash shell session of this container image. Your terminal session should change to a root shell session, indicating you have successfully accessed the container instance:
```
root@cf16890cbe41:/#
```
If you use commands such as **exit** to terminate a shell session, then your container instance because you are now attached to the primary process of the container instance. By default, docker provides the <kbd>Ctrl</kbd>+<kbd>P</kbd> and <kbd>Ctrl</kbd>+<kbd>Q</kbd> key sequence to gracefully detach from an **attach** session.

Upon successful detachment of the container, the words **read escape sequence** should be displayed before returning to your main terminal session:
```powershell
root@cf16890cbe41:/# read escape sequence
```
---
Use the **docker ps** command to verify that the container is still running as expected:
```powershell
docker ps
```
You should be able to see the **ubuntu-attach** container:
```
CONTAINER ID   IMAGE           COMMAND       CREATED          STATUS          PORTS     NAMES
cf16890cbe41   ubuntu:latest   "/bin/bash"   50 minutes ago   Up 50 minutes             ubuntu-attach
```
---
Attach to the container once more:
```powershell
docker attach cf16890cbe41
```
---
Now, terminate the primary process of this container using the **exit** command.
```
root@cf16890cbe41:/# exit
```
The terminal session should have exited, returning you once more to your primary terminal.

---
Use the **docker ps** command to observe that the **ubuntu-attach** container should no longer be running:
```powershell
docker ps
```
This should return no running container instances:
```
CONTAINER ID   IMAGE     COMMAND   CREATED   STATUS    PORTS     NAMES
```
---
Use the **docker ps -a** command to view all the containers, even ones that have been stopped or have exited:
```powershell
docker ps -a
```
This should display the **ubuntu-attach** container in a stopped state:
```
CONTAINER ID   IMAGE                                                  COMMAND                  CREATED       STATUS                      PORTS     NAMES
cf16890cbe41   ubuntu:latest                                          "/bin/bash"              2 hours ago   Exited (0) 47 minutes ago             ubuntu-attach
```
As you can see, the container has gracefully terminated (**Exited (0)**) approximately 47 minutes ago. The **exit** command gracefully terminated the Bash shell session.

Now you can also use the **docker system prune -fa** command to clean up the stopped container instances:
```powershell
docker system prune -fa
```

## Summary
In this post, we used the docker attach command to gain direct access to the primary process of a running container. This differs from the `docker exec` command we explored earlier in the chapter because docker exec executes a new process inside a running container, whereas docker attach attaches to the main process of a container directly. Careful attention must be paid, however, when attaching to a container not to stop the container by terminating the main process. 

Although we have only scratched the surface of what Docker is capable of, I hope it was able to whet your appetite for the material that will be covered in the upcoming posts. In the next post, we will discuss building truly immutable containers using Dockerfiles and the docker build command. Writing custom Dockerfiles to build and deploy unique container images will demonstrate the power of running containerized applications at scale.