pytune.com - Local dev with Nginx and uWSGI
This article is based on https://github.com/Einsteinish/PyTune.git
In the previous article (pytune.com - Local dev with Apache mod_wsgi), we were able to run our Django app for pytune.com using mod_wsgi and Apache. In this page, we'll run the app with uWSGI and Nginx.
uWSGI is an application container server coded in pure C. It operates on a client-server model, and our Web server (e.g., nginx, Apache) communicates with a django-uwsgi "worker" process to serve dynamic content.
Install uWSGI:
(venv)k@laptop:/var/www/django/pytune4$ sudo pip install uwsgi
Our wsgi.py looks like this:
import os os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") from django.core.wsgi import get_wsgi_application application = get_wsgi_application()
uWSGI config file is pytune4-app.ini which creates isolated environments, each running their own versions of packages.
[uwsgi] module = wsgi:application master = true processes = 5 socket = pytune4-app.sock chmod-socket = 664 vacuum = true die-on-term = true
We can use the ini configuration file by the following command:
(venv)k@laptop:/var/www/django/pytune4$ sudo uwsgi --ini pytune4-app.ini [uWSGI] getting INI configuration from pytune4-app.ini *** Starting uWSGI 2.0.13.1 (64bit) on [Wed May 25 14:12:03 2016] *** compiled with version: 4.8.4 on 25 May 2016 10:25:54 os: Linux-3.13.0-40-generic #69-Ubuntu SMP Thu Nov 13 17:53:56 UTC 2014 nodename: laptop machine: x86_64 clock source: unix pcre jit disabled detected number of CPU cores: 2 current working directory: /var/www/django/pytune4 detected binary path: /usr/local/bin/uwsgi uWSGI running as root, you can use --uid/--gid/--chroot options *** WARNING: you are running uWSGI as root !!! (use the --uid flag) *** your processes number limit is 27820 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 UNIX address pytune4-app.sock fd 3 Python version: 2.7.6 (default, Jun 22 2015, 18:01:27) [GCC 4.8.2] *** Python threads support is disabled. You can enable it with --enable-threads *** Python main interpreter initialized at 0x1564ab0 your server socket listen backlog is limited to 100 connections your mercy for graceful operations on workers is 60 seconds mapped 436608 bytes (426 KB) for 5 cores *** Operational MODE: preforking *** WSGI app 0 (mountpoint='') ready in 2 seconds on interpreter 0x1564ab0 pid: 9785 (default app) *** uWSGI is running in multiple interpreter mode *** spawned uWSGI master process (pid: 9785) spawned uWSGI worker 1 (pid: 9786, cores: 1) spawned uWSGI worker 2 (pid: 9787, cores: 1) spawned uWSGI worker 3 (pid: 9788, cores: 1) spawned uWSGI worker 4 (pid: 9789, cores: 1) spawned uWSGI worker 5 (pid: 9790, cores: 1)
Check the process:
$ ps -ef |grep pytune4-app root 9784 21033 0 14:12 pts/35 00:00:00 sudo uwsgi --ini pytune4-app.ini root 9785 9784 0 14:12 pts/35 00:00:01 uwsgi --ini pytune4-app.ini root 9786 9785 0 14:12 pts/35 00:00:00 uwsgi --ini pytune4-app.ini root 9787 9785 0 14:12 pts/35 00:00:00 uwsgi --ini pytune4-app.ini root 9788 9785 0 14:12 pts/35 00:00:00 uwsgi --ini pytune4-app.ini root 9789 9785 0 14:12 pts/35 00:00:00 uwsgi --ini pytune4-app.ini root 9790 9785 0 14:12 pts/35 00:00:00 uwsgi --ini pytune4-app.ini
For more information about the ini file, please visit How to use Django with uWSGI.
Let's see what's new in our project directory:
$ ls -la /var/www/django/pytune4 ... -rw-r--r-- 1 root root 143 May 25 13:53 pytune4-app.ini srw-rw-r-- 1 www-data www-data 0 May 25 14:12 pytune4-app.sock ...
Note that we made changes to uid and gid from 'root' to 'www-data'.
We want to launch a uWSGI instance at boot so that our application is always available (/etc/init/pytune4-app.conf):
description "uWSGI instance to serve pytune4-app" start on runlevel [2345] stop on runlevel [!2345] setuid root setgid www-data script cd /var/www/django/pytune4 . venv/bin/activate uwsgi --ini pytune4-app.ini end script
Now that our Upstart script is complete, we can start the service:
(venv)$ sudo start pytune4-app $ ps -ef|grep pytune4-app root 13238 13234 8 16:07 ? 00:00:01 uwsgi --ini pytune4-app.ini root 13239 13238 0 16:07 ? 00:00:00 uwsgi --ini pytune4-app.ini root 13240 13238 0 16:07 ? 00:00:00 uwsgi --ini pytune4-app.ini root 13241 13238 0 16:07 ? 00:00:00 uwsgi --ini pytune4-app.ini root 13242 13238 0 16:07 ? 00:00:00 uwsgi --ini pytune4-app.ini root 13243 13238 0 16:07 ? 00:00:00 uwsgi --ini pytune4-app.ini
The app will start automatically on boot.
We can stop the service at any time by typing:
(venv)$ sudo stop pytune4-app
Let's create a new file /etc/nginx/sites-available/pytune.com.conf:
server { listen 80; server_name pytune.com www.pytune.com; location / { include uwsgi_params; uwsgi_pass unix:/var/www/django/pytune4/pytune4-app.sock; } }
Enable the server configuration we just made by linking it to the sites-enabled directory:
$ sudo ln -s /etc/nginx/sites-available/pytune.com.conf /etc/nginx/sites-enabled
Check the configuration file for any syntax errors:
$ sudo service nginx configtest * Testing nginx configuration
If it reports back that no problems were detected, restart the server to implement new changes:
$ sudo service nginx restart
Once Nginx restarts, we should be able to go to our server's domain name or IP address (without a port number) and see the application we configured:
Ph.D. / Golden Gate Ave, San Francisco / Seoul National Univ / Carnegie Mellon / UC Berkeley / DevOps / Deep Learning / Visualization