Skip to main content

Nginx Reverse Proxy

Use Nginx to proxy Ovyxa requests through your own domain for self-hosted or VPS setups.

Why Nginx Proxy?

Perfect for:

  • Self-hosted websites
  • VPS/dedicated servers
  • Traditional LAMP/LEMP stacks
  • Non-Node.js applications

Prerequisites

  • Nginx installed and running
  • Your website already served by Nginx
  • SSL certificate (Let's Encrypt recommended)
  • Ovyxa account

Configuration

Basic Proxy Setup

Add this location block to your existing Nginx server configuration:

# /etc/nginx/sites-available/yourdomain.com
server {
listen 443 ssl http2;
server_name yourdomain.com;

# Your existing SSL config
ssl_certificate /path/to/fullchain.pem;
ssl_certificate_key /path/to/privkey.pem;

# Your existing website config
root /var/www/html;
index index.html;

# Ovyxa proxy
location /stats/ {
proxy_pass https://api.ovyxa.com/;
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;

# Forward client info
proxy_set_header Host api.ovyxa.com;
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_set_header User-Agent $http_user_agent;
proxy_set_header Referer $http_referer;

# Disable buffering for real-time
proxy_buffering off;

# Timeouts
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;

# CORS headers
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'Content-Type' always;

# Handle preflight requests
if ($request_method = 'OPTIONS') {
return 204;
}
}

# Rest of your website config...
}

Test Configuration

Before reloading Nginx, test the configuration:

sudo nginx -t

If successful, reload Nginx:

sudo systemctl reload nginx

Update Tracking Script

Update your website's HTML:

<script async
src="https://ingest.ovyxa.com/js/script.js"
data-domain="YOUR_DOMAIN"
data-api="https://yourdomain.com/stats">
</script>

Advanced Configuration

Rate Limiting

Protect against abuse with Nginx rate limiting:

# Add to http block in /etc/nginx/nginx.conf
http {
# Define rate limit zone (10MB can track ~160k IPs)
limit_req_zone $binary_remote_addr zone=analytics:10m rate=10r/s;

# Rest of http config...
}

# In your server block
server {
# ...

location /stats/ {
# Apply rate limit: 10 req/s, burst of 20, no delay for first 10
limit_req zone=analytics burst=20 nodelay;

# Proxy config...
proxy_pass https://api.ovyxa.com/;
# ... rest of proxy config
}
}

Caching (Static Assets Only)

Don't cache analytics requests, but you can cache the script:

# Cache the Ovyxa script (optional)
location = /js/script.js {
proxy_pass https://ingest.ovyxa.com/js/script.js;
proxy_cache_valid 200 1h;
proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
add_header X-Cache-Status $upstream_cache_status;
}

# Never cache analytics requests
location /stats/ {
proxy_pass https://api.ovyxa.com/;
proxy_no_cache 1;
proxy_cache_bypass 1;
add_header Cache-Control 'no-store, no-cache, must-revalidate' always;
# ... rest of config
}

Logging Analytics Requests

Log proxied requests for debugging:

# Custom log format for analytics
log_format analytics '$remote_addr - $remote_user [$time_local] '
'"$request" $status $body_bytes_sent '
'"$http_referer" "$http_user_agent" '
'proxy_time=$request_time';

server {
# ...

location /stats/ {
# Log analytics requests separately
access_log /var/log/nginx/analytics.log analytics;
error_log /var/log/nginx/analytics_error.log warn;

proxy_pass https://api.ovyxa.com/;
# ... rest of config
}
}

IP Geolocation Passthrough

Ensure IP is correctly forwarded for geolocation:

location /stats/ {
# Use real client IP (important for accuracy)
proxy_set_header X-Real-IP $remote_addr;

# If behind CloudFlare or another CDN
# Uncomment to use CF-Connecting-IP header
# proxy_set_header X-Real-IP $http_cf_connecting_ip;

# Standard X-Forwarded-For chain
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

proxy_pass https://api.ovyxa.com/;
# ... rest of config
}

Behind Cloudflare

If your site uses Cloudflare, restore real client IP:

# Install ngx_http_realip_module (usually included)
# Add to http block
http {
# Cloudflare IP ranges (update periodically)
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
# ... add more Cloudflare IPs from:
# https://www.cloudflare.com/ips/

real_ip_header CF-Connecting-IP;
real_ip_recursive on;
}

Complete Example Configuration

# /etc/nginx/sites-available/example.com

# Rate limit zone (add to main nginx.conf if not here)
limit_req_zone $binary_remote_addr zone=analytics:10m rate=10r/s;

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

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

# Website root
root /var/www/example.com/html;
index index.html index.php;

# Main website location
location / {
try_files $uri $uri/ =404;
}

# Ovyxa analytics proxy
location /stats/ {
# Rate limiting
limit_req zone=analytics burst=20 nodelay;

# Proxy to Ovyxa API
proxy_pass https://api.ovyxa.com/;
proxy_ssl_server_name on;
proxy_ssl_protocols TLSv1.2 TLSv1.3;

# Forward client information
proxy_set_header Host api.ovyxa.com;
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_set_header User-Agent $http_user_agent;
proxy_set_header Referer $http_referer;

# Performance settings
proxy_buffering off;
proxy_connect_timeout 5s;
proxy_send_timeout 10s;
proxy_read_timeout 10s;

# CORS headers
add_header Access-Control-Allow-Origin * always;
add_header Access-Control-Allow-Methods 'GET, POST, OPTIONS' always;
add_header Access-Control-Allow-Headers 'Content-Type' always;

# Prevent caching
add_header Cache-Control 'no-store, no-cache, must-revalidate' always;

# Handle OPTIONS preflight
if ($request_method = 'OPTIONS') {
return 204;
}

# Logging
access_log /var/log/nginx/analytics.log;
error_log /var/log/nginx/analytics_error.log warn;
}

# PHP or other application configs...
}

