Docker构建Node.js镜像时传入的环境变量为空是什么原因
Docker构建传入的环境变量运行时值为空问题排查
问题复现配置
尝试将开发机本地环境变量传入运行Node.js应用的Docker容器,开发机环境为MacOS v11.6.7,相关配置如下:
- 开发机本地
mysql_address环境变量可正常读取:echo $mysql_address # 输出 192.168.1.10 - 镜像构建Shell脚本:
#!/bin/bash sudo docker build -t myapp --build-arg MYSQL_ADDRESS=$mysql_address . - 项目Dockerfile:
FROM alpine:latest ARG MYSQL_ADDRESS ENV mysql_address=$MYSQL_ADDRESS WORKDIR /app RUN apk add --no-cache npm COPY package.json ./ COPY myApp.js ./ RUN npm install --omit=dev CMD node /app/myapp.js - 应用入口
myApp.js仅打印运行时环境变量:console.log(process.env); - 容器运行命令:
sudo docker run -d --name myapp myapp:latest
运行后查看容器日志,发现容器内mysql_address值为空字符串:
{ ... mysql_address: '', ... }
根因分析
问题和Dockerfile的ARG/ENV写法无关,核心原因是sudo命令默认会重置执行上下文的环境变量:
构建脚本中用sudo执行docker命令时,当前普通用户shell中的$mysql_address变量不会被带入sudo启动的root权限进程中,导致--build-arg MYSQL_ADDRESS=$mysql_address实际展开为--build-arg MYSQL_ADDRESS=,也就是给构建参数传了空值,最终ENV设置的变量自然为空。
修复方案
任选一种方式即可解决:
- 给sudo添加
-E参数,强制继承当前用户的环境变量:
修改构建脚本为:#!/bin/bash sudo -E docker build -t myapp --build-arg MYSQL_ADDRESS=$mysql_address . - 去掉docker命令的sudo(推荐,长期使用更方便):
先执行一次命令将当前用户加入docker用户组,执行完成后重启终端生效,后续所有docker命令都不需要加sudo:
生效后构建脚本直接写为:sudo usermod -aG docker $USER#!/bin/bash docker build -t myapp --build-arg MYSQL_ADDRESS=$mysql_address .
修复后删除旧的镜像和容器,重新构建、运行,即可在日志中看到mysql_address正常显示为192.168.1.10。
内容的提问来源于stack exchange,提问作者Pierogi
相关产品推荐
相关产品推荐

