如何在Docker Compose中用镜像的环境变量设置另一个环境变量?
问题描述
我有如下docker-compose.yml文件:
version: "3.7" services: test-build: image: docker-hardened-ol8-openjdk17 command: tail -f /dev/null restart: always volumes: - "C:/checkouts:/opt/checkouts" ports: - 9001:9001 environment: - JAVA_17_HOME=${JAVA_HOME:?err}
docker-hardened-ol8-openjdk17镜像内置了Java 17及JAVA_HOME环境变量,我需要将容器内的JAVA_17_HOME设置为镜像中JAVA_HOME的取值,但执行docker compose up时,系统会读取我主机上的JAVA_HOME值。
查阅Docker官方文档时看到:
Compose使用docker-compose运行所在shell环境中的变量值。
请问是否有办法让docker-compose使用镜像的环境变量而非主机的?
解决方法
修改容器启动命令,在容器内部完成变量赋值
直接移除environment中的JAVA_17_HOME配置,修改command让容器启动时读取镜像内置的JAVA_HOME并赋值给JAVA_17_HOME:version: "3.7" services: test-build: image: docker-hardened-ol8-openjdk17 command: /bin/sh -c "export JAVA_17_HOME=$JAVA_HOME && tail -f /dev/null" restart: always volumes: - "C:/checkouts:/opt/checkouts" ports: - 9001:9001这种方式完全避开了Compose的主机环境变量插值,直接在容器内部使用镜像自带的环境变量。
自定义镜像启动脚本(更持久的方案)
如果需要长期使用这个配置,可以基于原镜像构建新镜像,在Dockerfile中添加变量赋值:FROM docker-hardened-ol8-openjdk17 ENV JAVA_17_HOME=$JAVA_HOME CMD ["tail", "-f", "/dev/null"]构建新镜像后,在
docker-compose.yml中使用这个新镜像,就不需要每次在命令里处理变量了。关键提示
你当前使用的${JAVA_HOME:?err}是Compose的变量插值语法,这种语法会强制读取主机shell的环境变量,所以要使用容器内的变量,就必须放弃这种插值方式,转而让容器内部处理变量逻辑。
内容的提问来源于stack exchange,提问作者Dinakaran S
相关产品推荐
相关产品推荐

