Reputation: 1847
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.
Upvotes: 145
Views: 174259
Reputation: 374
Full working script built from the answer by WiRai above;
#!/bin/bash
container_name="nginx"
if [ "$(docker ps -q -f name=$container_name)" ]; then
echo "Container $container_name is running. It will be stopped ... "
docker stop $container_name
docker rm $container_name
else
echo "Container $container_name is not running."
if [ "!$(docker container inspect $container_name > /dev/null 2>&1)" ]; then
# cleanup
echo "removing stopped container $(docker rm $container_name)"
fi
fi
docker run $container_name
Upvotes: 0
Reputation: 7716
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 -a -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
Upvotes: 237
Reputation: 21
to skip Exited container:-
CONTAINER_NAME=xyz
if [ ! "$(docker ps -a | grep ${CONTAINER_NAME} | grep -v Exited)" ]; then echo "${CONTAINER_NAME} is not running"; else echo "${CONTAINER_NAME} is running"; fi
Upvotes: 1
Reputation: 359
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"
Upvotes: 1
Reputation: 16632
-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 $?
Ref: https://www.cyberciti.biz/faq/linux-bash-exit-status-set-exit-statusin-bash/
Upvotes: 2
Reputation: 1541
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
Upvotes: 0
Reputation: 4267
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).
Upvotes: 10
Reputation: 26682
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
Upvotes: 1
Reputation: 383040
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:
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.
Upvotes: 11
Reputation: 785276
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>
Upvotes: 41
Reputation: 13479
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.
Upvotes: 22
Reputation: 861
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.
Upvotes: 1
Reputation: 1664
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
Upvotes: 2
Reputation: 751
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.
Upvotes: 60
Reputation: 5039
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
Upvotes: 26