74

I want to make a Flask+Nginx+Gunicorn deployment. I have Nginx setup and running and I run gunicorn as described in the docs:

gunicorn app:app

But when I logout of the server the gunicorn process exits? What is the correct way to make sure it stay running for Nginx to connect to, and restarts if it crashes?

nickponline
  • 25,354
  • 32
  • 99
  • 167

9 Answers9

103

Use --daemon option while running gunicorn. Example:

gunicorn grand56.wsgi:application --name grand56 --workers 3 --user=root --group=root --bind=127.0.0.1:1001 --daemon

Nayan
  • 1,521
  • 2
  • 13
  • 27
zhiguo.wang
  • 4,393
  • 4
  • 16
  • 8
  • 4
    will the `--daemon` flag also restart my process if it fails? Or will I still have to use upstart, systemd, sysv (or even supervisor) for something like this? – ThisGuyCantEven Jul 24 '19 at 21:21
  • 2
    Is it safe to use the linux "nohup" when starting up the gunicorn? – kawingkelvin Mar 16 '21 at 17:13
  • @kawingkelvin In my opinion it is not safe. I have used `nohup` with `gunicorn` (without `daemon`) and found that the workers restarted after I closed the server terminal (which is unexpected). I have used a `.sh` file which contains the `gunicorn` command and runs the app by `nohup service.sh &`. – hafiz031 Jul 03 '22 at 07:41
  • How do you stop this once it starts? – Temba May 01 '23 at 13:30
41

use --daemon to the binding command of gunicorn. ex:

gunicorn --bind 0.0.0.0:8001 your_project.wsgi --daemon
Gihan Gamage
  • 2,944
  • 19
  • 27
31

I'd look into something like Supervisor.

Very useful tutorial can be found here https://www.codingforentrepreneurs.com/blog/hello-linux-setup-gunicorn-and-supervisor/

Krishnadas PC
  • 5,981
  • 2
  • 53
  • 54
Rachel Sanders
  • 5,734
  • 1
  • 27
  • 36
10

Try this:

nohup gunicorn app:app &
tonino.j
  • 3,837
  • 28
  • 27
9

The key thing to note is that when you start the process from the command line it is a child of your terminal process (i. e. a child of bash). When you log out of the server your bash process is terminated - as are all its children.

You'll want to use whatever system you have in place to manage nginx also manage gunicorn (anything from init.d or Upstart scripts to specialized application process monitors like Monit, Supervisor, Bluepill, Foreman, etc.)

Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
6

Pay attention to Sean.

However you can run it on the fly like this:

nohup gunicorn -c config.py </dev/null >/dev/null 2>&1 and it will no longer be dependent on the terminal connection. You could replace >/dev/null with something like >somelogfile if you want to save any output.

But for production use it is best to get it integrated into whatever tool you use for managing processes.

Michael Dillon
  • 31,973
  • 6
  • 70
  • 106
2

Supervisor is a great cross-platform solution for process management. It is very feature rich and (in my opinion) requires a lot more configuration than some of the vanilla Linux alternatives (upstart, sysv, systemd). You should definitely use something like this to start, monitor and (if need be) restart your process.

No matter what process manager you end up using, you can still very easily leave gunicorn "running improperly" (ie as root user). I think some of the important details left out by other answers are that you should probably have one (non-root) user own the gunicorn process which binds to a unix socket that is owned by that user and the nginx group and has permissions 770. With gunicorn, you specify a mask instead, so invert 770 into 007 and use the -m flag. This way, only gunicorn and nginx can read/write/execute to the socket and no port is needed. You can specify the user and group of your gunicorn process with the -u and -g flags, and it will create the socket with those owners. Whatever you end up using for process mgmt, for nginx/gunicorn, you probably want something like this in your startup script:

exec gunicorn wsgi:app -u gunicorn -g nginx -m 007 -b gunicorn.sock >> /var/log/$<service_name>.sys.log 2>&1

Make sure the gunicorn user has write permission on the log file. Then, in nginx, where you formerly had the ip/port (ie 0.0.0.0:5000), you put the path to the socket (ie /usr/share/nginx/html/gunicorn.sock). Notice I did not use the --daemon flag here, but I used exec, this assumes a process manager, which will run gunicorn as a child process with exec.

You can find all the different flags here.

ThisGuyCantEven
  • 1,095
  • 12
  • 21
1

I tried the systemd option and it worked fine, the link below has my full answer and has all the steps , to invoke your app as a gunicorn service.

https://askubuntu.com/questions/930589/running-upstart-script-on-17-04/1010398#1010398

siddharthrc
  • 624
  • 9
  • 11
1

Running hug api like this.

--daemon is to keep the process in background.

--access-logfile to keep request log

--bind=< ip>:< port> Giving IP will allow to access from other systems(If proxy is not needed).

gunicorn <pyscirpt_name>:__hug_wsgi__ --name  caassist -w 4 --access-logfile /var/logs/gunicorn/gunicorn_access.log --daemon --bind=<ip>:<port>
pavan
  • 3,225
  • 3
  • 25
  • 29