How to stop gunicorn properly
Asked Answered
T

14

96

I'm starting gunicorn with the Django command python manage.py run_gunicorn. How can I stop gunicorn properly?

Note: I have a semi-automated server deployment with fabric. Thus using something like ps aux | grep gunicorn to kill the process manually by pid is not an option.

Tradescantia answered 30/1, 2013 at 13:0 Comment(0)
C
41

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`")
Charin answered 30/1, 2013 at 13:19 Comment(0)
K
143

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

Kiona answered 30/1, 2013 at 13:29 Comment(5)
As I mentioned in my question, this is not an option (automated deployment).Tradescantia
@PiyushS.Wanare do kill -9 <pid number>Crissie
htop is useful for viewing pids as well as sending various kill commands besides SIGKILL (-9)Cyprio
Really, this answer is high voted? :o It would stop all gunicorn instances running on the server :/Beeeater
Doesn't stop it for me.Francescafrancesco
C
41

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`")
Charin answered 30/1, 2013 at 13:19 Comment(0)
R
34
pkill gunicorn

or

pkill -P1 gunicorn

should kill all running gunicorn processes

Rennold answered 28/10, 2020 at 11:21 Comment(1)
first one is enough.Tillman
S
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.

Samal answered 15/8, 2018 at 21:25 Comment(1)
I had a similar case, i make this command: ``` lsof "-i:${Port}" | grep gunicorn | cut -d" " -f2 | sort | head -1 ```Chat
A
17

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.

Agnesse answered 13/1, 2021 at 9:54 Comment(1)
This is an elegant solution which garantees that we do not kill any gunicorn process accidentally. Thanks.Unbelievable
A
17

Here is the command which worked for me :

pkill -f gunicorn

It will kill any process with the name gunicorn

Ali answered 12/8, 2021 at 10:52 Comment(1)
Works on Mac(zsh). Thanks!Topfull
L
6

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

Langobard answered 1/10, 2020 at 6:35 Comment(1)
This will work only if you created a myproject.service file in /etc/systemd/system/. See freedesktop.org/software/systemd/man/systemd.service.html on how to create systemd service files.Radicle
C
4

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
Chat answered 3/9, 2022 at 14:34 Comment(0)
P
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.

Pettit answered 15/8, 2018 at 6:44 Comment(0)
P
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"
Peruke answered 15/4, 2022 at 10:5 Comment(0)
A
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

Accra answered 27/6, 2022 at 20:35 Comment(2)
This won't work as master process will create workers immediately if they are killed.Bowling
@tka, please stop your application or server if you've an interface like viscose and then, try again. It works well in my case. Otherwise you may selected the wrong pid number. Try also pkill -f gunicornAccra
M
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 &
Monumental answered 31/10, 2022 at 11:8 Comment(0)
D
0

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

Downstage answered 13/6, 2023 at 6:26 Comment(0)
B
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.

Bowling answered 17/8, 2023 at 3:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.