3

I'm using docker and docker-compose. Inside docker-compose.yml I have command that starts django server:

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

In json format command should run in exec mode. Inside web.sh:

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

When I tried to stop service with docker-compose stop it waited 10 seconds (default timeout) and then just kill service. In logs I've found project_web_1 exited with code 137.

How to stop django runserver gracefully with docker stop?

aiven
  • 3,775
  • 3
  • 27
  • 52
  • did you try without exec? Ex: #!/bin/sh python manage.py runserver – Dmitrii G. Jul 05 '18 at 16:20
  • w/o `exec` command will run in separate context and docker will not be able to find command and send SIGTERM. Any other command works perfectly, but not `django runserver` – aiven Jul 05 '18 at 16:27
  • How about this command ? `ps aux | grep runserver | awk '{print $2}' | xargs sudo kill` – JPG Jul 05 '18 at 16:28
  • i know how to kill command manually, but don't know how to make docker kill it – aiven Jul 05 '18 at 16:31
  • make a page and kill python itself https://stackoverflow.com/a/29065968/4883754 – Jess Chen Aug 30 '19 at 08:54
  • You know the container ID, right? otherwise `sudo /usr/local/bin/docker ps`, get CID=12345? then just use : `ssh -t user@DockerServer "sudo /usr/local/bin/docker stop ${CID}"`, PS: you can use kill instead of stop as well. – NegaOverflow May 06 '22 at 13:25

2 Answers2

7

In your docker-compose.yml file, set the stop_signal to SIGINT:

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

I struggled with this for a while myself…

When starting the runserver you'll notice it says "Quit the server with CONTROL-C." I took this to mean that Django's runserver is written to handle SIGINT (ctrl-c) and not SIGTERM (the signal docker sends). For me, changing the signal Docker sends to Django was easier than trying to handle SIGTERM in my script and exit the runserver gracefully.

Note that this depends on using exec in your web.sh script so that the signals don't get eaten by the shell – but I see you're already doing that.

tenni
  • 475
  • 3
  • 11
0

I'll leave here the config that works for me:

yml file:

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 which is the same thing as your sh:

#!/bin/sh
sleep 10

python manage.py makemigrations

python manage.py migrate

gunicorn -c gunicorn-config.py app_name.wsgi:application
Dmitrii G.
  • 895
  • 1
  • 7
  • 21
  • As i told you any other command works fine. Including gunicorn. Only `./manage.py runserver` doesn't want to stop gracefully. – aiven Jul 05 '18 at 16:39