第一次生成 Dockerfile,尝试用 dfimage 的方案提取 Dockerfile 的方案失败后,自己简单写出了这个 Dockerfile 模板,语法不再赘述,如果是简单的 Flask 应用,生成 requirements.txt,然后替换 COPY 部分后可以直接使用。
然后是 Gunicorn 和 Flask 的日志融合问题,尤其是访问日志的融合,别走弯路了。
文件代码:
# 基于 python3.7 构建
FROM python:3.7
# 应用代码根目录
WORKDIR /root/data_micro_services
# 安装依赖
# requirements.txt 来自于开发使用的虚拟环境: pip3 freeze > requirements.txt
COPY requirements.txt ./
RUN pip install --upgrade pip -i https://pypi.douban.com/simple
RUN pip install -r requirements.txt -i https://pypi.douban.com/simple
# 拷贝工程文件
COPY config.py ./
COPY app.py ./
COPY admin.py ./
COPY dao.py ./
COPY schemas.py ./
COPY bp_factory.py ./
COPY data_accessor.py ./
COPY task_executor.py ./
COPY tmpl/access_bp.py.tmpl ./tmpl/
COPY tmpl/api_bp.py.tmpl ./tmpl/
COPY tmpl/task_bp.py.tmpl ./tmpl/
# 为了创建空目录 bp_lib 和 user_lib,故意放了两个 demo 文件到目录里面
COPY bp_lib/bp_demo.py ./bp_lib/
COPY user_lib/task_demo.py ./user_lib/
# ENV LANG C.UTF-8
# 使用 gunicorn 运行 flask app,调试阶段可以注释掉这一行,使用 sleep infinity
# --log-level 和 --access-logfile 分别配置错误日志和访问日志的输出
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:8088", "--log-level", "debug", "--access-logfile", "-", "app:app"]
EXPOSE 8088
构建镜像:
docker build -t data_micro_services:0.6 .
调试镜像:
# 为避免 docker 容器内进程运行后直接失败退出,导致无法调试
# 通过 sleep infinity 让容器运行起来
docker run -d -p 8088:8088 data_micro_services:0.6 sleep infinity
docker exec -it -u root e9c4701a9ea5 /bin/bash
# 然后进入到容器内环境执行命令,修复所有的bug后,重新构建镜像即可
gunicorn -w 4 -b 0.0.0.0:8088 app:app
错误日志(error log)的融合: 添加以下代码后通过 gunicorn 的 --log-level 配置日志等级即可,但是这仅仅只是融合了[info/debug/error/critical]等日志
import logging
if __name__ != '__main__':
gunicorn_logger = logging.getLogger('gunicorn.error')
app.logger.handlers = gunicorn_logger.handlers
app.logger.setLevel(gunicorn_logger.level)
访问日志(access log): 下面这种格式的访问日志怎么打印到 Docker 的标准输出呢,其实很简单
172.17.0.1 - - [22/May/2022:12:27:07 +0000] "GET / HTTP/1.1" 404 36 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_16_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"
访问日志(access log)的融合: 很简单,使用 --access-logfile -
即可,看例子如下
gunicorn -w 4 -b 0.0.0.0:8088 --log-level debug --access-logfile - app:app