Docker镜像构建与docker-compose参数配置及ARG失效问题排查
解决Docker多阶段构建中ARG变量无法传递的问题
你遇到的核心问题是多阶段构建里的ARG变量没传递到目标构建阶段,导致ENV_BUILD为空,最终npm run build:${ENV_BUILD}变成了npm run build:,自然找不到对应的脚本而失败。
问题原因拆解
你在Dockerfile最顶部定义的ARG ENV_BUILD,只在当前构建阶段生效——而你紧接着用FROM node:lts-alpine as build-stage开启了全新的构建阶段,这个新阶段默认不会继承之前定义的ARG变量,所以在build-stage里${ENV_BUILD}是空值,也就出现了echo无输出、构建脚本找不到的问题。
具体解决方案
有两种简单的方式可以修复这个问题:
方式1:在目标阶段重新声明ARG
修改Dockerfile,在build-stage阶段开头重新声明ARG ENV_BUILD,这样就能接收构建时传入的参数了:
# 可选:设置全局默认值,后续阶段可继承 ARG ENV_BUILD=dev # étape de build FROM node:lts-alpine as build-stage WORKDIR /app/webapp-client # 重新声明ARG,继承全局默认值或构建时传入的值 ARG ENV_BUILD COPY ./webapp-client . RUN npm install RUN echo ${ENV_BUILD} RUN npm run build:${ENV_BUILD} # étape de production FROM nginx:stable-alpine as production-stage COPY --from=build-stage /app/webapp-client/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
方式2:在阶段内直接定义ARG并设置默认值
如果不想依赖全局ARG,也可以直接在build-stage里定义ARG并设置默认值:
# étape de build FROM node:lts-alpine as build-stage # 直接在阶段内定义ARG并设置默认值 ARG ENV_BUILD=dev WORKDIR /app/webapp-client COPY ./webapp-client . RUN npm install RUN echo ${ENV_BUILD} RUN npm run build:${ENV_BUILD} # étape de production FROM nginx:stable-alpine as production-stage COPY --from=build-stage /app/webapp-client/dist /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]
之后你原来的构建命令可以正常使用:
docker build --build-arg ENV_BUILD=dev -t client_dev_20200909_1208 -f webapp-client/Dockerfile .
额外注意事项
- 确认
package.json中确实存在build:dev脚本(从报错信息看是有的,不过可以再核对一下); - 你用
docker-compose启动时传递镜像标签的方式需要调整:--build-arg是给docker build用的,在docker-compose里传递环境变量直接在命令前设置即可:server=server_dev_20200909 client=client_dev_20200909 docker-compose up -d
内容的提问来源于stack exchange,提问作者hhézre
相关产品推荐
相关产品推荐

