我有这个Dockerfile
FROM node:14.17.1
ARG GITHUB_TOKEN
ARG REACT_APP_BASE_URL
ARG DATABASE_URL
ARG BASE_URL
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
ENV PATH /usr/src/app/node_modules/.bin:$PATH
ENV GITHUB_TOKEN=${GITHUB_TOKEN}
ENV REACT_APP_BASE_URL=${REACT_APP_BASE_URL}
ENV DATABASE_URL=${DATABASE_URL}
ENV BASE_URL=${BASE_URL}
ENV PORT 80
COPY . /usr/src/app
RUN npm install
RUN npm run build
EXPOSE 80
CMD ["npm", "start"]
但是我不喜欢设置每个环境变量。是否有可能使它们全部可用而不需要逐个设置?
在继续之前我们需要注意下面两点:
- 正如@Lukman在评论中提到的,
TOKEN
不是一个很好的项目来存储在图像中,除非你完全是内部使用,你决定。 - 即使我们没有在
Dockerfile
中逐一指定环境,我们仍然需要在其他地方定义它们,因为程序本身不可能知道你真正需要的环境是什么。
如果你对以上没有问题,我们继续吧。基本上,我认为在脚本中定义环境(这里,使用ENV1
,ENV2
为例),然后在容器中source
它们,并让app
有方法访问这些变量是你需要的。
env.sh:
export ENV1=1
export ENV2=2
app.js:
#!/usr/bin/env node
var env1 = process.env.ENV1;
var env2 = process.env.ENV2;
console.log(env1);
console.log(env2);
entrypoint.sh:
#!/bin/bash
source /usr/src/app/env.sh
exec node /usr/src/app/app.js
Dockerfile:
FROM node:14.17.1
WORKDIR /usr/src/app
COPY . /usr/src/app
RUN chmod -R 755 /usr/src/app
CMD ["/usr/src/app/entrypoint.sh"]
执行:
$ docker build -t abc:1 .
$ docker run --rm abc:1
1
2
解释:
我们将Dockerfile中的CMD
或ENTRYPOINT
更改为使用自定义的entrypoint.sh
,在此entrypoint.sh
中,我们将首先源代码env.sh
,使ENV1
和ENV2
对entrypoint.sh
的子进程可见。
然后,我们用exec
代替当前进程node app.js
,这样PID1
就变成了node app.js
,同时app.js
仍然可以得到env.sh
中定义的环境。
有了以上,我们不需要在Dockerfile
中逐一定义变量,但我们的应用程序仍然可以获得环境。
这里有一个不同的(简单的)方法。
从制作文件开始。在这里,我选择使用我的所有东西,这是混乱的,不推荐。这是一段有用的代码,所以我想我应该添加它。
env | sed 's/^/export /' > env.sh
编辑它,这样你只需要你需要的vi env.sh
使用下面的命令将文件导入容器。将pwd
更改为您想要共享的文件夹。不小心使用此选项可能会导致您共享多个文件*
sudo docker run -it -v `pwd`:`pwd` ubuntu
分配适当的文件权限。我使用777,这意味着任何人都可以读、写、执行——用于演示目的。但是你只需要执行权限。
运行此命令,并确保添加了句号。
. /LOCATION/env.sh
如果您对文件的位置感到困惑,只需在主机控制台中输入pwd
。你可以在适当的地方添加这些命令到你的Dockerfile来自动化这个过程。如果我没有记错,Dockerfile有一个VOLUME标志。