supervisor 启动的进程不读取 /etc/profile,需显式注入环境变量;优先将静态变量写入 /etc/environment,动态变量用 supervisor 的 environment 参数或 bash -c source /etc/profile 方式加载,并通过 /proc/pid/environ 验证。

Supervisor 启动的进程默认不读取 /etc/profile,因为它不是通过登录 shell 启动的,而是由 supervisord 直接 fork/exec 执行命令。要让被管理进程正确加载 /etc/profile 中定义的环境变量(如 PATH、JAVA_HOME 等),不能依赖 shell 自动加载,必须显式注入。
确认哪些变量真正需要被继承
先区分变量用途:/etc/profile 中的 export PATH=... 是动态拼接的,而 /etc/environment 中的变量是静态键值对、被所有进程(包括 systemd 服务)直接继承。若只需基础路径或语言设置(如 LANG),优先写入 /etc/environment——它无需 shell 解释,supervisor 进程天然可见。
-
/etc/environment适合:LANG、TZ、HOME、简单 PATH(如PATH="/usr/local/bin:/usr/bin") -
/etc/profile适合:需引用其他变量拼接的路径(如export PATH="/opt/myapp/bin:$PATH")、带命令替换的变量(如export APP_VERSION=$(cat /opt/myapp/VERSION))
在 Supervisor 配置中显式声明环境变量
Supervisor 的程序配置支持 environment 参数,可逐个指定变量,也能调用 shell 命令获取值。这是最可靠、最可控的方式。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 编辑
/etc/supervisor/conf.d/your-app.conf - 在
[program:xxx]段内添加:environment=PATH="/usr/local/myscripts:/usr/local/bin:/usr/bin:/bin",\ JAVA_HOME="/usr/lib/jvm/java-17",\ PYTHONPATH="/opt/myapp/lib" - 若需动态读取
/etc/profile中的逻辑,可用bash -c包裹启动命令:command=bash -c 'source /etc/profile && exec /usr/bin/python3 /opt/myapp/app.py'
避免用 user 指令间接触发 profile 加载
不要依赖 user=someuser 后让 supervisor 切换用户并自动加载其 ~/.bashrc 或 /etc/profile——supervisord 不会以登录 shell 方式切换,该行为不可靠且不生效。
-
user参数只控制进程运行 UID/GID,不启动 shell - 即使设置了
user,也不会执行su -l someuser -c cmd类操作 - 若确实需要完整用户环境,应明确使用
bash -l -c '...'(-l表示 login shell)
验证环境是否生效
配置更新后,务必验证实际进程看到的环境,而非仅检查 supervisord 自身:
- 重启程序:
supervisorctl reread && supervisorctl update && supervisorctl restart your-app - 查看进程环境:
cat /proc/$(pgrep -f "your-app")/environ | tr '\0' '\n' - 或在程序中打印
os.environ(Python)或printenv(shell 脚本)到日志 - 注意:
supervisorctl status显示的是 supervisor 内部状态,不反映子进程环境










