在NGINX docker容器中启动之前运行bash脚本

时间:2016-11-15 10:56:11

标签: javascript bash nginx docker dockerfile

我尝试使用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;"]

但码头工人的容器仍然关闭。我有什么遗失的吗?

5 个答案:

答案 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才会生效。