Create a web server with uWSGI & Django
by Mecbar 2 settembre 2017


For execute an web application with Django you can use the web server into Python or create an application server with Uwsgi. Here we see how to create an application server with Uwsgi. First of all install Uwsgi from Terminal:

pip install uwsgi

for test correct execution of Uwsgi create a file python test.py

# test.py
def application(env, start_response):
start_response('200 OK', [('Content-Type','text/html')])
return [b"Hello World"] # python3
return ["Hello World"] # python2

from Terminal to launch Uwsgi
sudo uwsgi --http :8000 --wsgi-file_test.py
and into browser insert http://localhost:8000

sudo uwsgi --http :8000 --wsgi-file test.py

it's the result of the command python manage.py runserver. Now install Nginx and use an Unix socket for connect to the app


sudo apt-get install nginx
then start the service
sudo /etc/init.d/nginx start
Now go in the directory of the app and create a configuration file of Nginx for the app with tha Nano editor
sudo nano app_nginx.conf
and insert

# nginx.conf
upstream django {
# connect to this socket
# server unix:///path app/name_app.sock; # for a file socket
server 127.0.0.1:8001; # for a web port socket
}
# the port your site will be served on
listen 8000;
# the domain name it will serve for server_name 127.0.0.1;
# substitute your machine's IP address or FQDN charset utf-8; # max upload size client_max_body_size 75M; # adjust to taste
# Django media
location /media { alias /path_app/static/images; # your Django project's media files - amend as required } # si possono inserire nel file setting.py location /static { alias /percorso mia app/static; # your Django project's
static files - amend as required
}
# Finally, send all non-media requests to the Django server.
location / {
uwsgi_pass django;
include /etc/nginx/uwsgi_params; # the uwsgi_params file you installed
}
}


press ctrl+o for save and ctrl+x to exit. Now create the link between the file .conf created with Nginx

sudo ln -s ~/path_app/name_app_nginx.conf /etc/nginx/sites-enabled/


into file setting.py of the app insert STATIC_ROOT = os.path.join(BASE_DIR,"static/") for handle static files.
Now restart Nginx
sudo /etc/init.d/nginx restart
[ ok ] Restarting nginx (via systemctl): nginx.service.
sudo systemctl status nginx.service

● nginx.service - A high performance web server and a reverse proxy server Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since mer 2017-08-30 00:10:31 CEST; 4s ago
Process: 14530 ExecStop=/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid (code=exited, status=0/SUCCESS)
Process: 14830 ExecStart=/usr/sbin/nginx -g daemon on; master_process on; (code=exited, status=0/SUCCESS)
Process: 14827 ExecStartPre=/usr/sbin/nginx -t -q -g daemon on; master_process on; (code=exited, status=0/SUCCESS) Main PID: 14831 (nginx)
CGroup: /system.slice/nginx.service ├─14831 nginx: master process /usr/sbin/nginx -g daemon on; master_process on ├─14832 nginx: worker process ├─14833 nginx: worker process ├─14834 nginx: worker process └─14835 nginx: worker process ago 30 00:10:31 mecbar systemd[1]: Starting A high performance web server and a reverse proxy server... ago 30 00:10:31 mecbar systemd[1]: Started A high performance web server and a reverse proxy server.


copy uwsgi.params into the project directory. Now test the socket
sudo uwsgi --socket :8001 --wsgi-file_test.py
we see the following message how response:

*** Starting uWSGI 2.0.15 (64bit) on [Wed Aug 30 00:35:30 2017] ***
compiled with version: 5.4.0 20160609 on 29 August 2017 23:10:14
os: Linux-4.10.0-33-generic #37~16.04.1-Ubuntu SMP Fri Aug 11 14:07:24 UTC 2017
nodename: xxxxxx
machine: x86_64
clock source: unix detected
number of CPU cores: 4
current working directory: /percorso app
detected binary path: /usr/local/bin/uwsgi
!!! no internal routing support, rebuild with pcre support !!!
*** WARNING: you are running uWSGI without its master process manager ***
your processes number limit is 31000
your memory page size is 4096 bytes
detected max file descriptor number: 1024
lock engine: pthread robust mutexes
thunder lock: disabled (you can enable it with --thunder-lock)
uwsgi socket 0 bound to TCP address :8001 fd 3
Python version: 2.7.12 (default, Nov 19 2016, 06:48:10) [GCC 5.4.0 20160609]
*** Python threads support is disabled. You can enable it with --enable-threads ***


