【Docker】Dockerfile ENV环境变量传递问题

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录


前言

这两天在给生产环境部署skywalking链路监控,发现配置好agent之后无法连到服务端,经过排查发现是docker启动容器时环境变量传递没有传递给应用,导致配置不对!

特此记录修复过程!

Dockerfile:

复制代码
# 基于 Alpine 镜像
FROM alpine:3.18.2

# 安装 bash,便于环境变量传递和使用
RUN apk add --no-cache bash

# 设置默认环境变量(可以被 -e 参数覆盖)
ENV MY_VAR=default_value
ENV MY_VAR2="insert var is ${MY_VAR}"

# 打印 MY_VAR2 的值
CMD echo $MY_VAR2

构建&启动:

复制代码
# 构建
docker build -t alpine-env-example .
# 启动
docker run -it -e MY_VAR=custom_value alpine-env-example

结果:环境变量并没有传递成功


提示:以下是本篇文章正文内容,下面案例可供参考

一、直接说结论

在 Dockerfile 中设置环境变量时,${MY_VAR}是在构建镜像时解析的,而不是在容器运行时解析的。因此,如果你在设置 【MY_VAR2】 的值时依赖于 ${MY_VAR},它会在镜像构建时解析并填充默认值。

具体原因如下:

ENV MY_VAR=default_value 会将 【MY_VAR】 设置为 default_value

然后,ENV MY_VAR2="insert var is ${MY_VAR}" 会在构建镜像时将 ${MY_VAR} 替换为 default_value,因为 【MY_VAR】 在构建时已经存在,所以 【MY_VAR2】 最终的值是 "insert var is default_value"

二、怎么解决这个问题

方案1. 不使用多级嵌套的变量

Dockerfile:

复制代码
FROM alpine:3.18.2
RUN apk add --no-cache bash
# 这里只使用1个变量
ENV MY_VAR=default_value
#ENV MY_VAR2="insert var is ${MY_VAR}"

CMD bash -c 'echo "insert var is $MY_VAR" && exec bash'

构建&启动:

复制代码
# 构建
docker build -t alpine-env-example .
# 启动
docker run -it -e MY_VAR=custom_value alpine-env-example

结果如下:成功传递变量

方案2. 使用 bash 在启动时动态解析环境变量

Dockerfile:

复制代码
FROM alpine:3.18.2
RUN apk add --no-cache bash
ENV MY_VAR=default_value
ENV MY_VAR2="insert var is ${MY_VAR}"

# 使用 bash 在启动时动态解析环境变量
CMD bash -c 'export MY_VAR2="insert var is ${MY_VAR}" && echo $MY_VAR2 && exec bash'  

构建&启动:

复制代码
# 构建
docker build -t alpine-env-example .
# 启动
docker run -it -e MY_VAR=custom_value alpine-env-example

结果如下:也能达到效果

相关推荐
JZC_xiaozhong19 小时前
数据不互通、审批慢?企业多系统智能协同与流程自动化解决方案
运维·自动化·流程管理·流程自动化·数据集成与应用集成·流程监控·流程可视化设计
爱学习的小囧19 小时前
ESXi 8.0 原生支持 NVMe 固态硬盘吗?VMD 配置详解教程
linux·运维·服务器·esxi·esxi8.0
坚持就完事了19 小时前
Linux中的变量
linux·运维·服务器
hERS EOUS19 小时前
nginx 代理 redis
运维·redis·nginx
Cat_Rocky20 小时前
利用Packet Tracer网络实验
linux·运维·服务器
嵌入式×边缘AI:打怪升级日志20 小时前
Linux 驱动实战:SR501 人体红外传感器驱动开发与调试全记录
linux·运维·驱动开发
正点原子20 小时前
【正点原子Linux连载】第三章 U-Boot使用 摘自【正点原子】ATK-DLRK3568嵌入式Linux驱动开发指南
linux·运维·驱动开发
忍冬行者20 小时前
MongoDB 三节点副本集离线部署运维手册
运维·数据库·mongodb
爱学习的小囧21 小时前
ESXi VMkernel 端口 MTU 最佳设置详解
运维·服务器·网络·php·虚拟化
eRTE XFUN21 小时前
docker 安装 mysql
mysql·adb·docker