如何将docker-compose的环境/构建参数传递到Dockerfile的ENTRYPOINT命令?
问题原因
变量为空的核心原因是ARG和ENV的作用域差异:
ARG是仅构建阶段生效的变量,只在执行docker build过程中跑RUN等构建指令时存在,镜像构建完成、启动容器运行ENTRYPOINT时,所有ARG变量会被自动清除,运行阶段无法直接读取。ENV是会被固化到镜像元数据里的变量,容器运行阶段全程可以读取,是ENTRYPOINT/CMD能直接拿到的变量类型。
标准实现方案
方案1:构建参数转运行时环境变量(适合需要在构建+运行阶段共用变量值的场景)
只需要修改Dockerfile,在ARG声明后把值同步赋值给ENV即可,原有的ENTRYPOINT逻辑不需要改动:
# 声明构建参数,接收docker-compose build阶段传入的args值 ARG CURRENT_ENV # 关键步骤:将构建参数的值注入到运行时环境变量 ENV CURRENT_ENV=${CURRENT_ENV} # 原有ENTRYPOINT逻辑保持不变即可 ENTRYPOINT /bin/sh -c "rm -f /app/tmp/pids/*.pid && [[ $CURRENT_ENV = 'dev' ]] && /usr/local/rbenv/versions/`cat .ruby-version`/gemsets/my-project/bin/foreman start -f Procfile || /usr/local/rbenv/versions/`cat .ruby-version`/gemsets/my-project/bin/foreman start -f Procfile.hot; tail -f /dev/null"
这种方案下变量值会被固化到镜像中,如果是敏感信息不建议用这种方式。
方案2:直接传运行时环境变量(适合仅启动阶段需要用到变量的场景)
如果CURRENT_ENV不需要在镜像构建过程中使用,完全不用走build args传值,直接在docker-compose里配置运行时环境变量即可,ENTRYPOINT可以直接读取:
web: restart: "no" build: context: ../my-project # 直接配置容器运行时的环境变量,启动时ENTRYPOINT可直接读取 environment: CURRENT_ENV: "development"
这种方式的变量不会被固化到镜像里,同一个镜像换不同的environment配置就能跑不同环境,灵活性更高,也是日常开发最常用的方式。
额外注意
当前用的是shell格式的ENTRYPOINT(直接写命令字符串),会自动通过/bin/sh -c执行,变量可以正常被shell解析替换;如果后续改成exec格式的ENTRYPOINT(JSON数组写法),要注意不会自动启动shell做变量替换,需要显式写sh -c调用才能拿到变量值。
内容的提问来源于stack exchange,提问作者Dave
相关产品推荐
相关产品推荐

