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

Solution 1:

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:

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:

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:

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:

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.