Dockerfile中使用环境变量创建目录失败,原因是什么?
问题原因分析
你遇到的核心问题是Docker构建镜像的阶段和容器运行阶段的环境变量是完全隔离的,具体来说:
- Dockerfile里的
RUN命令是在构建镜像的时候执行的,这时候docker-compose.yml中environment字段定义的变量还没有被注入到构建环境里——environment是给容器启动后运行时用的。所以构建时$CUSTOM_PATH是空值,mkdir自然会报"missing operand"错误。 - 而容器启动后,
environment里的变量才会被加载到容器的运行环境中,这时候printenv能看到变量,手动执行mkdir也能成功,是因为此时变量已经存在了。
解决方案
要让构建阶段也能拿到这个自定义路径变量,需要用到Docker的ARG指令(专门用于构建阶段的参数传递),再结合docker-compose的build.args配置来传递.env里的变量。具体步骤如下:
1. 修改Dockerfile,添加构建参数
用ARG定义构建时的参数,再把它转为运行时的ENV变量(这样运行时也能继续使用这个变量):
FROM python:3.6.5 as my_base # 定义构建阶段可用的参数 ARG CUSTOM_PATH # 将构建参数转为容器运行时的环境变量(可选,但如果运行时需要用到这个变量的话建议保留) ENV CUSTOM_PATH=$CUSTOM_PATH # 现在构建阶段能正确获取到变量,mkdir命令正常执行 RUN mkdir $CUSTOM_PATH
2. 修改docker-compose.yml,传递构建参数
在build部分添加args字段,把.env里的CUSTOM_PATH传递到构建阶段:
services: my_service: build: context: ./Docker # 传递构建参数,从.env文件读取值 args: - CUSTOM_PATH=${CUSTOM_PATH} # 运行时环境变量(如果运行时不需要用到可以删掉,这里保留是为了和你原来的配置一致) environment: - CUSTOM_PATH=${CUSTOM_PATH}
3. 确保.env文件正确配置
你的.env文件需要明确定义CUSTOM_PATH的值,比如:
CUSTOM_PATH=/opt/my_custom_dir
额外说明
- 如果不需要在运行时保留这个变量,可以删掉
docker-compose.yml里的environment字段,只保留build.args即可。 - 如果你直接用
docker build命令构建镜像,也可以通过--build-arg参数直接传递,比如:docker build --build-arg CUSTOM_PATH=/opt/my_custom_dir ./Docker
内容的提问来源于stack exchange,提问作者user3535074
相关产品推荐
相关产品推荐

