How to integrate gunicorn with nginx
Provisioing gunicorn and Nginx for running python application is pretty hard for beginners. But you can easily start the provisioning after you read my article. I hope this help you.
Installing gunicorn
$pip install gunicorn
You can also install gunicorn with apt or yum.
$sudo apt-get install gunicorn
Setting gunicorn (for django)
Write below code in setting file of your Python application.
WSGI_APPLICATION = 'config.wsgi.application'
Create a wsgi under config directory, and write below code.
import os
from django.conf import settings
from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
Ok. application instance in your wsgi file is get ready.
How to run gunicorn independently
$gunicorn project.wsgi:application --bind=127.0.0.1:8001 --daemon --reload
project: wsgi.py 파일이 위치하는 python 패키지명 (여기서는 config)
— daemon: run as a daemon process
— reload: rerun when detect code change
Nginx intallation
$sudo yum install nginx
nginx is installed in below directories.
/etc/nginx/
/usr/share/nginx/
/var/log/nginx/
Setting Nginx
Move to /etc/nginx/
Edit /etc/nginx/nginx.conf
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
client_max_body_size 300M;
include /etc/nginx/mime.types;
default_type application/octet-stream;
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*.conf;
fastcgi_connect_timeout 1000;
fastcgi_send_timeout 1000;
fastcgi_read_timeout 1000;
}
Create sites-enabled directory under nginx directory.
$mkdir /etc/nginx/sites-enabled
$cd sites-enabled
Create nginx-site.conf file.
upstream site {
# fail_timeout=0 means we always retry an upstream even if it failed
# to return a good HTTP response
server unix:/var/lib/nginx/tmp/proxy/site.sock fail_timeout=0;
}
server {
listen 80;
listen [::]:80 ipv6only=on;
server_name site;
root /usr/share/nginx/html;
index index.html index.htm;
location /static/ {
alias /usr/share/nginx/site/staticfiles/;
}
location /media/ {
alias /usr/share/nginx/site/media/;
}
location / {
proxy_set_header Host $http_host;
# we don't want nginx trying to do something clever with
# redirects, we set the Host: header above already.
proxy_redirect off;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
# ensure https for django
# proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://site;
}
}
site.sock file on upstream block is automatically generated when nginx and gunicorn start to run without any problem.
To run gunicorn as a service, you have to make a service file.
$cd /etc/systemd/system/
$vi site.service
[Unit]
Description=Gunicorn instance to serve site listener
After=network.target
[Service]
User=nginx
Group=nginx
Environment=ENV_NAME=dev
WorkingDirectory=/usr/share/nginx/site
# TODO : set workers from CPU (2 x $num_cores) + 1,
# from http://docs.gunicorn.org/en/stable/design.html)
ExecStart=/usr/local/bin/gunicorn --workers 4 --bind unix:/var/lib/nginx/tmp/proxy/site.sock config.wsgi:application
[Install]
WantedBy=multi-user.target
Environment 항목에는 python application이 돌아갈때 필요한 환경변수를 설정한다.
ExecStart 항목의 gunicorn의 위치는 절대 경로로 설정해야한다. 그렇지 않으면 기동할 때 전혀 엉뚱한 에러 메시지를 출력하며 동작하지 않는다.
All preparations are done. Let’s run gunicorn and nginx.
$sudo systemctl enable site.service
$sudo systemctl enable nginx.service
$sudo service site.service restart
$sudo service nginx restart
If you don’t see any error, your python application, gunicorn and nginx are running well.