How to Kill All Containers in Docker

7 min read

In this post, we’re going to look at how to kill all containers in Docker. First, we’ll look at a one-liner using the CLI. Then, we’ll look at how to kill all containers using Docker Compose. Of course, you can also kill local containers via Docker Desktop. Underneath it all, these methods use the Docker Engine API, so we’ll look at that, too. Without further ado, let’s get started!

Kill All Docker Containers Using the CLI

Here’s a code snippet to kill all Docker containers using the CLI:

docker kill $(docker ps -q)

You could also use this snippet:

docker container kill $(docker container ls -q)

The two code snippets are equivalent. docker ps is an alias for docker container ls. And docker kill is an alias for docker container kill

Let’s break this down and see why it works.

The docker kill command takes one or more container IDs as its arguments. You can pass a list of container IDs or container names. Now we just need to get a list of containers together.

The docker ps command lists all running containers. However, it first prints a line of column headers followed by a line for each container. The output has several columns beside the list of containers we need to pass to the docker kill command. This is where the -q (--quiet) option comes in. With this flag, docker ps prints only the container IDs. This is what we need!

Sure, passing only the output of docker ps will kill all the containers, but it’ll also cause a bunch of errors, too. We could 2>/dev/null, but then we’ll miss out from logging important errors if they do occur. And speaking of errors…

What happens if there are no running containers? Let's try it:

docker kill $(docker ps -q) 2>/dev/null && echo $?
1

(Note: $? holds the last exit code.)

That’s not good! We actually wouldn’t want to run the kill command unless we have containers. So, what do we do?

Let’s Make It Safe to Automate

To make the one-liner above more safe to automate—that is, not return errors for valid states—we want to skip docker kill when there are no containers. Here, we'll set the container IDs to a variable:

containers=$(docker ps -q)
docker kill $containers

Now we can test for containers before we kill them. This is how:

containers=$(docker ps -q)
if [ ! -z $containers ]; then
  docker kill $containers;
fi

Or, on a more modern bash system, you can use this one-liner:

c=$(docker ps -q) && [[ $c ]] && docker kill $c

Provided that you started the containers with --rm, you’ll also remove the container once it’s stopped. Otherwise, you’ll be able to restart the container—but restarting a stopped container is another story. Just keep this in mind: If you don't remove them, the stopped container images still take up storage space.

Example

Now let’s go through an example to see it in action. Play along at home!  First, we’ll run three containers.

docker run -dit alpine
docker run -dit alpine
docker run -dit alpine

Next, we’ll list all the running containers:

docker ps

And now, we’ll kill one of the containers:

docker kill 03u3r903r09u3r09u

Finally, let’s use these two powerful commands to kill all the containers:

docker kill $(docker ps -q)

And now, bring three containers up once again and run the one-liner:

c=$(docker ps -q) && [[ $c ]] && docker kill $c

This should have killed all the containers. Run it again and see that it exits with no error (echo $? to verify). If you need a whole set of containers for an app, there's an easier way to bring them up and down: docker-compose.

Kill All Containers Using Docker Compose

Granted, there are plenty of times when you'll run containers directly using the CLI. However, for the sake of providing additional info to the uninitiated, you could have Docker Compose manage all your containers. If you do, killing multiple containers takes one command: docker-compose down.

First, a simple docker-compose.yml file with the following:

version: "3.3"
services:
  one:
    image: alpine
    tty: true
  two:
    image: alpine
    tty: true
  three:
    image: alpine
    tty: true 

Then run docker-compose up in detached mode:

docker-compose up -d

You could also run docker-compose without detached mode. If so, you’ll just use ^C to kill all containers.

Now, to kill all containers simply use docker-compose down:

docker-compose down

And there you have it—all containers killed!

There are other benefits of using docker-compose besides easily bringing containers up and down. For example, you can create a whole network of containers with various components needed to run an application.

Let's look now at another possibility: Docker Desktop.

Docker Desktop

Docker Desktop is a GUI used to manage Docker in a desktop environment. You could always restart the dockerd service, which would kill all containers as well. Using restart in Docker Desktop is essentially the same as restarting the dockerd service. There’s an item in the GUI menu to restart. It takes three simple steps (or one keyboard shortcut) to accomplish this.

1. Open Docker Desktop menu.

2. Click “restart”.

3. Confirm.

As you can see, all the running containers will be stopped. This isn’t the same thing as issuing a kill command to all running containers, but it will essentially accomplish the same. And you could, of course, go through each container and stop them one at a time.

Docker Engine API

While we're at it, why not go directly after the Docker engine API itself? After all, each of the methods above is essentially calling this API. Well, other than cycling the dockerd service, that is.

The Docker engine exposes an HTTP API. Theoretically, you could build your own app to kill all containers by calling two endpoints. First, we need to list the containers. Next, we need to issue a kill command to each container.

The list containers query is as follows:

GET /containers/json

And the kill endpoint:

POST /containers/{id}/kill[?signal=]

Now, if you’re using JavaScript, you can create a function to kill all containers:

const killAllContainers = ( server, port=2376 ) => {
  const urlRoot = `https://{server}:{port}`
  fetch( `{urlRoot}/containers/json` )
    .then( response => response.json() )
    .then( containers => containers.map( async container => 
      await fetch( `{urlRoot}/containers/{container.Id}/kill`, { method: ‘POST’  } )
    .catch(console.error)
    )
    .catch(console.error)
}

This is just an example using JavaScript; the possibilities are endless. You could even use cURL to kill all containers at this point.

Signals and Other Options

There’s always a chance that things will get screwed up when doing a kill. And, just like kill on Linux systems, the Docker kill command has the option to send different signals to the process. You can tell it to die without regard to what’s currently running or to attempt to terminate gracefully.

The default signal is KILL but you can send other signals to the container as needed. Some commonly used signals are HUP (1), INT (2), QUIT (3), KILL (9), and TERM (15). Just remember, with Docker kill, the command along with the signal is sent to the running container, not any process within, or even the entrypoint process. Commonly, you’ll only need to send the kill command with the default signal (KILL).

There are several options to kill all running containers. Just ask yourself first, is this actually what I want to do? Or do I really want to kill a process running in the containers? If you need to send a kill signal to something inside each container, you’ll need a different set of commands. You can still use docker ps -q in conjunction with something like docker exec to do something like pkill to kill all processes with a specific name.

Conclusion

Generally, you’ll want to kill all containers from the command line. Otherwise, you can choose from any other option above. This article did not cover Kubernetes, but of course that’s an option as well. Plus, there are many other ways to manage Docker containers. Each of those will have their own ways of killing all containers, and we couldn’t get around to covering all possible container management solutions. Still, hopefully this article provided enough insights to help you determine the best option for your situation.

This post was written by Phil Vuollet. Phil leads software engineers on the path to high levels of productivity. He writes about topics relevant to technology and business, occasionally gives talks on the same topics, and is a family man who enjoys playing soccer and board games with his children.

Stay up to date

We'll never share your email address and you can opt out at any time, we promise.