【问题标题】:Docker: gracefully stop django serverDocker:优雅地停止 django 服务器
【发布时间】:2018-08-28 03:54:57
【问题描述】:

我正在使用dockerdocker-compose。 在docker-compose.yml里面我有启动django服务器的命令:

command: ["./run/web.sh"]

json 格式的命令应该在 exec 模式下运行。里面web.sh

#!/usr/bin/env bash
exec python manage.py runserver

当我尝试使用docker-compose stop 停止服务时,它等待了 10 秒(默认超时),然后就终止了服务。在日志中我找到了project_web_1 exited with code 137

如何用docker stop优雅地停止django runserver?

【问题讨论】:

  • 你试过不带 exec 吗?例如:#!/bin/sh python manage.py runserver
  • w/o exec 命令将在单独的上下文中运行,docker 将无法找到命令并发送 SIGTERM。任何其他命令都可以完美运行,但django runserver
  • 这个命令怎么样? ps aux | grep runserver | awk '{print $2}' | xargs sudo kill
  • 我知道如何手动杀死命令,但不知道如何让 docker 杀死它
  • 创建一个页面并杀死python本身stackoverflow.com/a/29065968/4883754

标签: python django docker


【解决方案1】:

在您的docker-compose.yml 文件中,将stop_signal 设置为SIGINT

django:
  build: .
  command: ["./run/web.sh"]
  stop_signal: SIGINT

我自己也为此苦苦挣扎了一段时间……

启动运行服务器时,您会注意到它显示“使用 CONTROL-C 退出服务器”。我认为这意味着 Django 的运行服务器是为处理 SIGINT (ctrl-c) 而不是 SIGTERM (docker 发送的信号) 而编写的。对我来说,更改 Docker 发送给 Django 的信号比尝试在我的脚本中处理 SIGTERM 并优雅地退出运行服务器要容易。

请注意,这取决于在您的 web.sh 脚本中使用 exec,这样信号就不会被 shell 吃掉 - 但我看到您已经这样做了。

【讨论】:

  • 终于!我什至从没想过 django 只听 SIGINT。
【解决方案2】:

我会留下适合我的配置:

yml 文件:

backend:
restart: always
container_name: django_proj
image: username/django_proj
build:
  context: .
  dockerfile: ./docker/django/Dockerfile
command: /code/gunicorn-entrypoint.sh
expose:
  - 8000

gunicorn-entrypoint.sh 和你的 sh 是一样的:

#!/bin/sh
sleep 10

python manage.py makemigrations

python manage.py migrate

gunicorn -c gunicorn-config.py app_name.wsgi:application

【讨论】:

  • 正如我告诉你的,任何其他命令都可以正常工作。包括独角兽。只有./manage.py runserver 不想优雅地停下来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-09-14
  • 1970-01-01
  • 1970-01-01
  • 2021-04-06
  • 2016-05-10
  • 1970-01-01
  • 2017-09-20
相关资源
最近更新 更多