Fading Coder

One Final Commit for the Last Sprint

Home > Tech > Content

Deploying Python Applications with uWSGI and Nginx

Tech May 10 5

Nginx Installation and Compilation

First, ensure the build environment and necessary libraries are present on the system. The following sequence installs developmant tools, downloads the PCRE library required for regex support, and compiles Nginx from source with SSL and status monitoring modules enabled.

# Install build dependencies
yum install -y gcc make zlib-devel openssl-devel pcre-devel

# Download and compile PCRE
wget ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre/pcre-8.45.tar.gz
tar -xzf pcre-8.45.tar.gz -C /usr/local/src/
cd /usr/local/src/pcre-8.45
./configure
make && make install

# Download and compile Nginx
wget http://nginx.org/download/nginx-1.22.0.tar.gz
tar -xzf nginx-1.22.0.tar.gz
cd nginx-1.22.0
./configure \
  --prefix=/opt/nginx \
  --with-http_stub_status_module \
  --with-http_ssl_module \
  --with-pcre=/usr/local/src/pcre-8.45
make && make install

# Verify installation
/opt/nginx/sbin/nginx -v

# Create a dedicated system user for the service
groupadd deploy
useradd -g deploy -s /sbin/nologin deploy

Configuring Nginx

The main configuration file defines the user context, worker processes, and connection handling methods. The epoll method is recommended for high-performance Linux systems.

# /opt/nginx/conf/nginx.conf
user deploy deploy;
worker_processes 4;
error_log /opt/nginx/logs/error.log warn;
pid /var/run/nginx.pid;

events {
    use epoll;
    worker_connections 2048;
}

http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;

    server {
        listen       80;
        server_name  localhost;

        # Serve static files directly
        location /static/ {
            alias /var/www/app/static/;
            autoindex on;
            autoindex_exact_size off;
            autoindex_localtime on;
        }
    }
}

For specific application routing, a separate configuration block is used to pass traffic to the uWSGI socket or set up a reverse proxy with proper CORS headers.

# /opt/nginx/conf.d/app.conf

server {
    listen 80;
    server_name api.example.com;

    # Timeout settings for long-running processes
    proxy_connect_timeout 300s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;

    location /api/v1 {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/uwsgi_app.sock;
    }

    location /dashboard/proxy {
        rewrite ^/dashboard/proxy/(.*)$ /$1 break;
        proxy_pass http://127.0.0.1:8080;
        
        # Standard Proxy Headers
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        
        # CORS Configuration
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, DELETE';
    }
}

uWSGI Configuration

The uWSGI application server is configured via an INI file. This setup specifies the Python environment, the WSGI entry point, and process management settings. It utilizes a Unix socket for communication with Nginx.

# /var/www/app/uwsgi.ini
[uwsgi]
# Socket communication
socket = /tmp/uwsgi_app.sock
chmod-socket = 666

# Python Environment
chdir = /var/www/app
module = wsgi:app
home = /var/www/app/venv
py-autoreload = 2

# Process Management
master = true
processes = 4
threads = 2
enable-threads = true

# Logging
pidfile = /var/run/uwsgi_app.pid
daemonize = /var/log/uwsgi_app.log
buffer-size = 65536

# Permissions
uid = deploy
gid = deploy

To manage the uWSGI service, use the following commands:

# Start the service
uwsgi --ini /var/www/app/uwsgi.ini

# Graceful reload
uwsgi --reload /var/run/uwsgi_app.pid

Database Configuration

For database connectivity, ensure the root user is configured with a secure password and native password authentication.

ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'StrongPassword';
FLUSH PRIVILEGES;

Advanced Nginx Setup for WebSockets and Proxies

This configuration demonstrates handling WebSocket connections (e.g., for Socket.io) and increased buffer sizes for large payloads.

server {
    listen 80;
    server_name websocket.example.com;

    # Buffer Sizes
    proxy_buffer_size 128k;
    proxy_buffers 4 256k;
    proxy_busy_buffers_size 256k;
    proxy_temp_file_write_size 256k;

    location /socket.io {
        include uwsgi_params;
        uwsgi_pass unix:/tmp/uwsgi_app.sock;
        
        # WebSocket upgrade headers
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

Related Articles

Understanding Strong and Weak References in Java

Strong References Strong reference are the most prevalent type of object referencing in Java. When an object has a strong reference pointing to it, the garbage collector will not reclaim its memory. F...

Comprehensive Guide to SSTI Explained with Payload Bypass Techniques

Introduction Server-Side Template Injection (SSTI) is a vulnerability in web applications where user input is improper handled within the template engine and executed on the server. This exploit can r...

Implement Image Upload Functionality for Django Integrated TinyMCE Editor

Django’s Admin panel is highly user-friendly, and pairing it with TinyMCE, an effective rich text editor, simplifies content management significantly. Combining the two is particular useful for bloggi...

Leave a Comment

Anonymous

◎Feel free to join the discussion and share your thoughts.