Docker容器中Python无法读取run传入的环境变量问题
Docker容器中sudo导致Python无法读取
docker run --env传入的环境变量 问题场景
使用python:3.12-alpine3.20镜像构建容器时,出现以下异常:
- 通过
docker run --env传入的自定义环境变量(如LOOP=10),在入口脚本中执行env命令能正常看到,但Python代码通过os.environ或os.system("env")无法读取。 - Dockerfile中用
ENV指令设置的变量(如TZ=Europe/Berlin),无论在脚本env输出还是Python中都能正常显示。
相关配置及启动命令如下:
Dockerfile
# This is the stage for the final image FROM python:3.12-alpine3.20 WORKDIR /src COPY ./python/src/ . COPY ./python/docker_entrypoint.sh / RUN apk add --no-cache sudo bluez tzdata ENV TZ=Europe/Berlin ENTRYPOINT sh /docker_entrypoint.sh
入口脚本docker_entrypoint.sh
#!/bin/sh python3.12 api_endpoints.py & sudo python3.12 main.py
容器启动命令
docker run --name=MY_CONTAINER --restart=on-failure --env LOOP=10 IMAGE:TAG
原因分析
问题核心是sudo的默认环境变量重置机制:
sudo默认启用env_reset配置,执行时会清除当前用户的大部分环境变量,仅保留env_keep列表中预设的少量变量(TZ这类系统级变量通常在默认保留范围内)。因此通过docker run --env传入的自定义变量会被sudo过滤,导致其启动的Python进程无法读取。
移除sudo调用后,Python进程直接继承容器的完整环境变量,因此能正常读取所有变量,验证了这一原因。
解决方案
方案1:避免使用sudo(优先推荐)
如果main.py的执行不需要root权限,直接删除sudo调用,让Python进程直接继承容器环境:
#!/bin/sh python3.12 api_endpoints.py & python3.12 main.py
方案2:保留环境变量执行sudo
如果必须以root权限运行main.py,可以通过以下方式让sudo保留当前环境变量:
- 使用
sudo -E参数,强制保留当前用户的环境变量(受sudoers配置限制):#!/bin/sh python3.12 api_endpoints.py & sudo -E python3.12 main.py - 或者修改sudoers配置,添加需要保留的自定义环境变量:
在Dockerfile中添加以下指令(用echo配合权限设置,避免语法错误):RUN echo 'Defaults env_keep += "LOOP"' >> /etc/sudoers.d/keep-env && \ chmod 440 /etc/sudoers.d/keep-env
临时替代方案
如果上述方案暂时无法实施,可以沿用临时方法:在入口脚本中将环境变量写入文件,再让Python读取加载:
#!/bin/sh env > /src/.env python3.12 api_endpoints.py & sudo python3.12 main.py
之后在Python代码中读取.env文件解析变量(可使用python-dotenv库或手动读取)。
内容的提问来源于stack exchange,提问作者DasMoorhuhn
相关产品推荐
相关产品推荐

