# Nginx reverse proxy configuration for the AI Crop Decision Support System
#
# Install: copy this file to /etc/nginx/sites-available/crop-ai-system
# then: sudo ln -s /etc/nginx/sites-available/crop-ai-system /etc/nginx/sites-enabled/
# then: sudo nginx -t && sudo systemctl reload nginx
#
# Replace YOUR_DOMAIN and the SSL cert paths before deploying. Until a
# real domain + Let's Encrypt cert is set up, run port 80 only and
# comment out the 443 server block.

# Rate limit zone — extra layer in front of the app's own Redis-backed
# limiter. Defense in depth: even if a misconfigured client bypasses
# the app's rate limiter logic, Nginx still throttles at the connection
# level before requests reach Gunicorn at all.
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=20r/s;

upstream crop_ai_backend {
    # Multiple Gunicorn workers bound to different local ports, OR a
    # single Gunicorn process managing its own worker pool on one port —
    # see deployment/systemd/crop-ai-api.service for the Gunicorn command.
    # If running Gunicorn with multiple worker processes on one socket,
    # this upstream block only needs the one entry below.
    server 127.0.0.1:8000;
    keepalive 32;
}

server {
    listen 80;
    server_name YOUR_DOMAIN.com www.YOUR_DOMAIN.com;

    # Redirect all HTTP to HTTPS once SSL is configured.
    # Comment this out and uncomment the locations below for HTTP-only
    # testing before a domain/cert is ready.
    return 301 https://$host$request_uri;
}

server {
    listen 443 ssl http2;
    server_name YOUR_DOMAIN.com www.YOUR_DOMAIN.com;

    ssl_certificate     /etc/letsencrypt/live/YOUR_DOMAIN.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/YOUR_DOMAIN.com/privkey.pem;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    client_max_body_size 1M;  # this API never accepts file uploads —
                                # keep this tight to limit abuse surface

    access_log /var/log/nginx/crop-ai-access.log;
    error_log  /var/log/nginx/crop-ai-error.log warn;

    # /metrics is internal-only — never expose Prometheus metrics to
    # the public internet. Restrict to localhost / your monitoring
    # server's IP.
    location /metrics {
        allow 127.0.0.1;
        # allow YOUR_MONITORING_SERVER_IP;
        deny all;
        proxy_pass http://127.0.0.1:9090;
    }

    location / {
        limit_req zone=api_limit burst=10 nodelay;

        proxy_pass http://crop_ai_backend;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        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;

        # ML analysis can legitimately take several seconds end to end
        # (6 models + LLM call) even though the API itself returns fast
        # via the async task queue — but the /tasks polling endpoint and
        # any synchronous calls still need headroom over Nginx's default
        # 60s timeout in case of a slow backend hiccup.
        proxy_connect_timeout 10s;
        proxy_send_timeout 30s;
        proxy_read_timeout 30s;
    }

    location /health/live {
        access_log off;
        proxy_pass http://crop_ai_backend;
    }
}
