Deploy Python Django Web Application with UWSGI and Nginx1. Install Packages2. Configure uWSGI2.1 Loading configuration files2.2 Magic variables2.3 Placeholders2.4 Placeholders math2.5 Start & ReloadExampleuWSGINginx
1. Install Packages
Install python-devel
yum install python-devel
Install uwsgi
pip install uwsgi
2. Configure uWSGI
Refer to official configuration document: https://uwsgi.readthedocs.io/en/latest/Configuration.html
The configuration system is unified, so each command line option maps 1:1 with entries in the configuration files.
Example:
uwsgi --http-socket :9090 --psgi myapp.pl
can be written as
[uwsgi] http-socket = :9090 psgi = myapp.pl
2.1 Loading configuration files
uWSGI supports loading configuration files over several methods other than simple disk files:
uwsgi --ini http://uwsgi.it/configs/myapp.ini # HTTP uwsgi --xml - # standard input uwsgi --yaml fd://0 # file descriptor uwsgi --json 'exec://nc 192.168.11.2:33000' # arbitrary executable
2.2 Magic variables
uWSGI configuration files can include “magic” variables, prefixed with a percent sign. Currently the following magic variables (you can access them in Python via uwsgi.magic_table
) are defined.
%v
the vassals directory (pwd)
%V
the uWSGI version
%h
the hostname
%o
the original config filename, as specified on the command line
%O
same as %o but refer to the first non-template config file (version 1.9.18)
%p
the absolute path of the configuration file
%P
same as %p but refer to the first non-template config file (version 1.9.18)
%s
the filename of the configuration file
%S
same as %s but refer to the first non-template config file (version 1.9.18)
%d
the absolute path of the directory containing the configuration file
%D
same as %d but refer to the first non-template config file (version 1.9.18)
%e
the extension of the configuration file
%E
same as %e but refer to the first non-template config file (version 1.9.18)
%n
the filename without extension
%N
same as %n but refer to the first non-template config file (version 1.9.18)
%c
the name of the directory containing the config file (version 1.3+)
%C
same as %c but refer to the first non-template config file (version 1.9.18)
%t
unix time (in seconds, gathered at instance startup) (version 1.9.20-dev+)
%T
unix time (in microseconds, gathered at instance startup) (version 1.9.20-dev+)
%x
the current section identifier, eg. config.ini:section (version 1.9-dev+)
%X
same as %x but refer to the first non-template config file (version 1.9.18)
%i
inode number of the file (version 2.0.1)
%I
same as %i but refer to the first non-template config file
%0..%9
a specific component of the full path of the directory containing the config file (version 1.3+)
%[
ANSI escape “\033” (useful for printing colors)
%k
detected cpu cores (version 1.9.20-dev+)
%u
uid of the user running the process (version 2.0)
%U
username (if available, otherwise fallback to uid) of the user running the process (version 2.0)
%g
gid of the user running the process (version 2.0)
%G
group name (if available, otherwise fallback to gid) of the user running the process (version 2.0)
%j
HEX representation of the djb33x hash of the full config path
%J
same as %j but refer to the first non-template config file
2.3 Placeholders
Placeholders are custom magic variables defined during configuration time by setting a new configuration variable of your own devising.
[uwsgi] ; These are placeholders... my_funny_domain = uwsgi.it set-ph = max_customer_address_space=64 set-placeholder = customers_base_dir=/var/www ; And these aren't. socket = /tmp/sockets/%(my_funny_domain).sock chdir = %(customers_base_dir)/%(my_funny_domain) limit-as = %(max_customer_address_space)
Placeholders can be assigned directly, or using the set-placeholder
/ set-ph
option. These latter options can be useful to:
Make it more explicit that you’re setting placeholders instead of regular options.
Set options on the commandline, since unknown options like
--foo=bar
are rejected but--set-placeholder foo=bar
is ok.Set placeholders when strict mode is enabled.
Placeholders are accessible, like any uWSGI option, in your application code via uwsgi.opt
.
import uwsgi print uwsgi.opt['customers_base_dir']
This feature can be (ab)used to reduce the number of configuration files required by your application.
2.4 Placeholders math
You can apply math formulas to placeholders using this special syntax:
[uwsgi] foo = 17 bar = 30 ; total will be 50 total = %(foo + bar + 3)
Remember to not miss spaces between operations.
Operations are executed in a pipeline (not in common math style):
[uwsgi] foo = 17 bar = 30 total = %(foo + bar + 3 * 2)
‘total’ will be evaluated as 100:
(((foo + bar) + 3) * 2)
Incremental and decremental shortcuts are available
[uwsgi] foo = 29 ; remember the space !!! bar = %(foo ++)
bar will be 30
If you do not specify an operation between two items, ‘string concatenation’ is assumed:
[uwsgi] foo = 2 bar = 9 ; remember the space !!! bar = %(foo bar ++)
the first two items will be evaluated as ‘29’ (not 11 as no math operation has been specified)
2.5 Start & Reload
#start uwsgi conf.ini
reload
uwsgi --reload /tmp/project-master.pid
Example
uWSGI
[uwsgi] socket = 127.0.0.1:3031 chdir = /datageek/DataGeek/api/ pidfile = /tmp/project-master.pid wsgi-file = api/wsgi.py processes = 4 threads = 2 stats = 127.0.0.1:9191 daemonize=/datageek/log/uwsgi/datageek.log
Nginx
# For more information on configuration, see:
* Official English Documentation: http://nginx.org/en/docs/
* Official Russian Documentation: http://nginx.org/ru/docs/
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 /datageek/log/nginx/access.log main; sendfile on; tcp_nopush on; tcp_nodelay on; keepalive_timeout 65; types_hash_max_size 2048; include /etc/nginx/mime.types; default_type application/octet-stream; # Load modular configuration files from the /etc/nginx/conf.d directory. # See http://nginx.org/en/docs/ngx\_core\_module.html#include # for more information. include /etc/nginx/conf.d/*.conf; server { listen 80 default_server; listen [::]:80 default_server; server_name _; root /datageek/DataGeek/webapp/dist/index.html; # Load configuration files for the default server block. include /etc/nginx/default.d/*.conf; location / { root /datageek/DataGeek/webapp/dist; } location /api { include uwsgi_params; uwsgi_pass 127.0.0.1:3031; } error_page 404 /404.html; location = /40x.html { } error_page 500 502 503 504 /50x.html; location = /50x.html { } }
Settings for a TLS enabled server.
server {
listen 443 ssl http2 default_server;
listen [::]:443 ssl http2 default_server;
server_name _;
root /usr/share/nginx/html;
ssl_certificate "/etc/pki/nginx/server.crt";
ssl_certificate_key "/etc/pki/nginx/private/server.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_prefer_server_ciphers on;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
location / {
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}