Apache Alternative

If you use Apache instead of Nginx, use mod_proxy:

# /etc/apache2/sites-available/example.com.conf
<VirtualHost *:443>
ServerName example.com

# SSL config
SSLEngine on
SSLCertificateFile /etc/letsencrypt/live/example.com/fullchain.pem
SSLCertificateKeyFile /etc/letsencrypt/live/example.com/privkey.pem

# Document root
DocumentRoot /var/www/html

# Enable proxy modules (ensure enabled)
# a2enmod proxy proxy_http proxy_html ssl headers

# Ovyxa proxy
ProxyPass /stats/ https://api.ovyxa.com/
ProxyPassReverse /stats/ https://api.ovyxa.com/

# Preserve client info
ProxyPreserveHost Off
RequestHeader set X-Forwarded-Proto "https"
RequestHeader set Host "api.ovyxa.com"

# CORS headers
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "GET, POST, OPTIONS"
Header always set Access-Control-Allow-Headers "Content-Type"

# No caching
Header always set Cache-Control "no-store, no-cache, must-revalidate"
</VirtualHost>

Enable modules:

sudo a2enmod proxy proxy_http headers ssl
sudo systemctl restart apache2

Testing

Verify Proxy Works

# Test from server
curl -X POST https://yourdomain.com/stats/e \
-H "Content-Type: application/json" \
-d '{"site":"test","event":"pageview"}'

# Should return 200 or 202

Check Logs

# Watch analytics logs
sudo tail -f /var/log/nginx/analytics.log

# Check for errors
sudo tail -f /var/log/nginx/analytics_error.log

Browser DevTools

  1. Open your website
  2. Open DevTools → Network tab
  3. Reload page
  4. Filter for "stats"
  5. Should see POST to yourdomain.com/stats/e
  6. Check response: 202 Accepted

Troubleshooting

502 Bad Gateway

Check:

  • DNS resolution: dig api.ovyxa.com
  • SSL verification: curl -I https://api.ovyxa.com
  • Nginx error logs: sudo tail -f /var/log/nginx/error.log

504 Gateway Timeout

Increase timeouts:

proxy_connect_timeout 30s;
proxy_send_timeout 30s;
proxy_read_timeout 30s;

Headers Not Forwarded

Verify headers in logs:

log_format debug '$remote_addr - $request - '
'User-Agent: $http_user_agent - '
'X-Real-IP: $proxy_add_x_forwarded_for';

access_log /var/log/nginx/debug.log debug;

SSL Certificate Issues

Ensure proxy can verify Ovyxa SSL:

# Test SSL connection
curl -v https://api.ovyxa.com

If issues, update CA certificates:

sudo apt-get update && sudo apt-get install ca-certificates

Performance

Nginx is extremely efficient for proxying:

  • ~10,000 requests/second on modest hardware
  • Less than 1ms overhead per request
  • Minimal memory footprint

Security Best Practices

  1. Use rate limiting to prevent abuse
  2. Keep Nginx updated for security patches
  3. Restrict proxy to /stats/ only (don't proxy everything)
  4. Monitor logs for suspicious patterns
  5. Use fail2ban to block malicious IPs

Learn More

Nginx proxying is rock-solid for production environments.