gunicorn Flask 应用程序在 Docker 中挂起

Posted

技术标签:

【中文标题】gunicorn Flask 应用程序在 Docker 中挂起【英文标题】:gunicorn Flask application hangs in Docker 【发布时间】:2021-08-29 02:32:59 【问题描述】:

我有一个 Flask 应用程序,我通过 gunicorn 运行(在装有 Ubuntu 20.04 的戴尔 latitude 5410 笔记本电脑上)并且我配置了 Docker 以按照 this wonderful guide 中的建议运行它。

这是我的boot.sh

#!/bin/sh
source venv/bin/activate
while true; do
    flask db init
    flask db migrate
    flask db upgrade
    if [[ "$?" == "0" ]]; then
        break
    fi
    echo Deploy command failed, retrying in 5 secs...
    sleep 5
done
exec gunicorn -b 0.0.0.0:5000 --access-logfile - --error-logfile - main:app

Dockerfile 只需将其称为入口点:

FROM python:3.8-alpine

RUN adduser -D diagnosticator

RUN apk add --no-cache bash mariadb-dev mariadb-client python3-dev build-base libffi-dev openssl-dev

WORKDIR /home/diagnosticator

COPY requirements.txt requirements.txt
RUN python -m venv venv
RUN venv/bin/pip install -U pip
RUN venv/bin/pip install wheel
RUN venv/bin/pip install -r requirements.txt
RUN venv/bin/pip install gunicorn pymysql

COPY app app
COPY upload upload
COPY variant_dependencies variant_dependencies
COPY main.py config.py boot.sh ./
COPY convert_VCF_REDIS.py asilo_variant_functions.py cloud_bigtable_functions.py mongodb_functions.py redis_functions.py ./
COPY docker_functions.py ./
RUN chmod a+x boot.sh

ENV FLASK_APP main.py

RUN chown -R diagnosticator:diagnosticator ./
USER diagnosticator

EXPOSE 5000
ENTRYPOINT ["./boot.sh"]

我在 docker-network 中运行 Docker:

docker network create --driver bridge diagnosticator-net

我注意到的问题是 Docker 容器由于某种原因在一段时间不活动后挂起并出现 gunicorn 错误:

[CRITICAL] 工作人员超时

这里是码头工人日志:

192.168.32.1 - - [12/Jun/2021:12:28:30 +0000] "GET /patient_page/GHARIgANY21uuITW2196372 HTTP/1.1" 200 19198 "http://127.0.0.1:3000/patient_result" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/91.0.4472.77 Safari/537.36"
[2021-06-12 12:29:10 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:16)
[2021-06-12 12:29:10 +0000] [16] [INFO] Worker exiting (pid: 16)
[2021-06-12 12:29:10 +0000] [17] [INFO] Booting worker with pid: 17
[2021-06-12 12:29:10,905] INFO in __init__: Diagnosticator-local startup
[2021-06-12 12:29:41 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:17)
20
[2021-06-12 12:29:41 +0000] [17] [INFO] Worker exiting (pid: 17)
[2021-06-12 12:29:41 +0000] [18] [INFO] Booting worker with pid: 18
[2021-06-12 12:29:42,094] INFO in __init__: Diagnosticator-local startup
[2021-06-12 12:30:12 +0000] [1] [CRITICAL] WORKER TIMEOUT (pid:18)
[2021-06-12 12:30:12 +0000] [18] [INFO] Worker exiting (pid: 18)

并且应用程序只是永远挂起加载您尝试访问的任何页面。

我在这里看到了一些建议并在谷歌上搜索它,例如 this one 或 this one,建议在 gunicorn --timeout 上工作,但无论我在那里放什么,问题都会不断发生。

任何帮助将不胜感激,因为我无法找到任何真正的解决方案!

【问题讨论】:

您在查询数据库吗?从 docker 容器到数据库的连接是否正确建立? @KaustubhDesai 您的意思是说 docker 应用程序是否连接到数据库?这对gunicorn有何影响? 如果 docker 应用程序连接到数据库,并且由于端口阻塞、容器不在同一个 docker 网络上等原因导致连接未建立,则连接数据库的工作人员将始终超时。跨度> 你能用 Flask 的development server 运行它吗?如果是,我们可以进一步调查gunicorn,否则我们可能不得不调查应用程序本身。 这可能与gunicorn无关,超时更可能发生在应用程序中。如果您可以在本地运行容器并启用调试,您应该能够看到一些回溯并确定挂起您的应用程序的原因。我猜你有一个本地数据库正在运行,而 docker 容器看不到它,因为你没有转发端口。 【参考方案1】:

尝试使用--log-level debug 运行 Gunicorn... 它应该会提供一些有关错误的跟踪信息。

另外,您可以尝试在 gunicorn 命令中添加 --worker-class

【讨论】:

以上是关于gunicorn Flask 应用程序在 Docker 中挂起的主要内容,如果未能解决你的问题,请参考以下文章

Kubernetes 和 Gunicorn 上的 Flask 应用程序扩展

Flask 应用程序退出时如何停止 Gunicorn

如何在多线程模式下使用 Gunicorn 运行 Flask

AWS上带有nginx和gunicorn的Flask应用程序[重复]

gunicorn Flask 应用程序在 Docker 中挂起

在 Gunicorn / Flask 应用程序中的进程之间共享静态全局数据