![](/img/trans.png)
[英]Passing environment variable to docker image at build time with docker-compose
[英]docker-compose build environment variable
TL;DR:如何在使用docker-compose
构建图像时传递 env 变量并让docker run image command
识别它们?
我有这个 Dockerfile :
FROM mhart/alpine-node:10
ADD . /app
WORKDIR /app
RUN apk --no-cache add --virtual builds-deps build-base python &&\
yarn global add nodemon &&\
yarn &&\
apk del builds-deps build-base python
和这个 docker-compose.yml :
version: "3.3"
services:
api:
build:
context: .
dockerfile: Dockerfile-preprod
image: registry.git.louis-girones.fr:4567/make-your-night/back:preprod
environment:
- NODE_ENV=development
env_file:
- .env
volumes:
- .:/app
ports:
- "${PORT_PREPROD}:${PORT_PREPROD}"
command: sh -c "mkdir -p dist && touch ./dist/app.js && yarn run start"
mongo:
image: mongo:4.0
ports:
- "${MONGO_PREPROD}"
command: mongod
volumes:
- ./data:/data/db
elasticsearch:
image: docker.elastic.co/elasticsearch/elasticsearch:6.1.1
volumes:
- ./esdata:/usr/share/elasticsearch/data
environment:
- bootstrap.memory_lock=true
- "ES_JAVA_OPTS=-Xms512m -Xmx512m"
- discovery.type=single-node
ports:
- "9300:9300"
- "9200:9200"
volumes:
esdata:
使用这个 .env 文件(位于根文件夹中,如 docker-compose.yml 和 Dockerfile):
#!/usr/bin/env bash
NODE_ENV=development
PORT=9000
SECRET_SESSION=superSecr3t
APP_NAME=Night Vision
API_VERSION=/api/v0/
DEFAULT_TZ=Europe/Paris
ASSETS_URI=http://localhost:9000/public/img/
BCRYPT_WORKFACTOR=1
ES_PORT=9200
ES_LOG_LEVEL=trace
而节点服务器启动中的这段代码:
// Export the config object based on the NODE_ENV
// ==============================================
const config: IConfig = commonConfig
if (commonConfig.env === 'development') {
_.merge(config, developmentConfig)
} else if (commonConfig.env === 'test') {
_.merge(config, testConfig)
} else if (commonConfig.env === 'preproduction') {
_.merge(config, preproductionConfig)
} else if (commonConfig.env === 'production') {
_.merge(config, productionConfig)
} else {
throw new Error('Please set an environment')
}
当我运行docker-compose build
命令时,一切都很好,但是例如如果我尝试docker run myimage yarn run test
会抛出错误“请设置环境”。
我希望
env_file:
- .env
使这个文件的 env 变量可以在我的图像中访问,但事实并非如此,这就是我尝试添加的原因
environment:
- NODE_ENV=development
但仍然没有成功,我还尝试在运行 build 时将我的 env 变量作为命令行参数传递:
docker-compose build --build-arg NODE_ENV=development api
但它给了我这样的信息:
[Warning] One or more build-args [NODE_ENV] were not consumed
Successfully built 9b14dd5abc3f
我真的更喜欢使用第一种或第二种方法
docker 版本:18.06.1-ce docker-compose 版本:1.19.0
文档中有一个注释:
注意:如果您的服务指定了构建选项,则在构建期间,环境中定义的变量不会自动显示。 使用build的args子选项来定义构建时环境变量。
它也在这里描述 。 首先(如上所述),您需要在Dockerfile中指定ARG
:
FROM mhart/alpine-node:10
ARG NODE_ENV
ENV NODE_ENV $NODE_ENV
ADD . /app
WORKDIR /app
RUN apk --no-cache add --virtual builds-deps build-base python &&\
yarn global add nodemon &&\
yarn &&\
apk del builds-deps build-base python
然后编辑您的docker-compose
文件以在构建期间包含参数,如下所示:
build:
context: .
dockerfile: Dockerfile-preprod
args:
- NODE_ENV=development
甚至
build:
context: .
dockerfile: Dockerfile-preprod
args:
- NODE_ENV=${NODE_ENV}
根据build args下的文档。
您可以在指定构建参数时省略该值,在这种情况下,它在构建时的值是 Compose 运行环境中的值。
args:
NODE_ENV:
此外,它将使用变量替换下记录的.env
文件。
您可以使用 Compose 自动查找的 .env 文件为环境变量设置默认值。 在 shell 环境中设置的值会覆盖在 .env 文件中设置的值。
所以你可以创建一个.env
文件,如下所示。
NODE_ENV=production
BASE_URL=/foo/bar/
然后只需在build.args
下的 compose 文件中列出它们以使其在build下可用,或者在environment
出它们以使其在run下可用。
version: '3.9'
services:
app:
build:
context: .
# these are available on build
args:
NODE_ENV:
# these are available on run
environment:
BASE_URL:
这有点有用。 然而,这种方法带来的问题是,如果变量不是从 shell 或 env 文件设置的,Dockerfile 中的默认值将被空值覆盖。
如果想要保留某种默认值,可以使用以下内容。
version: '3.9'
services:
app:
build:
context: .
args:
NODE_ENV: ${NODE_ENV:-dev}
environment:
BASE_URL: ${BASE_URL:-http://localhost:8080}
这是使用posix 参数扩展。 如果未设置变量,它将使用:-
之后的值。 所以在上面的例子中,如果没有设置,它会默认为 NODE_ENV=dev 和 BASE_URL=http://localhost:8080 。 允许使用.env
文件或通过设置 shell 变量覆盖它们,即export NODE_ENV=prod
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.