Docker环境变量应在哪里声明?如何在应用中访问?
嘿,我之前也碰到过类似的坑!核心问题其实是Docker容器的环境变量是容器级隔离的——你在Nginx服务里定义的ENV=stage,只有Nginx进程和容器里直接跑的命令能拿到,但你的JS/PHP应用要么不在Nginx的运行上下文里,要么干脆在另一个容器里,自然读不到。下面分两种常见场景给你解决办法:
场景1:应用和Nginx在同一个容器里
如果你的PHP/Node.js是和Nginx打包在同一个容器里(比如一些简单的单容器部署),那得确保应用进程能继承容器的环境变量:
针对PHP应用
要是你用的是php-fpm和Nginx同容器,默认情况下php-fpm会清空环境变量,所以得改配置:
- 找到php-fpm的
www.conf(一般在/usr/local/etc/php-fpm.d/www.conf) - 把
clear_env = yes改成clear_env = no,这样php-fpm就会继承容器的环境变量,之后用$_ENV['ENV']或者getenv('ENV')就能拿到值了 - 或者更稳妥的方式,直接在
www.conf里加一行env[ENV] = $ENV,这样哪怕clear_env是yes也能传递这个变量
针对Node.js应用
如果是Node后端和Nginx同容器,只要Node进程是容器启动后直接运行的(不是打包好的静态前端),那process.env.ENV应该直接能读。但如果是静态前端应用(比如React/Vue打包后的文件),那得注意:浏览器是在容器外运行的,根本读不到Docker的环境变量!这种情况你得在构建前端的时候就把环境变量注入代码,比如用Vite的import.meta.env.VITE_ENV,或者Webpack的DefinePlugin,构建时跑ENV=stage npm run build就能把变量嵌进去。
场景2:应用在单独的容器里(推荐生产环境这么做)
正常生产环境都是把Nginx、PHP-FPM、Node分成不同容器的,这时候Nginx的环境变量和应用容器完全不互通,你得把变量直接声明在对应的应用服务里:
第一步:在docker-compose.yml里给应用服务加环境变量
比如你的PHP服务叫php-fpm,Node服务叫node-app,修改配置如下:
services: nginx: image: nginx:alpine # 这里的ENV是给Nginx自己用的(比如配置文件里的变量替换) environment: - ENV=stage php-fpm: image: php:fpm-alpine # 给PHP服务单独加环境变量 environment: - ENV=stage node-app: image: node:18-alpine # 给Node服务也加上 environment: - ENV=stage
这样每个应用容器自己的环境里就有ENV变量了,PHP用$_ENV['ENV']、Node用process.env.ENV就能正常读取。
进阶:用.env文件统一管理变量
如果变量多的话,重复写太麻烦,推荐用.env文件统一管理:
# .env文件内容 ENV=stage
然后在docker-compose.yml里引用这个文件的变量:
services: nginx: environment: - ENV=${ENV} php-fpm: environment: - ENV=${ENV} node-app: environment: - ENV=${ENV}
之后只要改.env文件,所有服务都会同步拿到最新的变量值,非常方便。
额外提醒
- 纯前端应用:再强调一遍,浏览器没法读Docker容器的环境变量,必须在构建阶段注入变量,别想着运行时读取了!
- Nginx配置里用变量:如果你是想在Nginx的conf文件里用
$ENV,那得在Nginx配置开头加env ENV;,然后用${ENV}引用,这和应用的环境变量是完全独立的两回事哦。
内容的提问来源于stack exchange,提问作者Cesar Martinez Dominguez

