Stop and delete Docker container if it's running

BashDockerContainers

Bash Problem Overview


I am looking to pragmatically stop and delete a Docker container if it is running. This is for a build script.

Take the following example. How would I stop and delete the Docker container "rabbitmq" as seen under the NAMES column in a bash script?

docker ps

CONTAINER ID        IMAGE             COMMAND                  CREATED             STATUS              PORTS                   NAMES
9909a5e2856f        rabbitmq-image   "/docker-entrypoint.s"   11 minutes ago      Up 11 minutes       0.0.0.0:5672->5672/tcp, rabbitmq
8990dd1fe503        redis-image      "/entrypoint.sh redis"   6 weeks ago         Up 4 days           0.0.0.0:32770->6379/tcp redis
etc 

The following command will delete the container and does what I'm looking to do

docker stop rabbitmq && docker rm -f rabbitmq

However, it's combing it into a script that I would like to know? I think it would look something like this.

#!/bin/bash

if [ /*docker ps check some value */ ]; then
   docker stop rabbitmq && docker rm -f rabbitmq
fi

Bash Solutions


Solution 1 - Bash

As you have probably noticed, docker stop as well as docker rm exit with a status code indicating failure if the container is not existent or not running. This results in your build failing.

If you can cope with the error messages in your build log you can do this little trick to prevent the shell command of failing:

docker stop rabbitmq || true && docker rm rabbitmq || true

In the case that one of the docker command fails, true is called which always exits with a status code indicating success.

Solution 2 - Bash

I have a similar problem, but didn't like the accepted answer as it suppresses all errors from the commands, rather than just the "not found" error.

However, docker ps -q --filter "name=rabbitmq" only produces output if a container of that name actually exists, so inspired by https://stackoverflow.com/questions/12137431/test-if-a-command-outputs-an-empty-string/25496589#25496589 I came up with:

docker ps -q --filter "name=rabbitmq" | grep -q . && docker stop rabbitmq && docker rm -fv rabbitmq

The following command is also useful for testing filter definitions:

docker ps -q --filter "name=rabbitmq" | grep -q . && echo Found || echo Not Found

My actual use case was in defining a pair of Ansible tasks that deleted all currently existing containers (whether running or not) from a list of names generated in an earlier task:

- name: Check for containers that actually exist
  shell: 'docker ps -aq --filter "name={{ item }}"'
  with_items:
    - '{{ previous_command.stdout_lines }}'
  register: found_containers

- name: Remove the containers found by the above command
  shell: 'docker stop {{ item.item }} && docker rm -fv {{ item.item }}'
  with_items: '{{ found_containers.results }}'
  when: item.stdout

Solution 3 - Bash

This is my preferred way to stop and remove a docker container. The piping of true is there to ensure that it always outputs a success. Without it, any bash scripts would exit and error if the container name did not exist.

docker rm -f container_name || true

Solution 4 - Bash

You can use:

app="rabbitmq"
if docker ps | awk -v app="$app" 'NR > 1 && $NF == app{ret=1; exit} END{exit !ret}'; then
  docker stop "$app" && docker rm -f "$app"
fi
  • awk command gets a command line var app from BASH's variable $app
  • NR>1 skips first header row from docker ps command.
  • $(NF) == app Compare last column NAMES is equal to app variable or not

Solution 5 - Bash

# Stop and remove containers with names like "rabbitmq" and "rabbitmq123" if they exist
CONTAINER_NAME="rabbitmq"
OLD="$(docker ps --all --quiet --filter=name="$CONTAINER_NAME")"
if [ -n "$OLD" ]; then
  docker stop $OLD && docker rm $OLD
fi

Solution 6 - Bash

I suggest this incantation in bash:

( docker stop $CONTAINER > /dev/null && echo Stopped container $CONTAINER && \
  docker rm $CONTAINER ) 2>/dev/null || true

It always exits with 0, doesn't complain if the container is not running, and prints Stopped container $CONTAINER if it actually got stopped.

