docker-在命令数组中编写求值表达式
docker-compose evaluate expression in command array
我有以下 docker-compose.yml 文件。在 command
部分,我想在命令传递给 docker 引擎之前评估 curl
表达式,即我的卷曲应该首先评估,然后我的容器应该 运行 与-ip 10.0.0.2
选项。
version: '2'
services:
registrator:
image: gliderlabs/registrator:v7
container_name: registrator
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: ['-ip', '$$(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)']
然而,这没有被评估,我的选择被传递为 -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)
然而,相应的 docker 运行 命令正确地评估了表达式,我的容器正确地以 -ip 10.0.0.2
选项开始:
docker run -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:v7 -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)
命令行上的 docker 命令将起作用,因为该命令将由 shell 而不是 docker 图像执行,因此它将得到解决。
docker-compose command
将覆盖默认命令 (CMD)(请参阅 https://docs.docker.com/compose/compose-file/#command),因此它不会在容器启动之前执行,而是作为主要命令在容器中...
你可以这样做:
version: '2'
services:
registrator:
image: gliderlabs/registrator:v7
container_name: registrator
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: ['-ip', '${IP}']
和运行它与:
IP="$(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)" docker-compose up
这将在 shell 中再次 运行 并将其分配给一个名为 IP 的变量,将在 docker-compose up
命令期间可用。您可以将该命令放在 shell 脚本中以使其更容易。
在互联网上搜索了几个小时和此处发布的答案后,我最终选择了以下解决方案。为何如此有效的解释,请参考@Ivonet 的回答。
我在容器启动时将 Dockerfile
修改为 运行 脚本。
FROM gliderlabs/registrator:v7
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh && \
apk update && \
apk add curl
ENTRYPOINT ["/entrypoint.sh"]
脚本entrypoint.sh
也很简单。它首先检查它是否可以调用端点。成功响应会触发我的容器以正确的 IP 地址启动,而不成功的响应(用于本地测试)不会设置任何值。
#!/bin/sh
LOCAL_IP=$(curl -s --connect-timeout 3 169.254.169.254/latest/meta-data/local-ipv4)
if [ $? -eq 0 ]; then
/bin/registrator -ip $LOCAL_IP $@
else
/bin/registrator $@
fi
我有以下 docker-compose.yml 文件。在 command
部分,我想在命令传递给 docker 引擎之前评估 curl
表达式,即我的卷曲应该首先评估,然后我的容器应该 运行 与-ip 10.0.0.2
选项。
version: '2'
services:
registrator:
image: gliderlabs/registrator:v7
container_name: registrator
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: ['-ip', '$$(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)']
然而,这没有被评估,我的选择被传递为 -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)
然而,相应的 docker 运行 命令正确地评估了表达式,我的容器正确地以 -ip 10.0.0.2
选项开始:
docker run -v /var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:v7 -ip $(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)
命令行上的 docker 命令将起作用,因为该命令将由 shell 而不是 docker 图像执行,因此它将得到解决。
docker-compose command
将覆盖默认命令 (CMD)(请参阅 https://docs.docker.com/compose/compose-file/#command),因此它不会在容器启动之前执行,而是作为主要命令在容器中...
你可以这样做:
version: '2'
services:
registrator:
image: gliderlabs/registrator:v7
container_name: registrator
volumes:
- /var/run/docker.sock:/tmp/docker.sock
command: ['-ip', '${IP}']
和运行它与:
IP="$(curl -X GET -s http://169.254.169.254/latest/meta-data/local-ipv4)" docker-compose up
这将在 shell 中再次 运行 并将其分配给一个名为 IP 的变量,将在 docker-compose up
命令期间可用。您可以将该命令放在 shell 脚本中以使其更容易。
在互联网上搜索了几个小时和此处发布的答案后,我最终选择了以下解决方案。为何如此有效的解释,请参考@Ivonet 的回答。
我在容器启动时将 Dockerfile
修改为 运行 脚本。
FROM gliderlabs/registrator:v7
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh && \
apk update && \
apk add curl
ENTRYPOINT ["/entrypoint.sh"]
脚本entrypoint.sh
也很简单。它首先检查它是否可以调用端点。成功响应会触发我的容器以正确的 IP 地址启动,而不成功的响应(用于本地测试)不会设置任何值。
#!/bin/sh
LOCAL_IP=$(curl -s --connect-timeout 3 169.254.169.254/latest/meta-data/local-ipv4)
if [ $? -eq 0 ]; then
/bin/registrator -ip $LOCAL_IP $@
else
/bin/registrator $@
fi