DockerDebugging a container

Syntax

  • docker stats [OPTIONS] [CONTAINER...]
  • docker logs [OPTIONS] CONTAINER
  • docker top [OPTIONS] CONTAINER [ps OPTIONS]

Entering in a running container

To execute operations in a container, use the docker exec command. Sometimes this is called "entering the container" as all commands are executed inside the container.

docker exec -it container_id bash

or

docker exec -it container_id /bin/sh

And now you have a shell in your running container. For example, list files in a directory and then leave the container:

docker exec container_id ls -la

You can use the -u flag to enter the container with a specific user, e.g. uid=1013, gid=1023.

docker exec -it -u 1013:1023 container_id ls -la

The uid and gid does not have to exist in the container but the command can result in errors.If you want to launch a container and immediately enter inside in order to check something, you can do

docker run...; docker exec -it $(docker ps -lq) bash

the command docker ps -lq outputs only the id of the last (the l in -lq) container started. (this supposes you have bash as interpreter available in your container, you may have sh or zsh or any other)

Monitoring resource usage

Inspecting system resource usage is an efficient way to find misbehaving applications. This example is an equivalent of the traditional top command for containers:

docker stats

To follow the stats of specific containers, list them on the command line:

docker stats 7786807d8084 7786807d8085

Docker stats displays the following information:

CONTAINER     CPU %   MEM USAGE / LIMIT   MEM %    NET I/O               BLOCK I/O
7786807d8084  0.65%   1.33 GB / 3.95 GB   33.67%   142.2 MB / 57.79 MB   46.32 MB / 0 B

By default docker stats displays the id of the containers, and this is not very helpful, if your prefer to display the names of the container, just do

docker stats $(docker ps --format '{{.Names}}')

Monitoring processes in a container

Inspecting system resource usage is an efficient way to narrow down a problem on a live running application. This example is an equivalent of the traditional ps command for containers.

docker top 7786807d8084

To filter of format the output, add ps options on the command line:

docker top 7786807d8084 faux

Or, to get the list of processes running as root, which is a potentially harmful practice:

docker top 7786807d8084 -u root

The docker top command proves especially useful when troubleshooting minimalistic containers without a shell or the ps command.

Attach to a running container

'Attaching to a container' is the act of starting a terminal session within the context that the container (and any programs therein) is running. This is primarily used for debugging purposes, but may also be needed if specific data needs to be passed to programs running within the container.

The attach command is utilized to do this. It has this syntax:

docker attach <container>

<container> can be either the container id or the container name. For instance:

docker attach c8a9cf1a1fa8

Or:

docker attach graceful_hopper

You may need to sudo the above commands, depending on your user and how docker is set up.

Note: Attach only allows a single shell session to be attached to a container at a time.

Warning: all keyboard input will be forwarded to the container. Hitting Ctrl-c will kill your container.

To detach from an attached container, successively hit Ctrl-p then Ctrl-q

To attach multiple shell sessions to a container, or simply as an alternative, you can use exec. Using the container id:

docker exec -i -t c8a9cf1a1fa8 /bin/bash

Using the container's name:

docker exec -i -t graceful_hopper /bin/bash

exec will run a program within a container, in this case /bin/bash (a shell, presumably one the container has). -i indicates an interactive session, while -t allocates a pseudo-TTY.

Note: Unlike attach, hitting Ctrl-c will only terminate the exec'd command when running interactively.

Printing the logs

Following the logs is the less intrusive way to debug a live running application. This example reproduces the behavior of the traditional tail -f some-application.log on container 7786807d8084.

docker logs --follow --tail 10 7786807d8084

This command basically shows the standard output of the container process (the process with pid 1).

If your logs do not natively include timestamping, you may add the --timestamps flag.

It is possible to look at the logs of a stopped container, either

  • start the failing container with docker run ... ; docker logs $(docker ps -lq)

  • find the container id or name with

docker ps -a

and then

docker logs container-id or

docker logs containername

as it is possible to look at the logs of a stopped container

Docker container process debugging

Docker is just a fancy way to run a process, not a virtual machine. Therefore, debugging a process "in a container" is also possible "on the host" by simply examining the running container process as a user with the appropriate permissions to inspect those processes on the host (e.g. root). For example, it's possible to list every "container process" on the host by running a simple ps as root:

sudo ps aux

Any currently running Docker containers will be listed in the output.

This can be useful during application development for debugging a process running in a container. As a user with appropriate permissions, typical debugging utilities can be used on the container process, such as strace, ltrace, gdb, etc.