docker镜像在构建基于gradio app的python代码时时遇到的日志不打印问题记录

1,039 阅读1分钟

趁热记录下,给未来的自己

前言

由于业务需要,需要将基于 gradio 的 python 代码,打包成 docker 镜像,然后交由 kubernetes 管理。

出现的问题是:本地直接跑 python 代码,日志可以打印,打包成 docker 镜像,用 docker run 启动或者交由 kubernetes 启动时,容器内不打印日志,退出程序时(ctrl+c)时,才会打印原来的日志。

问题原因

Python,会将打印的日志,根据日志级别,确定是先写到缓存里还是直接输出到终端。

  • sys.stdout.write() 会将日志先写入到缓存,当缓存满了,再统一输出到终端,
  • sys.stderr.write() 会直接将日志打印到终端上。

解决方案

强制关闭日志缓存即可, 运行时加上 -u 参数:

python -u app.py

针对本案例,可以修改Dockerfile

FROM xxx
WORKDIR /app
RUN pip install cmake && pip install dlib && pip install wget
RUN pip install gradio
#RUN mkdir -p src/data && mkdir -p src/work_dirs/experiments && mkdir src/work_dirs/pre-trained && mkdir -p src/user/input && mkdir -p src/user/output
ADD src ./src
ENTRYPOINT [ "python", "-u", "src/app.py" ]

也可以修改kubernetes的配置文件, 添加环境变量 PYTHONUNBUFFERED=1 或者 True 即可。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: app
  namespace: xxx
spec:
  selector:
    matchLabels:
      name: app
  replicas: 1
  template:
    metadata:
      labels:
        name: app
    spec:
      restartPolicy: Always
      hostNetwork: true
      terminationGracePeriodSeconds: 30
      containers:
        - name: app
          image: xxx
          env: # 添加环境变量 PYTHONUNBUFFERED=1 或者 True
            - name: PYTHONUNBUFFERED 
              value: "1"

参考

  1. docs.python.org/3/using/cmd…