我尝试使用docker在localhost:8000上运行javascript应用。我想做的部分是基于docker run命令交换一些配置文件,我想将环境变量传递到容器中,以便bash脚本可以将其用作参数。
我的dockerfile看起来是这样的:
FROM nginx
COPY . /usr/share/nginx/html
CMD ["bash","/usr/share/nginx/html/runfile.sh"]
bash脚本如下所示:
#!/bin/bash
if [ "$SECURITY_VERSION" = "OPENAM" ]; then
sed -i -e 's/localhost/openam/g' authConfig.js
fi
docker run -p 8000:80 missioncontrol:latest -e SECURITY_VERSION="TEST"
Docker给了我一个例外,说找不到-e exec命令。
但是,如果我将dockerfile更改为使用ENTRYPOINT而不是CMD,则-e标志有效但Web服务器无法启动。
我有什么东西在这里失踪吗? ENTRYPOINT是否被覆盖?或者什么?
编辑:
所以我已经更新了我的dockerfile以使用ENTRYPOINT ["bash","/usr/share/nginx/html/runfile.sh", ";", " nginx -g daemon off;"]
但码头工人的容器仍然关闭。我有什么遗失的吗?
答案 0 :(得分:4)
NGINX 1.19在根目录上有一个文件夹const.Value
,放置由/docker-entrypoint.d
脚本执行的启动脚本。您还可以在日志中阅读执行情况。
/docker-entrypoint.sh:/docker-entrypoint.d/不为空,将 尝试执行配置
/docker-entrypoint.sh:在以下位置查找shell脚本 /docker-entrypoint.d /
/docker-entrypoint.sh:启动
[..........]
/docker-entrypoint.sh:配置完成;准备启动
答案 1 :(得分:1)
nginx容器已经定义了ENTRYPOINT。如果您同时定义CMD,它会将它们组合起来,如“ENTRYPOINT CMD'以这种方式,CMD成为ENTRYPOINT的参数。这就是为什么你需要重新定义ENTRYPOINT以使其正常工作。
通常ENTRYPOINT以这种方式定义,如果你也传递CMD,它将由ENTRYPOINT脚本执行。但是,每个容器都可能不是这种情况。
答案 2 :(得分:0)
我知道这已经晚了但我在寻找解决方案的过程中找到了这个帖子,以为我会分享。
我有同样的问题。您的ENTRYPOINT脚本还应包含exec "$@"
#!/bin/sh
set -e
envsubst '\$CORS_HOST \$UPSTREAM_CONTAINER \$UPSTREAM_PORT' < /srv/api/default.conf > /etc/nginx/conf.d/default.conf
exec "$@"
这意味着来自nginx:alpine
容器的启动CMD将运行。上面的脚本会将指定的环境变量注入配置文件中。通过在运行时执行此操作,您可以覆盖环境变量。
答案 3 :(得分:0)
对于我自己和其他人,这是您可以在启动时设置变量替换的方式(对于nginx,可能也适用于其他图像)
我还写了一篇更深入的博客文章:https://danielhabenicht.github.io/docker/angular/2019/02/06/angular-nginx-runtime-variables.html
Dockerfile:
FROM nginx
ENV TEST="Hello variable"
WORKDIR /etc/nginx
COPY ./substituteEnv.sh ./substituteEnv.sh
# Execute the subsitution script and pass the path of the file to replace
ENTRYPOINT ["./substituteEnv.sh", "/usr/share/nginx/html/index.html"]
CMD ["nginx", "-g", "daemon off;"]
subsitute.sh :(与@Daniel West的答案相同)
#!/bin/bash
if [[ -z $1 ]]; then
echo 'ERROR: No target file given.'
exit 1
fi
#Substitute all environment variables defined in the file given as argument
envsubst '\$TEST \$UPSTREAM_CONTAINER \$UPSTREAM_PORT' < $1 > $1
# Execute all other paramters
exec "${@:2}"
现在您可以运行docker run -e TEST="set at command line" -it <image_name>
捕获是WORKDIR
,如果没有捕获,nginx命令将不会执行。如果要将其应用于其他容器,请确保相应地设置WORKDIR
。
如果要递归地在多个文件中进行替换,这是您要查找的bash脚本:
# Substitutes all given environment variables
variables=( TEST )
if [[ -z $1 ]]; then
echo 'ERROR: No target file or directory given.'
exit 1
fi
for i in "${variables[@]}"
do
if [[ -z ${!i} ]]; then
echo 'ERROR: Variable "'$i'" not defined.'
exit 1
fi
echo $i ${!i} $1
# Variables to be replaced should have the format: ${TEST}
grep -rl $i $1 | xargs sed -i "s/\${$i}/${!i}/Ig"
done
exec "${@:2}"
答案 4 :(得分:0)
如下所示在您的dockerfile中更新CMD行。请注意,如果runfile.sh
不成功(其中的exit 0;
),则将不执行下一个nginx
命令。
FROM nginx
COPY . /usr/share/nginx/html
CMD /usr/share/nginx/html/runfile.sh && nginx -g 'daemon off;'
nginx docker file is using a CMD commnd以在您使用的基础映像上启动服务器。在dockerfile中使用CMD命令时,将覆盖其映像中的命令。正如dockerfile documentation所述:
在Dockerfile中只能有一条CMD指令。如果您列出多个CMD,则只有最后一个CMD才会生效。