.... if we insert into the browser http://localhost:8000 we see 'hello world' . For error or problem read the log of Nginx at the link /var/log/nginx/error.log) if error 13: Permission denied or other messagge insert the following command:
sudo uwsgi --socket name_app.sock --wsgi-file_test.py --chmod-socket=666
sudo uwsgi --socket mysite.sock --wsgi-file_test.py --chmod-socket=664 # (more sensible)

Se tutto ok ci siamo e proviamo il socket con la nostra applicazione che per esempio la chiamiamo app
sudo uwsgi --socket app.sock --module app.wsgi –chmod-socket=666
N.B: se errore

502 bad gateway read the log /var/log/nginx → error.log if error 13 Permission denied folder project delete the file app.sock and try again
*** Starting uWSGI 2.0.15 (64bit) on [Wed Aug 30 19:41:56 2017] *** compiled with version: 5.4.0 20160609 on 29 August 2017 23:10:14
os: Linux-4.10.0-33-generic #37~16.04.1-Ubuntu SMP Fri Aug 11 14:07:24 UTC ..... *** uWSGI is running in multiple interpreter mode ***


into the browser http://localhost:8000 we have our app ready and run through Django, Uwsgi e Nginx. Config uWSGI for execute it with .ini file insert the data into a file and then run it
sudo nano app_uwsgi.ini

# mysite_uwsgi.ini file
[uwsgi]
# Django-related settings
# the base directory (full path)
chdir = /path_app
# Django's wsgi file
module = app.wsgi
# the virtualenv (full path)
home = /path/virtualenv
# process-related settings
# master master = true
# maximum number of worker processes processes = 10
# the socket (use the full path to be safe
socket = /path/app.sock # ... with appropriate permissions - may be needed
# chmod-socket = 664 # chmod-socket = 666
# clear environment on exit
vacuum = true


press ctrl+o to save then ctrl+x for exit and execute created file
sudo uwsgi --ini app_uwsgi.ini # the --ini option it means that is a file

[uWSGI] getting INI configuration from app_uwsgi.ini *** Starting uWSGI 2.0.15 (64bit) on [Wed Aug 30 20:49:26 2017] *** compiled with version: 5.4.0 20160609 on 29 August 2017 23:10:14 os: Linux-4.10.0-33-generic #37~16.04.1-Ubuntu SMP Fri Aug 11 14:07:24 UTC 2017...........


For the end of configuration set Emperor methd for handle more application on the same server (uid user id – gid group id) - create the directory uwsgi into the folder /etc
sudo mkdir /etc/uwsgi
sudo mkdir /etc/uwsgi/vassals

than a file ini with folder vassals
sudo ln -s /path/app_uwsgi.ini /etc/uwsgi/vassals/
sudo uwsgi --emperor /etc/uwsgi/vassals --uid www-data --gid www-data

*** Starting uWSGI 2.0.15 (64bit) on [Wed Aug 30 20:57:24 2017] *** compiled with version: 5.4.0 20160609 on 29 August 2017 23:10:14 os: Linux-4.10.0-33-generic #37~16.04.1-Ubuntu SMP Fri Aug 11 14:07:24 UTC 2017 nodename: xxxxxx machine: x86_64 clock source: unix detected number of CPU cores: 4 current working directory: /path_app detected binary path: /usr/local/bin/uwsgi !!! no internal routing support, rebuild with pcre support !!! setgid() to 33 setuid() to 33 *** WARNING: you are running uWSGI without its master process manager *** your processes number limit is 31000 your memory page size is 4096 bytes detected max file descriptor number: 1024 *** starting uWSGI Emperor *** *** has_emperor mode detected (fd: 6) *** [uWSGI] getting INI configuration from app_uwsgi.ini *** .... - [emperor] vassal app_uwsgi.ini is now loyal.


Into the browser app is ready.
Now set the automatic start of the service Uwsgi with the systemctl of linux.
Create the file uwsgi.service
sudo nano /etc/systemd/system/uwsgi.service
and insert the following data

[Unit]
Description=uWSGI Emperor
After=syslog.target
[Service]
ExecStart=/usr/local/bin/sudo uwsgi --emperor /etc/uwsgi/vassals/ --uid www-data --gid www-data --daemonize /var/log/uwsgi-emperor.log
# Requires systemd version 211 or newer
RuntimeDirectory=uwsgi
Restart=always
KillSignal=SIGQUIT
Type=notify StandardError=syslog
NotifyAccess=all
[Install]
WantedBy=multi-user.target


ctrl+o for save and crl+x for exit. Start the service and test if it is active
sudo systemctl start uwsgi.service
sudo systemctl status uwsgi.service


uwsgi service status


For test if service is automatic active at every restart run the system restart and just the system is ready check the status of service. if it's active we finished.

That's all