Docker From the Ground Up: Working With Containers, Part 2

This is part two of a two-part series about working with Docker containers. In part one, we focused on the many ways and options to run an image and how the host can interact with a Docker container. 

In this part, we'll cover listing, starting, stopping and restarting containers as well as executing commands on running containers. In particular, you'll learn the difference between running and stopped (exited) containers, and how to control precisely the information and display when you list your containers by filtering and formatting. 

Then, you'll get hands-on experience stopping, starting, restarting and attaching to your containers. Finally, you'll run one-off commands as well as gain interactive shell access to a running container. 

Before we start, make sure that Docker is installed properly in your environment. Depending on how it installed and your user, you may need to run it as sudo. I'll skip the sudo. 

Listing Containers

When working with containers, you often want to list, view and filter your containers. The docker ps command is the key, and it has several interesting options.

Running Containers

The most basic command is plain docker ps with no arguments, which shows all the currently running containers.

You get a lot of information on each container, including the container id, the image, the command, when it was created, its current status, its ports, and its names. It's a little difficult to parse due to the wrapping. We'll see later how to filter and format the output. Note that the command is truncated (as well as the container id). To show the full command, add --no-trunc:

Now, the full command is visible: nginx -g 'daemon off;'

All Containers

As you recall, Docker keeps stopped containers around (unless you ran them with --rm). Adding -a shows all containers:

Formatting

The output of docker ps can be too verbose and often shows a lot of fields that are not interesting. You can use Go-template formatting to display just the fields you're interested in. Here is showing just the name and the command:

That works, but to present it with the field names, add "table" to the beginning of the format string:

The format name for the container id (not selected here) is {{.ID}} (all caps).

Filtering

The docker ps command supports many filters. They are pretty straightforward to use. The syntax is -f "<filter>=<value>". Supported filters are id, label, name, exited, status, ancestor, before, since, isolation, network, and health.

Here is filtering by container name and showing only the busybox container:

The -q Flag

If all you want is the container id, use the -q flag (quiet flag). It's simpler than --format 'table {{.ID}}'. This is often needed when you want to perform operations on multiple containers (you'll see an example later).

Stopping, Starting, and Restarting Containers

You can stop running containers and start a stopped container. There are several differences between starting a stopped container and running a new instance of the same image:

  • You use the same environment variables, volumes, ports and other arguments of the original run command.
  • You don't have to create yet another container.
  • If the stopped instance modified its file system, the started container will use the same.

Let's stop the nginx container and then start it. When you refer to a container, you can use its name or an unambiguous prefix of its id. I usually name my long-running containers so I have a meaningful handle and don't have to deal with Docker's auto-generated names or containers' id prefixes.

OK. Nginx is stopped (status is "Exited"). Let's start it:

Restarting a running container is another option, which is equivalent to docker stop followed by docker start.

$ docker restart nginx

Attaching to a Running Container

When you start a stopped container, or if you ran your container in detached mode (-d command-line argument), you can't see the output. But you can attach to it.

Removing Containers

You can remove stopped containers with the command:  docker rm <container id or name>

If you want to remove a running container, you can either stop it first or use the -f (force) command-line argument:

If you want to remove all containers, here is a nice snippet:

docker rm -f $(docker ps -aq)

If you want to remove just the stopped container, remove the -f (force) flag.

Executing a Command Inside a Running Container

Docker runs a single process inside a container, but you can execute additional commands against a running container. It is very similar to providing a custom command to the docker run command, except that in this case it is running side by side with the run command.

Simple Commands

Running a simple command is done via docker exec. You provide a running container id or name and the command you wish to execute. Let's check out the nginx.conf file inside the nginx container and see how many worker processes are configured.

Interactive Shell

One of the best troubleshooting techniques with Docker containers is to connect to an interactive shell and just explore the internal file system. In order to attach stdin and have a tty, you need to provide the -i -t command-line arguments (can be grouped as -it) and then the name of a shell executable (usually bash). 

You end up with shell access to your container. Here is an example of checking the worker processes interactively from "inside" the container.

Conclusion

Docker is a powerful platform, and since the container is its unit of work, it provides a lot of tools to manage and work with containers. I described most of the important aspects of working with containers, but there are many more advanced features, options and nuances to the commands I covered, as well some additional commands. 

If you work closely with Docker containers, take the time to dive in and learn all about them. It will pay off handsomely.

Tags:

Comments

Related Articles