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
- Open your website
- Open DevTools → Network tab
- Reload page
- Filter for "stats"
- Should see POST to
yourdomain.com/stats/e - 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
- Use rate limiting to prevent abuse
- Keep Nginx updated for security patches
- Restrict proxy to /stats/ only (don't proxy everything)
- Monitor logs for suspicious patterns
- Use fail2ban to block malicious IPs
Learn More
- Cloudflare Proxy - For sites behind Cloudflare
- Vercel Proxy - For Next.js/Vercel sites
- Nginx Docs - Official proxy module docs
Nginx proxying is rock-solid for production environments.