How to execute a Bash command only if a Docker con

2019-03-08 13:38发布

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 docker
8条回答
我只想做你的唯一
2楼-- · 2019-03-08 14:02

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
查看更多
Fickle 薄情
3楼-- · 2019-03-08 14:05

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.
查看更多
神经病院院长
4楼-- · 2019-03-08 14:06

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
查看更多
迷人小祖宗
5楼-- · 2019-03-08 14:10

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.

查看更多
孤傲高冷的网名
6楼-- · 2019-03-08 14:14

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
查看更多
Lonely孤独者°
7楼-- · 2019-03-08 14:20

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>
查看更多
登录 后发表回答