Nginx Configuration for Bare Metal: Reverse Proxy, Load Balancing, and Caching
Nginx powers over 30% of websites on the internet. On bare metal, it becomes your front door — handling TLS termination, reverse proxying to application servers, balancing traffic across backends, and caching static assets. Here is the production-ready configuration guide.
Install Nginx on Your RAW Server
# Deploy a RAW server and SSH in
npx rawhq deploy
ssh root@your-server-ip
# Install Nginx
apt update && apt install -y nginx
# Verify it is running
systemctl status nginx
curl -I http://localhostReverse Proxy for Node.js, Python, and Go
Most web applications run on localhost ports. Nginx sits in front, handling TLS, HTTP/2, and routing while forwarding requests to your app.
Node.js / Express (Port 3000)
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://127.0.0.1:3000;
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;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}Python / Gunicorn (Port 8000)
location / {
proxy_pass http://127.0.0.1:8000;
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_read_timeout 300;
}Go (Port 8080)
Go applications handle concurrency natively, so the proxy config is identical — just point to the correct port. Go apps typically need no extra timeout tuning.
Load Balancing Multiple Backends
When you run multiple instances of your app (on different ports or servers), Nginx distributes traffic across them automatically.
upstream app_cluster {
# Round-robin (default)
server 127.0.0.1:3001;
server 127.0.0.1:3002;
server 127.0.0.1:3003;
# Alternative: least connections
# least_conn;
# Alternative: IP hash (sticky sessions)
# ip_hash;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://app_cluster;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}On a RAW bare metal server with 4+ dedicated cores, running 3–4 Node.js workers behind Nginx load balancing gives you near-linear throughput scaling.
Static File Caching
Serve static files directly from Nginx instead of proxying to your application. This alone can 10x your throughput for assets.
server {
listen 80;
server_name example.com;
# Static files served directly by Nginx
location /static/ {
alias /var/www/app/static/;
expires 30d;
add_header Cache-Control "public, immutable";
access_log off;
}
# Everything else proxied to the app
location / {
proxy_pass http://127.0.0.1:3000;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}Gzip Compression
Enable gzip to reduce bandwidth usage by 60–80% for text-based responses. Add this to your nginx.conf http block:
gzip on;
gzip_vary on;
gzip_proxied any;
gzip_comp_level 6;
gzip_min_length 1024;
gzip_types
text/plain
text/css
text/javascript
application/javascript
application/json
application/xml
image/svg+xml;Security Headers
Add these headers to every server block to harden your Nginx against common attacks:
# Security headers
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
# Hide Nginx version
server_tokens off;Testing and Reloading
# Test config syntax before reloading
nginx -t
# Reload without downtime
systemctl reload nginx
# Check error logs if something breaks
tail -f /var/log/nginx/error.logWhy Bare Metal for Nginx
On shared cloud VMs, Nginx competes for CPU with noisy neighbors. On RAW bare metal, you get dedicated cores and NVMe storage. The result: consistent sub-millisecond proxy latency, higher concurrent connection limits, and no throttling at traffic spikes. All starting at $6/mo.