Docker Compose容器命令与CLI执行环境变量不一致问题排查
问题诊断
你的问题根源在于lsiobase/rdesktop-web:alpine镜像使用s6-overlay作为初始化系统,它的默认启动流程会通过s6的机制加载容器环境变量。当你在docker-compose.yml中用command覆盖默认CMD时,相当于直接跳过s6初始化流程执行命令,此时容器的环境变量还没被注入到当前进程的环境中,所以printenv看不到REDIS_HOST;而你进入容器手动执行时,是在s6初始化完成后的shell环境里,环境变量已经被加载,因此能正常显示。
解决方案
针对这个问题,有两种可行的解决方式:
方法1:用s6提供的with-contenv命令执行你的程序
s6-overlay提供了with-contenv工具,它会先加载容器的所有环境变量,再执行指定命令。直接修改docker-compose.yml中的command即可:
version: "3" services: service: restart: unless-stopped build: context: . dockerfile: Dockerfile volumes: - ./config:/config # 用with-contenv包裹你的命令 command: /usr/bin/with-contenv printenv environment: - REDIS_HOST=some.host
如果是运行Python脚本,只需替换成:
command: /usr/bin/with-contenv python /path/to/your_script.py
方法2:通过s6服务配置启动程序(更符合lsiobase镜像的设计)
如果需要长期维护服务,可以通过Dockerfile配置s6服务,让程序纳入s6的管理流程:
FROM lsiobase/rdesktop-web:alpine AS base FROM base AS service # 创建自定义s6服务目录 RUN mkdir -p /etc/s6-overlay/s6-rc.d/my-python-service # 编写服务启动脚本(用with-contenv确保环境变量加载) RUN cat > /etc/s6-overlay/s6-rc.d/my-python-service/run <<EOF #!/usr/bin/with-contenv sh exec python /path/to/your_script.py EOF RUN chmod +x /etc/s6-overlay/s6-rc.d/my-python-service/run # 编写服务停止脚本(可选) RUN cat > /etc/s6-overlay/s6-rc.d/my-python-service/finish <<EOF #!/usr/bin/with-contenv sh echo "Python service stopped" EOF RUN chmod +x /etc/s6-overlay/s6-rc.d/my-python-service/finish # 将服务加入s6用户服务组,启动时自动运行 RUN mkdir -p /etc/s6-overlay/s6-rc.d/user/contents.d RUN ln -s /etc/s6-overlay/s6-rc.d/my-python-service /etc/s6-overlay/s6-rc.d/user/contents.d/my-python-service # 保留s6的默认启动命令 CMD ["/init"]
此时docker-compose.yml中可以移除command配置,启动容器后s6会自动初始化并运行你的Python脚本,环境变量会被正确注入。
验证步骤
- 先确认镜像中存在
with-contenv工具:
docker run --rm lsiobase/rdesktop-web:alpine which with-contenv
如果输出/usr/bin/with-contenv,说明工具可用。
- 执行
docker-compose up --build,观察printenv的输出是否包含REDIS_HOST=some.host,或者Python脚本是否能读取到环境变量。
内容的提问来源于stack exchange,提问作者Rafael Antonio Pólit
相关产品推荐
相关产品推荐

