Skip to content

Nginx Reverse Proxy Configuration

For production deployments, it is highly recommended to run the Champa Intelligence application behind a reverse proxy like Nginx. This provides several key benefits:

  • SSL/TLS Termination: Nginx can handle HTTPS traffic, encrypting communication between the client and the server.
  • Efficient Static File Serving: Nginx is highly optimized for serving static files (CSS, JS, images), offloading this work from the Python application.
  • Load Balancing: Nginx can distribute traffic across multiple instances of the Champa Intelligence application for high availability and scalability.
  • Security: Nginx can provide an additional layer of security, handling things like rate limiting and request filtering.

Example Nginx Configuration

This configuration is based on the provided nginx.conf and is a production-ready starting point. It assumes you have already set up SSL certificates (e.g., using Let's Encrypt).

Save this configuration as /etc/nginx/sites-available/champa.conf and create a symbolic link in /etc/nginx/sites-enabled/.

# Define the root path for your static files.
# This should match the path where your application's static files are located.
map $host $static_root {
    default /path/to/your/champa-intelligence/static;
}

server {
    listen 443 ssl http2;
    server_name champa.yourcompany.com;

    # SSL Configuration
    ssl_certificate /etc/letsencrypt/live/champa.yourcompany.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/champa.yourcompany.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    # Security and performance headers
    add_header X-Frame-Options "SAMEORIGIN";
    add_header X-Content-Type-Options "nosniff";
    add_header Referrer-Policy "strict-origin-when-cross-origin";

    # Body size and timeout settings
    client_max_body_size 50M;
    proxy_connect_timeout 60s;
    proxy_send_timeout 300s;
    proxy_read_timeout 300s;

    # Main application proxy
    # All requests that don't match a more specific static file location
    # will be forwarded to the Flask application running on port 8088.
    location / {
        proxy_pass http://127.0.0.1:8088;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # === STATIC FILES HANDLING ===
    # This block tells Nginx to serve static files directly from the filesystem,
    # which is much more efficient than going through the Python application.
    # It includes aggressive caching headers for better client performance.

    location /static/ {
        # 'alias' is used here to map the URL path to the filesystem path.
        alias $static_root/;

        # Cache static assets in the browser for 1 day.
        expires 1d;
        # 'immutable' tells modern browsers this file will never change,
        # so it doesn't need to re-validate it.
        add_header Cache-Control "public, immutable";
        access_log off; # Disable logging for static files to reduce noise.

        # Enable gzip compression
        gzip on;
        gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript image/svg+xml;
        gzip_proxied any;
        gzip_vary on;
        gzip_comp_level 6;
        gzip_buffers 16 8k;
        gzip_http_version 1.1;
    }
}

# Optional: Redirect HTTP to HTTPS
server {
    listen 80;
    server_name champa.yourcompany.com;
    return 301 https://$host$request_uri;
}

Key Configuration Points

Static Root Variable

$static_root: This variable points to the static directory of your application. You must set this to the correct absolute path on your server.

map $host $static_root {
    default /path/to/your/champa-intelligence/static;
}

Proxy Configuration

proxy_pass http://127.0.0.1:8088;: This is the core directive that forwards traffic to your Gunicorn server. If your app is running in Docker, you might change this to http://champa-intelligence:8088 to use Docker's internal DNS.

Forwarded Headers

X-Forwarded-* Headers: These headers are crucial. They pass information about the original client request (like the IP address and protocol) to the Flask application, which is necessary for logging, security, and correct URL generation. ProxyFix in app.py is configured to read these headers.

Static File Optimization

location /static/: This block intercepts requests for static assets. The alias directive tells Nginx to serve these files directly from the specified filesystem path, bypassing the Python application entirely. The expires and Cache-Control headers instruct browsers to cache these files aggressively, reducing load times on subsequent page visits.


Testing Your Configuration

After creating the configuration file, test it before reloading Nginx:

# Test the configuration
sudo nginx -t

# If the test passes, reload Nginx
sudo systemctl reload nginx

Troubleshooting

502 Bad Gateway

If you see a 502 error, check that:

  1. The Champa Intelligence application is running on port 8088
  2. The proxy_pass address is correct
  3. Firewall rules allow communication between Nginx and the application
# Check if the app is listening
sudo netstat -tlnp | grep 8088

# Check Nginx error logs
sudo tail -f /var/log/nginx/error.log

Static Files Not Loading

If static files (CSS, JS) are not loading:

  1. Verify the $static_root path is correct
  2. Check file permissions (Nginx needs read access)
  3. Look for 404 errors in Nginx access logs
# Check file permissions
ls -la /path/to/your/champa-intelligence/static

# Check access logs
sudo tail -f /var/log/nginx/access.log