[Django]-How to stop gunicorn properly

40๐Ÿ‘

โœ…

One option would be to use Supervisor to manage Gunicorn.

Then again i donโ€™t see why you canโ€™t kill the process via Fabric.
Assuming you let Gunicorn write a pid file you could easily read that file in a Fabric command.

Something like this should work:

run("kill `cat /path/to/your/file/gunicorn.pid`")
๐Ÿ‘คarie

140๐Ÿ‘

To see the processes is ps ax|grep gunicorn and to stop gunicorn_django is pkill gunicorn.

๐Ÿ‘คVoislav Sauca

33๐Ÿ‘

pkill gunicorn

or

pkill -P1 gunicorn

should kill all running gunicorn processes

๐Ÿ‘คMalgo

19๐Ÿ‘

pkill gunicorn stops all gunicorn daemons. So if you are running multiple instances of gunicorn with different ports, try this shell script.

#!/bin/bash
Port=5000
pid=`ps ax | grep gunicorn | grep $Port | awk '{split($0,a," "); print a[1]}' | head -n 1`
if [ -z "$pid" ]; then
  echo "no gunicorn deamon on port $Port"
else
  kill $pid
  echo "killed gunicorn deamon on port $Port"
fi

ps ax | grep gunicorn | grep $Port shows the daemons with specific port.

๐Ÿ‘คtakasoft

17๐Ÿ‘

Here is the command which worked for me :

pkill -f gunicorn

It will kill any process with the name gunicorn

15๐Ÿ‘

Start:

gunicorn --pid PID_FILE APP:app

Stop:

kill $(cat PID_FILE)

The --pid flag of gunicorn requires a single parameter: a file where the process id will be stored. This file is also automatically deleted when the service is stopped.

I have used PID_FILE for simplicity but you should use something like /tmp/MY_APP_PID as file name.

If the PID file exists it means the service is running. If it is not there, the service is not running. To stop the service just kill it as mentioned.

You could also want to include the --daemon flag in order to detach the process from the current shell.

๐Ÿ‘คDavid

5๐Ÿ‘

To start the service which is running on gunicorn

sudo systemctl enable myproject

sudo systemctl start myproject

or

sudo systemctl restart myproject

But to stop the service running on gunicorn

sudo systemctl stop myproject

to know more about python application hosting using gunicorn please refer here

3๐Ÿ‘

kill -9 `ps -eo pid,command | grep 'gunicorn.*${moduleName:appName}' | grep -v grep | sort | head -1 | awk '{print $1}'`

ps -eo pid,command will only fetch process id, command and args out

grep -v grep to get rid of output like โ€˜grep โ€“color=auto xxxโ€™

sort | head -1 to do ascending sort and get first line

awk '{print $1}' to get pid back

One more thing you may need to pay attention to: Where gunicorn is installed and which one youโ€™re using?

Ubuntu 16 has gunicorn installed by default, the executable is gunicorn3 and located on /usr/bin/gunicorn3, and if you installed it by pip, itโ€™s located on /usr/local/bin/gunicorn. You would need to use which gunicorn and gunicorn -v to find out.

๐Ÿ‘คdelusionxb

3๐Ÿ‘

The above solutions does not remove pid file when the process is killed.

cat <pid-file> | xargs kill -2

This solution reads pid file and send interrupt signal. This closes gunicorn properly and pid file is also removed.

PID file can be generated by

gunicorn --pid PID-FILE

or by adding the following in config file

pidfile = "pid_file"

3๐Ÿ‘

In your terminal, do:

ps ax|grep gunicorn

Then to kill the Gunicorn process, just do that:

kill -9 <gunicorn pid number>

In my case I dealt with many processes

For example: kill -9 398 399 4225 4772

๐Ÿ‘คM E S A B O

3๐Ÿ‘

If we run:

pkill gunicorn

We stop all gunicorn services, in this case to start gunicorn we only need to stop the parent process associated with the service that attends the port where gunicorn will be executed.

The following script searches for said process (pid), if it exists it kills this process:

#!/bin/bash
# ---------------------
stop_unicorn_on_port() {
  pid=$(lsof -w -t -i "TCP:${1}" | head -1)
  if [ -z "${pid}" ]; then
    echo "๐Ÿฆ„ no service deamon on port ${1}"
  else
    kill -9 "${pid}"
    echo "๐Ÿฆ„ killed service deamon(${pid}) on port ${1}"
  fi
}
# Example/Testing
stop_unicorn_on_port 5000
stop_unicorn_on_port 5001
stop_unicorn_on_port 5002

more info check: man lsoft

  • -t specifies that lsof should produce terse output with process identifiers only and no header โ€“ e.g., so
    that the output may be piped to kill(1). -t selects the -w option.

  • -iselects the listing of files any of whose Internet address matches the address specified in i. If no
    address is specified, this option selects the listing of all Internet and x.25 (HP-UX) network filesโ€ฆ

Here are some sample addresses:

                     -i6 - IPv6 only
                     TCP:25 - TCP and port 25
                     @1.2.3.4 - Internet IPv4 host address 1.2.3.4
๐Ÿ‘คfitorec

0๐Ÿ‘

I built upon @Davidโ€™s recommendation to use โ€“pid (PID_FILE) to fix the problem I faced because killing the parent pid didnโ€™t kill worker processes.

import os
import sys

import psutil


def stop_pid(pid):
    if sys.platform == 'win32':
        p = psutil.Process(pid)
        p.terminate()  # or p.kill()
    else:
        os.system('kill -9 {0}'.format(pid))


def get_child_pids(ppid):
    pid_list = []
    for process in psutil.process_iter():
        _ppid = process.ppid()
        if _ppid == ppid:
            _pid = process.pid
            pid_list.append(_pid)
    return pid_list


def send_kill_cmd(ppid, cpids):
    stop_pid(ppid)  # Killing the parent proc first
    for pid in cpids:
        stop_pid(pid)


if __name__ == '__main__':
    parent_pid = int(sys.argv[1])
    child_pids = get_child_pids(parent_pid)
    send_kill_cmd(parent_pid, child_pids)

Then finally excecuted above python script with below commands

#!/bin/bash

FILE_NAME=PID_FILE
if [ -f "$FILE_NAME" ]; then
    pypy stop_gunicorn.py "$(cat PID_FILE)"
    echo "killed -  $(cat PID_FILE) and it's child processes."
    sleep 2
fi

echo 'Starting gunicorn'
nohup gunicorn --workers 1 --bind 0.0.0.0:5050 app:app --thread 50 --worker-class eventlet --reload --pid PID_FILE > nohup_outs/nohup_process.out &
๐Ÿ‘คRusiru Boteju

0๐Ÿ‘

kill -9 $(ps ax | grep gunicorn | awk '{print $1}')

๐Ÿ‘คhuangsy13

0๐Ÿ‘

I find that specifying the pid file location is the way to go.

$PIDFILE = '/var/etc' 
gunicorn master.wsgi:application  --pid $PIDFILE --bind=127.0.0.1:8090 

A pid file will be created to the location upon running. Gunicorn will stop properly if you remove that pid file.

๐Ÿ‘คkta

Leave a comment