【问题标题】:Gunicorn graceful stopping with docker-composeGunicorn 使用 docker-compose 优雅地停止
【发布时间】:2017-09-20 22:31:24
【问题描述】:

我发现当我使用 docker-compose 关闭我的 gunicorn (19.7.1) python 应用程序时,总是需要 10 秒才能关闭。这是 docker-compose 在强制终止进程之前等待的默认最长时间(使用 -t / --timeout 参数调整)。我认为这意味着 gunicorn 没有被优雅地关闭。我可以通过以下方式重现:

docker-compose.yml:

version: "3"
services:
  test:
    build: ./
    ports:
      - 8000:8000

Dockerfile:

FROM python

RUN pip install gunicorn

COPY test.py .

EXPOSE 8000
CMD gunicorn -b :8000 test:app

test.py

def app(_, start_response):
    """Simplest possible application object"""
    data = b'Hello, World!\n'
    status = '200 OK'
    response_headers = [
        ('Content-type', 'text/plain'),
        ('Content-Length', str(len(data)))
    ]
    start_response(status, response_headers)
    return iter([data])

然后运行应用程序:

docker-compose up -d

并优雅地停止它:

docker-compose stop

版本:

docker-compose version 1.12.0, build b31ff33

我宁愿让 gunicorn 优雅地停下来。我认为它应该能够基于base.py中的信号处理程序。

上述所有情况也适用于两次使用docker-compose up -d 更新图像,第二次使用新图像替换旧图像。

我是否误解/误用了某些东西? docker-compose 发送什么信号来停止进程? gunicorn 不应该使用它吗?我应该能够在 10 秒内重新启动我的应用程序吗?

【问题讨论】:

    标签: python docker docker-compose gunicorn


    【解决方案1】:

    TL;DR

    在 dockerfile 中的 CMD 后添加 execCMD exec gunicorn -b :8000 test:app

    详情

    我遇到了同样的问题,当我运行 docker exec my_running_gunicorn ps aux 时,我看到了类似的内容:

    gunicorn     1  0.0  0.0   4336   732 ?        Ss   10:38   0:00 /bin/sh -c gunicorn -c gunicorn.conf.py vision:app
    gunicorn     5  0.1  1.1  91600 22636 ?        S    10:38   0:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gunicorn.conf.py vision:app
    gunicorn     8  0.2  2.5 186328 52540 ?        S    10:38   0:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gunicorn.conf.py vision:app
    

    1 PID 不是 gunicorn master,因此它没有收到 sigterm 信号。

    有了 Dockerfile 中的 exec,我现在有了

    gunicorn     1 32.0  1.1  91472 22624 ?        Ss   10:43   0:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gunicorn.conf.py vision:app
    gunicorn     7 45.0  1.9 131664 39116 ?        R    10:43   0:00 /usr/local/bin/python /usr/local/bin/gunicorn -c gunicorn.conf.py vision:app
    

    它有效。

    【讨论】:

    • 有效!但是为什么 gunicorn 需要 exec 而其他命令运行良好呢?
    • 这仅在 ENTRYPOINT 文档下进行了解释,而不是 CMD 文档:docs.docker.com/engine/reference/builder/#entrypoint 但是,我认为 CMD 的工作方式相同。简而言之,CMD command param1 形式的 shell 表示该命令没有接收到来自 Docker 的信号。如文档所述,它使用/bin/sh -c 运行命令,就像您在答案的示例输出中看到的那样。另一方面,CMD ["command", "param1"]exec 形式确实接收到来自 Docker 的信号。在这个答案中使用CMD exec 可以达到同样的效果。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-05
    • 1970-01-01
    • 1970-01-01
    • 2021-04-06
    相关资源
    最近更新 更多