如何在Nginx Unit Docker中输出WSGI应用日志至docker-compose?
解决Nginx Unit Docker中WSGI应用print内容不输出到docker-compose日志的问题
1. 禁用Python输出缓冲
Python在非交互式环境下会默认缓冲stdout,导致print内容无法实时输出到日志,可通过两种方式解决:
- 环境变量法:在docker-compose或Unit配置中添加
PYTHONUNBUFFERED=1环境变量,强制Python禁用输出缓冲。 - 代码强制刷新:在每个print语句后手动刷新标准输出:
import sys print('DURING INITIAL SETUP') sys.stdout.flush() def application(environ, start_response): print('DURING REQUEST') sys.stdout.flush() start_response('200 OK', [('Content-Type', 'text/plain')]) yield b'Hello, World!\n'
2. 配置Nginx Unit转发应用输出到容器stdout
官方Nginx Unit镜像默认会捕获应用的stdout/stderr,但需配置让其直接转发到容器标准输出,才能被docker-compose日志捕获。
示例docker-compose.yml配置
假设项目结构为:
project/ ├── app.py └── docker-compose.yml
docker-compose.yml内容:
version: '3.8' services: unit: image: nginx/unit:1.31.0-python3.11 ports: - "8000:8000" volumes: - ./app.py:/www/app.py environment: - PYTHONUNBUFFERED=1 command: > /bin/sh -c " unitd --no-daemon && curl -X PUT -d '{ \"listeners\": { \"*:8000\": { \"pass\": \"applications/wsgi_app\" } }, \"applications\": { \"wsgi_app\": { \"type\": \"python\", \"path\": \"/www\", \"module\": \"app\", \"processes\": { \"stdout\": \"/dev/stdout\", \"stderr\": \"/dev/stderr\" } } } }' http://localhost:8000/config"
核心是在applications.wsgi_app.processes中指定stdout和stderr为/dev/stdout、/dev/stderr,让Unit直接将应用输出转发到容器标准输出。
3. 避开权限陷阱
不要尝试写入/proc/1/fd/1,该文件属于root用户,而Unit默认以unit用户运行应用,无写入权限。通过上述配置,应用输出会通过Unit转发到stdout,无需直接操作该文件。
验证测试
启动容器后访问http://localhost:8000,然后查看日志:
docker-compose logs -f
此时你会看到DURING INITIAL SETUP(应用启动时输出)和DURING REQUEST(每次请求时输出)的内容出现在日志中。
内容的提问来源于stack exchange,提问作者hl037_
相关产品推荐
相关产品推荐

