我有一个 dockerfile,其中有 Web 构建和 api 构建,并且我需要一个 Web 构建参数,需要稍后在运行时覆盖它。当我按照下面的方式执行时,它会覆盖,因为我看到 printenv 中运行时传递的新值,但当调用 url 时,它仍然显示旧的构建值。这是 Dockerfile:
# base
# ------------------------------------------------
FROM node:18-bookworm-slim as base
USER node
WORKDIR /home/node/app
RUN yarn install
# api build
# ------------------------------------------------
FROM base as api_build
RUN yarn prisma generate
# web build
# ------------------------------------------------
FROM base as web_build
# Add web environment variables here as args
ARG ENV1=val1
RUN yarn build web --no-prerender
# serve api
# ------------------------------------------------
FROM node:18-bookworm-slim as serve
#Add runtime envs here
ENV ENV1=${ENV1}
ENV NODE_ENV=production
USER node
WORKDIR /home/node/app
RUN yarn install
RUN yarn add api-server web-server
EXPOSE 8910
CMD ["sh", "-c", "node_modules/.bin/rw-server api & node_modules/.bin/rw-server web"]
我运行以下命令来在构建后运行图像 docker run -e ENV1="val2" -dt -p 8910:8910 镜像名
当我执行 docker exec 并检查 printenv 时,我可以看到更新的值,但是当我运行 webapp 并且 ENV1 值是重定向 url 时,它使用构建参数中的 val1 而不是环境变量中的 val2
我认为这里的问题是
ARG
变量在后续阶段不会自动可用。它们只能在定义的阶段内访问。如果您希望它在最后阶段起作用,那么您需要在那里复制它。
考虑这个
Dockerfile
的精简版本:
FROM node:18-bookworm-slim as base
# ------------------------------------------------
FROM base as api_build
# ------------------------------------------------
FROM base as web_build
ARG ENV1=val1
# ------------------------------------------------
FROM node:18-bookworm-slim as serve
ARG ENV1=val1
ENV ENV1=${ENV1}
CMD echo $ENV1
ARG
正在serve
阶段重新声明。
无需构建变量或环境变量即可构建并运行。
docker build -t arg-env . && docker run -it arg-env
ENV1
的值设置为ARG
中为Dockerfile
提供的默认值。
使用构建参数。
docker build --build-arg ENV1="val2" -t arg-env . && docker run -it arg-env
ENV1
的值现在在构建时设置。
在运行时指定环境变量。
docker build -t arg-env . && docker run -it -e ENV1=val3 arg-env
这将覆盖构建时间设置。无论是否指定
--build-arg
,您都会得到相同的结果,因为环境变量是在运行时使用 -e
设置的。