How to execute a Bash command only if a Docker container with a given name does not exist?

BashDocker

Bash Problem Overview


On a Jenkins machine I would like to create a docker container with a specified name only if it does not already exist (in a shell script). I thought I might run the command to create the container regardless and ignore the failure if there was one, but this causes my jenkins job to fail.

Hence, I would like to know how I can check if a docker container exists or not using bash.

Bash Solutions


Solution 1 - Bash

You can check for non-existence of a running container by grepping for a <name> and fire it up later on like this:

[ ! "$(docker ps -a | grep <name>)" ] && docker run -d --name <name> <image>

Better:

Make use of https://docs.docker.com/engine/reference/commandline/ps/ and check if an exited container blocks, so you can remove it first prior to run the container:

if [ ! "$(docker ps -q -f name=<name>)" ]; then
    if [ "$(docker ps -aq -f status=exited -f name=<name>)" ]; then
        # cleanup
        docker rm <name>
    fi
    # run your container
    docker run -d --name <name> my-docker-image
fi

Solution 2 - Bash

I suppose

docker container inspect <container-name> || docker run...

since docker container inspect call will set $? to 1 if container does not exist (cannot inspect) but to 0 if it does exist (this respects stopped containers). So the run command will just be called in case container does not exist as expected.

Solution 3 - Bash

You can use filter and format options for docker ps command to avoid piping with unix utilities like grep, awk etc.

name='nginx'

[[ $(docker ps --filter "name=^/$name$" --format '{{.Names}}') == $name ]] ||
docker run -d --name mynginx <nginx-image>

Solution 4 - Bash

Just prefix the name with ^/ and suffix with $. It seems that it is a regular expression:

CONTAINER_NAME='mycontainername'

CID=$(docker ps -q -f status=running -f name=^/${CONTAINER_NAME}$)
if [ ! "${CID}" ]; then
  echo "Container doesn't exist"
fi
unset CID

Solution 5 - Bash

Even shorter with docker top:

docker top <name> || docker run --name <name> <image>

docker top returns non-zero when there are no containers matching the name running, else it returns the pid, user, running time and command.

Solution 6 - Bash

Robust grep ^$ without undocumented behavior

This is the most precise and flexible approach I could find:

container_name=mycont
if sudo docker ps -a --format '{{.Names}}' | grep -Eq "^${container_name}\$"; then
  echo exists
else
  echo 'does not exist'
fi

Rationale:

  1. https://stackoverflow.com/a/38576401/895245 doesn't work if the container name is a substring in another container
  2. https://stackoverflow.com/a/45171589/895245 and https://stackoverflow.com/a/43202632/895245 rely on behaviors for which I could not find the documentation: the exit status of docker container inspect and that -f name takes regular expressions of some kind.

Python

A Python version for convenience since I ended up using it in a project:

containers = subprocess.check_output([
        'sudo',
        'docker',
        'ps',
        '-a',
        '--format', '{{.Names}}',
]).decode()
if container_name in containers.split():
    # Exists.

Solution 7 - Bash

This is my solution to check for a running container, stop it, then remove it.

CNAME=$CONTAINER_NAME-$CODE_VERSION
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

I've had to search this too many times because even the 100+ answer above doesn't actually work. I think the reason is a misunderstanding on docker ps. docker ps lists RUNNING containers. docker ps -q does the same but the output is striped to include only the container_id. docker ps -a lists ALL containers (running or not). docker ps -qa then is a simple list of all containers while docker ps -q is a simple list of running containers. docker ps -q -f name=ContainerName is then a simple list of running containers with the name ContainerName. docker ps -qa -f would include exited containers as well so the logic must be to check -a (there, running or not), then without -a to see if it's not only there, but running (and needs to be stopped first).

Solution 8 - Bash

I use following code to determine if docker container exists:

CONTAINER_NAME='my_docker_container'
# Checking if docker container with $CONTAINER_NAME name exists.
COUNT=$(docker ps -a | grep "$CONTAINER_NAME" | wc -l)
if (($COUNT > 0)); then
    echo 'container exists'
fi

Solution 9 - Bash

-a if you want to list all states (stopped, running etc.)
-f status=running (no need if you want to list only running containers)

$ docker ps -f name=containerName | grep containerName

If there is 1 or more lines status code of command will be 0. If there is no container, grep will be ended with 1 status code. You can handle it by:

Windows

$ echo %errorlevel%

Linux

$ echo $?

container is up and running

when container is stopped

see the properties of execSync Ref: https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/

Solution 10 - Bash

if [[ $(sudo docker inspect --format . <container-name>) == "." ]]; then
  docker run <container-name>;
fi

Explanation:

There is a similar response already. The difference here is the --format . option (you can also use -f .). This removes all the details from the inspect command. Docker uses the go template format, which in this case means that it will copy to the output anything it does not recognize.

So -f itIsThere will return itIsThere if a container with that namex exits. If it doesn't, docker will return an error code and message (Error: No such object: <container-name>).

I found this one in Jenkins logs.

Solution 11 - Bash

Piggy-backing off of @Fernando César.
This checks for the container id from the given container name and suppresses error output ( 2> /dev/null ).

CONTAINER_NAME="awesome-container"

CONTAINER_ID=$(docker inspect --format="{{.Id}}" ${CONTAINER_NAME} 2> /dev/null)
if [[ "${CONTAINER_ID}" ]]; then
  # container found.
else
  # container not found.
fi

Solution 12 - Bash

In bash script I check if container exists by name like this :

CONTAINER_NAME="my-container-name"
if ! docker container ls -a | grep -Fq "$CONTAINER_NAME" 1>/dev/null; then
echo "could not found container $CONTAINER_NAME..."
fi

Solution 13 - Bash

Here an example of a docker container existence check by exact name:

(docker ps -a --format {{.Names}} | grep container_name -w) && echo Exists || echo "Doesn't exist"

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
QuestionkshahView Question on Stackoverflow
Solution 1 - BashferdyView Answer on Stackoverflow
Solution 2 - BashWiRaiView Answer on Stackoverflow
Solution 3 - BashanubhavaView Answer on Stackoverflow
Solution 4 - BashyucerView Answer on Stackoverflow
Solution 5 - BashBlaiseView Answer on Stackoverflow
Solution 6 - BashCiro Santilli Путлер Капут 六四事View Answer on Stackoverflow
Solution 7 - BashrainabbaView Answer on Stackoverflow
Solution 8 - BashAliaksei ManiukView Answer on Stackoverflow
Solution 9 - Bashuzay95View Answer on Stackoverflow
Solution 10 - BashFernando CésarView Answer on Stackoverflow
Solution 11 - BashGollyJerView Answer on Stackoverflow
Solution 12 - BashNamig HajiyevView Answer on Stackoverflow
Solution 13 - BashGustavo DiasView Answer on Stackoverflow