容器内读取环境变量的前提是变量已显式注入,因Docker不自动继承宿主机变量;需用docker exec env或printenv VAR_NAME验证是否生效,再通过各语言标准API(如Java的System.getenv、Python的os.getenv等)读取。
容器内读取环境变量,前提是变量已成功注入——docker 不会自动继承宿主机的环境变量,必须显式传递,之后才能在应用中访问。
确认变量是否真正进入容器
很多问题其实出在“以为传了,其实没传”。先验证变量是否生效:
- 运行
docker exec -it env查看全部环境变量,确认目标变量出现在输出中 - 用
docker exec -it printenv VAR_NAME单独查指定变量,返回为空说明未注入或拼写错误(注意大小写) - 若使用
docker-compose.yml,检查是否混淆了environment(运行时注入)和args(仅构建阶段有效)
不同语言中读取方式
变量注入后,各语言通过标准系统 API 获取,无需额外依赖:
-
Java:用
System.getenv("VAR_NAME"),建议配合非空校验,例如Objects.requireNonNull(System.getenv("DB_URL")) -
Python:用
os.getenv("VAR_NAME")或os.environ["VAR_NAME"](后者会抛异常,适合强依赖场景) -
Node.js:用
process.env.VAR_NAME,注意前端 React 应用需加REACT_APP_前缀且必须在构建时注入(不是运行时) -
Go:用
os.Getenv("VAR_NAME"),返回空字符串表示未设置,需自行判断是否可接受
特别注意前端应用(如 React/Vue)
浏览器端代码运行在用户设备上,与 Docker 容器完全隔离。所谓“容器中设置的环境变量”,对前端 JS 是不可见的:
- React 要求所有暴露给前端的变量必须以
REACT_APP_开头,且只能在npm run build构建时嵌入静态文件 - 正确做法是在
docker build阶段用--build-arg传参,再通过ARG+ENV写入镜像,最后在public/或构建脚本中替换占位符 - 不要试图在容器运行时用
process.env读取后端注入的变量——它根本不存在于浏览器进程里
调试常见陷阱
变量看似传了却读不到?重点排查这几个点:
-
ENTRYPOINT/CMD 启动方式:如果用了 shell 形式(如
sh -c "java -jar app.jar"),变量能被继承;但 exec 形式(["java", "-jar", "app.jar"])依赖进程自身加载,确保启动脚本没有重置环境 -
变量作用域时机:Dockerfile 中的
ENV在构建时固化,运行时-e注入的变量优先级更高,会覆盖同名ENV -
inspect 与 exec 环境不一致:用
docker inspect | jq '.[].Config.Env'看声明的变量,再用docker exec实际查,两者应一致;不一致说明启动命令或入口脚本干扰了环境


















