【发布时间】:2017-11-27 15:00:08
【问题描述】:
仅当 docker 容器尚未运行时,我才需要运行它。给出这个命令。如果它不存在,我将如何运行它。
docker run --name nginx -d nginx
我对任何脚本或语言持开放态度。
【问题讨论】:
仅当 docker 容器尚未运行时,我才需要运行它。给出这个命令。如果它不存在,我将如何运行它。
docker run --name nginx -d nginx
我对任何脚本或语言持开放态度。
【问题讨论】:
我肯定会建议调查 docker-compose 和 docker-compose up,如上所述。
由于您的问题是关于 docker run,我会像这样简化 VonC 的答案
docker start nginx || docker run --name nginx -d nginx
如果容器已经在运行,docker start 将返回0,因此不会执行docker run。如果容器存在但没有运行,docker start 将启动它,否则docker run 将创建并一次性启动它。
VonC 的回答中缺少“存在但已停止”部分。
【讨论】:
docker start nginx 2>/dev/null || docker run --name nginx -d nginx
使用过滤器检查某个名称的容器是否存在:
(见docker ps Filterring)
#!/bin/bash
name='nginx'
[[ $(docker ps -f "name=$name" --format '{{.Names}}') == $name ]] ||
docker run --name "$name" -d nginx
docker run 只有在第一部分为 false 时才会执行。
为了安全起见(docker ps 可能会返回多个名称),您也可以这样做(如果您认为“nginx”这个词不能是任何容器名称的一部分):
if ! docker ps --format '{{.Names}}' | grep -w nginx &> /dev/null; then
docker run --name nginx -d nginx
fi
或者:
if ! docker ps --format '{{.Names}}' | egrep '^nginx$' &> /dev/null; then
docker run --name nginx -d nginx
fi
【讨论】:
docker start || docker run 似乎是一个更可行的选择。
== $name 应该限制为完全容器名称。但我同意,Eugen Mayer 的回答也很好(并且赞成)
docker ps -f name=... 可能会返回不止一个名称(nginx\ns1_nginx... 或其他名称),因此使用if docker ps --format '{{.Names}}' | egrep '^nginx$' &> /dev/null; then ...; fi 似乎是一个更安全的选择。
grep -w "nginx"
如果您对任何语言持开放态度,我建议您使用 docker-compose 来完成此任务。安装后,使用以下内容创建一个名为 docker-compose.yml 的文件:
version: '2'
services:
nginx:
image: 'nginx'
然后使用:
docker-compose up -d
它会一直检查容器是否已经在运行。如果容器不存在,它将创建并运行。如果容器停止,它只是运行它。
最好的是,如果您更改 docker-compose.yml 或拉取新版本的映像,它将自动重新创建容器,保留所有卷,即使是未命名的卷。
问候
【讨论】:
如果目的是幂等性并且有问题的容器是可替代的(如您的示例中的情况),那么系统的当前状态(是否正在运行)并不重要。
在一张白纸上。
$ docker ps -a --format '{{.Names}}' | wc -l
0
在容器存在时执行强制删除和创建。
$ docker run --name=hello -d alpine sleep inf
0f6175804d69d48cdada66de57cb62c2855d1085c08a69f21e782c433be2c6a2
$ docker ps --format '{{.Names}}'
hello
$ docker rm -f hello ||:
hello
$ docker run --name=hello -d alpine sleep inf
...
和没有的时候完全一样。
$ docker ps -a --format '{{.Names}}' | wc -l
0
$ docker rm -f hello 2>/dev/null ||:
$ docker run --name=hello -d alpine sleep inf
d0210fefc7e934fea6d669615538596cf372f15e9095edae81c35965ff021898
执行条件检查时完全一样。
$ docker ps -a --format '{{.Names}}'
hello
$ if ! docker ps -a --format '{{.Names}}' | grep hello >/dev/null ;then
> docker run --name=hello -d alpine sleep inf
> fi
$ docker rm -f hello
hello
$ if ! docker ps -a --format '{{.Names}}' | grep hello >/dev/null ;then
> docker run --name=hello -d alpine sleep inf
> fi
1edcbba0c01979edbe05072bd3c15b6ecfb129d9e20d45a33eff0921cc5f2ed3
这使得 force-remove/create 成为幂等操作,而我们对状态、后操作的保证使条件变得毫无意义和笨拙。
如果你的容器必须观察一些底层状态,那么就忘记这一切吧。
【讨论】: