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.plcan 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 { # } # } }