use*_*mda 13 javascript environment-variables node.js docker
我的nodejs项目有以下文件
FROM node:boron
# Create app directory
RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
# Install app dependencies
COPY package.json /usr/src/app/
RUN npm install
# Bundle app source
COPY . /usr/src/app
# Replace with env variable
RUN envsubs < fil1 > file2
EXPOSE 8080
CMD [ "npm", "start" ]
Run Code Online (Sandbox Code Playgroud)
我使用-e标志运行docker容器,提供环境变量
但我没有看到替代品.当env变量可用时,Run ccommand是否会被执行?
Dan*_*owe 40
Dockerfile定义图像的构建过程.构建后,图像是不可变的(无法更改).运行时变量不会被烘焙到这个不可变图像中.所以Dockerfile是解决这个问题的错误地方.
您可能想要做的是ENTRYPOINT使用您自己的脚本覆盖默认值,并让该脚本对环境变量执行某些操作.由于入口点脚本将在运行时执行(当容器启动时),这是收集环境变量并对它们执行某些操作的正确时间.
首先,您需要调整Dockerfile以了解入口点脚本.虽然Dockerfile没有直接参与处理环境变量,但它仍然需要知道这个脚本,因为脚本将被烘焙到您的图像中.
Dockerfile:
COPY entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
CMD ["npm", "start"]
Run Code Online (Sandbox Code Playgroud)
现在,编写一个入口点脚本,在运行命令之前执行所需的任何设置,最后编写exec命令本身.
entrypoint.sh:
#!/bin/sh
# Where $ENVSUBS is whatever command you are looking to run
$ENVSUBS < fil1 > file2
npm install
# This will exec the CMD from your Dockerfile, i.e. "npm start"
exec "$@"
Run Code Online (Sandbox Code Playgroud)
在这里,我已经包括在内npm install,因为您在评论中询问了这一点.我会注意到这将npm install 在每次运行时运行.如果这是合适的,那很好,但我想指出它每次都会运行,这会给你的启动时间增加一些延迟.
现在重建您的图像,因此入口点脚本是它的一部分.
入口点脚本知道如何使用环境变量,但您仍然必须告诉Docker在运行时导入变量.您可以使用该-e标志docker run来执行此操作.
docker run -e "ENVSUBS=$ENVSUBS" <image_name>
Run Code Online (Sandbox Code Playgroud)
这里,Docker被告知定义一个环境变量ENVSUBS,它被赋值的值是$ENVSUBS当前shell环境的值.
我会详细说明一下,因为在评论中,看起来你对它如何组合起来有点模糊.
当Docker启动容器时,它会在容器内执行一个(也是唯一一个)命令.该命令变得PID 1,就像init或systemd典型的Linux系统上.此过程负责运行容器需要的任何其他进程.
默认情况下,ENTRYPOINT是/bin/sh -c.您可以在Dockerfile或docker-compose.yml中或使用docker命令覆盖它.
启动容器时,Docker会运行entrypoint命令,并将command(CMD)作为参数列表传递给它.早些时候,我们将自己定义ENTRYPOINT为/entrypoint.sh.这意味着在您的情况下,这是Docker在启动时将在容器中执行的内容:
/entrypoint.sh npm start
Run Code Online (Sandbox Code Playgroud)
因为["npm", "start"]被定义为命令,所以它作为参数列表传递给入口点脚本.
因为我们使用-e标志定义了一个环境变量,所以此入口点脚本(及其子项)将可以访问该环境变量.
在入口点脚本的末尾,我们运行exec "$@".因为$@扩展到传递给脚本的参数列表,所以这将运行
exec npm start
Run Code Online (Sandbox Code Playgroud)
并且因为exec将其参数作为命令运行,用自己替换当前进程,完成后,npm start在容器中变为PID 1.
在评论中,您询问是否可以定义多个CMD条目来运行多个内容.
您只能定义一个ENTRYPOINT和一个CMD.在构建过程中根本不使用它们.与RUN和不同COPY,它们不会在构建期间执行.它们在构建后作为元数据项添加到图像中.
只有在稍后,当图像作为容器运行时,才会读取这些元数据字段,并用于启动容器.
如前所述,入口点是真正运行的,它CMD作为参数列表传递.他们分开的原因部分是历史性的.在早期版本的Docker中,它CMD是唯一可用的选项,并且ENTRYPOINT已被修复为/bin/sh -c.但是由于像这样的情况,Docker最终允许ENTRYPOINT由用户定义.
| 归档时间: |
|
| 查看次数: |
16246 次 |
| 最近记录: |