Solution 7 - Bash

A general form based on some answers here:

docker rm -f container_name > /dev/null 2>&1 && echo 'removed container' || echo 'nothing to remove'

Solution 8 - Bash

Copy this code in your script.sh if you want stop and remove all

#!/bin/sh
ids=$(docker ps -a -q)
for id in $ids
do
  echo "$id"
  docker stop $id && docker rm $id
done

Solution 9 - Bash

Try below function. Adapted from https://stackoverflow.com/a/60579344/1554778

    function remove_previous_instance(){
        echo "Container name: $1"
        CNAME=$1
        if [ "$(docker ps -qa -f name=$CNAME)" ]; then
            echo ":: Found container - $CNAME"
            if [ "$(docker ps -q -f name=$CNAME)" ]; then
                echo ":: Stopping running container - $CNAME"
                docker stop $CNAME;
            fi
            echo ":: Removing stopped container - $CNAME"
            docker rm $CNAME;
        fi
    }

Call it: remove_previous_instance "CNAME"

Solution 10 - Bash

If you do not delete your stopped containers, another simple way to address this is to rely on docker ps -a, which will always return that container id. Then executing docker stop on that stopped container will idempotently simply do nothing:

docker stop $(docker ps -a --filter name= rabbitmq -q )    

Solution 11 - Bash

Easy way to do this issue

docker container ls -al | grep <name> && docker container rm -f <name>

Solution 12 - Bash

In the Below scenario:-

  1. Docker on windows(wsl2)
  2. Jenkins server on the same windows.
  3. Using Jenkins pipeline to build and run containers.
  4. Using bat script in the pipeline.

In this case, you can use the below command for preventing the build from failing.

'docker stop rabbitmq && docker rm rabbitmq || exit 0;'

Solution 13 - Bash

In a CI/CD pipeline or something that you don't need the output, the way I use is this:

docker rm -f rabbitmq &> /dev/null

but as I undertand &> is not part of the official POSIX spec so we shoud use:

docker rm -f rabbitmq 1> /dev/null 2>&1

-f (force) in docker rm -f:

> Force the removal of a running container (uses SIGKILL)

instead of docker stop that sends:

> .. SIGTERM, and after a grace period, SIGKILL

1> /dev/nul redirect the output 1 (stdout) to /dev/null and 2>&1 redirect the error 2 (stderr) to the same "file". & as the firs example redirect both 1 and 2.

To write a real file and append the content use docker rm -f rabbitmq 1>> docker_rabbitmq.txt 2>&1 or different files docker rm -f rabbitmq 1>> docker_rabbitmq_success.txt 2>> docker_rabbitmq_error.txt.

Solution 14 - Bash

to stop all containers first you have to stop all containers with

docker kill $(docker ps -q)

and to delete all containers

docker rm $(docker ps -a -q)

and if you want delete all images this is the command

docker rmi $(docker images -q)

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRobbo_UKView Question on Stackoverflow
Solution 1 - BashJohannes BaropView Answer on Stackoverflow
Solution 2 - BashncoghlanView Answer on Stackoverflow
Solution 3 - BashRobbo_UKView Answer on Stackoverflow
Solution 4 - BashanubhavaView Answer on Stackoverflow
Solution 5 - Bashiver56View Answer on Stackoverflow
Solution 6 - BashDS.View Answer on Stackoverflow
Solution 7 - BashChristoph SchranzView Answer on Stackoverflow
Solution 8 - BashAlex MontoyaView Answer on Stackoverflow
Solution 9 - BashVitalisView Answer on Stackoverflow
Solution 10 - BashSvendView Answer on Stackoverflow
Solution 11 - BashWillie ChengView Answer on Stackoverflow
Solution 12 - BashharryView Answer on Stackoverflow
Solution 13 - BashEmeeusView Answer on Stackoverflow
Solution 14 - BashGustavo Muñoz ValenzuelaView Answer on Stackoverflow