Nginx & Reverse Proxy Documentation

Complete guide to setting up and configuring Nginx web server with reverse proxy capabilities

Installation Guide

Ubuntu/Debian Installation

Install Nginx on Ubuntu or Debian systems using the package manager:

# Update package index

sudo apt update

# Install Nginx

sudo apt install nginx

# Start and enable Nginx service

sudo systemctl start nginx
sudo systemctl enable nginx

# Check status

sudo systemctl status nginx

CentOS/RHEL Installation

For CentOS or RHEL systems:

# Install EPEL repository

sudo yum install epel-release

# Install Nginx

sudo yum install nginx

# Start and enable service

sudo systemctl start nginx
sudo systemctl enable nginx

Firewall Configuration

Don't forget to allow HTTP and HTTPS traffic through your firewall:

# For UFW (Ubuntu)

sudo ufw allow 'Nginx Full'

# For firewalld (CentOS/RHEL)

sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload

Basic Configuration

Directory Structure

Understanding Nginx configuration structure:

  • /etc/nginx/nginx.conf - Main configuration file
  • /etc/nginx/sites-available/ - Available site configurations
  • /etc/nginx/sites-enabled/ - Enabled site configurations
  • /var/log/nginx/ - Log files directory
  • /var/www/html/ - Default web root

Basic Server Block

Create a basic server configuration:

Create a basic server configuration:

server {
    listen 80;
    server_name example.com www.example.com;
    root /var/www/example.com;
    index index.html index.htm index.php;

    location / {
        try_files $uri $uri/ =404;
    }

    # Log files
    access_log /var/log/nginx/example.com.access.log;
    error_log /var/log/nginx/example.com.error.log;
}

PHP Configuration

Add PHP support to your server block:

Add PHP support to your server block:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Reverse Proxy Setup

Complete Setup Guide

This guide will walk you through the complete process of setting up a reverse proxy with Nginx. Follow the steps in order for the best results.

Step 1: Domain & DNS Setup

First, configure your domain to point to your server. This must be done before setting up SSL certificates.

Configure Nginx as a reverse proxy:

server {
# -------------------------------------------------------

# HTTP -> HTTPS (men tillad ACME-challenges for cert fornyelse)
server {
    if ($host = api.example.com) {
        return 301 https://$host$request_uri;
    } # managed by Certbot

    listen 80;
    server_name api.example.com;

    # ACME (Let's Encrypt) – lad certbot validere uden at blive redirectet
    location ^~ /.well-known/acme-challenge/ {
        root /var/www/letsencrypt;
        allow all;
    }

    return 301 https://api.example.comk$request_uri;




}

# HTTPS -> din NGINX-egg / webservice på port
server {
    listen 443 ssl http2;
    server_name api.example.com;

    # Let's Encrypt certifikater
    ssl_certificate /etc/letsencrypt/live/docs.mrfaws.dk/fullchain.pem; # managed by Certbot
    ssl_certificate_key /etc/letsencrypt/live/docs.mrfaws.dk/privkey.pem; # managed by Certbot

    # Fornuftige TLS-indstillinger
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;
    ssl_prefer_server_ciphers on;

    # Sikkerheds-headers
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload" always;
    add_header X-Content-Type-Options nosniff always;
    add_header X-Frame-Options SAMEORIGIN always;
    add_header Referrer-Policy "strict-origin-when-cross-origin" always;

    # Proxy til din specifikke Pterodactyl-server (HTTP på 3000)
    location / {
         proxy_pass http://127.0.0.1:3000;

        # Vigtige headers
        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;

        # WebSocket support (hvis nødvendigt)
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Timeouts (så builds/uploads ikke dør for hurtigt)
        proxy_read_timeout 300;
        proxy_send_timeout 300;
    }




}

}

Load Balancing

Set up load balancing across multiple backend servers:

Set up load balancing across multiple backend servers:

upstream backend {
    server 127.0.0.1:3000 weight=3;
    server 127.0.0.1:3001 weight=2;
    server 127.0.0.1:3002 backup;
}

server {
    listen 80;
    server_name app.example.com;

    location / {
        proxy_pass http://backend;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Domain & DNS Setup

Before configuring your reverse proxy, ensure your domain is properly set up:

DNS Configuration Interface

Configure DNS records for your domain. This interactive tool shows you how to set up different record types:

Edit DNS record example.com

DNS changes can take from 1 to 24 hours to take effect, but will be written to the zone immediately.

A Record Guide

A records map domain names to IPv4 addresses. Use this to point your domain to a server.

Example A Record:

example.com    A    45.133.74.72
⚠️ Warning: Changing DNS records can greatly affect the availability of your domain
We DO NOT recommend you to change your DNS records unless you understand their function.

Verify DNS propagation:

# Check if DNS is working
dig example.com A
nslookup example.com

# Test from different locations
dig @8.8.8.8 example.com A
dig @1.1.1.1 example.com A

Step 2: Generate Nginx Configuration

Create a custom Nginx configuration file for your domain and backend application:

Configuration Generator

Fill in your details below to generate a custom Nginx configuration file:

Features
Performance
# Your configuration will appear here...

Step 3: Deploy Configuration

Save your generated configuration file and deploy it to your server:

1) Create configuration file:

# Create new site configuration (replace 'your-domain.com' with your actual domain)
sudo nano /etc/nginx/sites-available/your-domain.com

# Or upload your downloaded file
sudo cp ~/your-domain.com-nginx.conf /etc/nginx/sites-available/your-domain.com

2) Enable the site:

# Create symbolic link to enable site
sudo ln -sf /etc/nginx/sites-available/your-domain.com /etc/nginx/sites-enabled/your-domain.com

3) Test and activate:

# Test configuration syntax
sudo nginx -t

# If test passes, reload Nginx
sudo systemctl reload nginx

Step 4: SSL Certificate (Optional)

If you didn't include SSL in your configuration, you can add it using Certbot:

Generate SSL certificate:

# Install Certbot (if not already installed)
sudo apt install certbot python3-certbot-nginx

# Generate certificate for your domain
sudo certbot --nginx -d your-domain.com -d www.your-domain.com

Step 5: Management & Troubleshooting

Use these commands to manage and troubleshoot your reverse proxy:

Essential Management Commands

Service management:

# Check Nginx status
sudo systemctl status nginx

# Start Nginx
sudo systemctl start nginx

# Stop Nginx
sudo systemctl stop nginx

# Restart Nginx (full restart)
sudo systemctl restart nginx

# Reload configuration (preferred - no downtime)
sudo systemctl reload nginx

Configuration testing:

# Test configuration syntax
sudo nginx -t

# Test specific configuration file
sudo nginx -t -c /etc/nginx/sites-available/your-domain.com

Log monitoring:

# View access logs (real-time)
sudo tail -f /var/log/nginx/access.log

# View error logs (real-time)
sudo tail -f /var/log/nginx/error.log

# View logs for specific domain
sudo tail -f /var/log/nginx/your-domain.com.access.log
sudo tail -f /var/log/nginx/your-domain.com.error.log
Success! Your reverse proxy is now configured. Test it by visiting your domain in a web browser.

Important Tips

  • Always run sudo nginx -t before reloading to prevent breaking your server
  • DNS changes can take up to 48 hours to propagate globally
  • Keep your SSL certificates updated with sudo certbot renew
  • Monitor logs regularly to catch issues early

SSL Configuration

Let's Encrypt with Certbot

Install and configure free SSL certificates:

# Install Certbot

sudo apt install certbot python3-certbot-nginx

# Obtain certificate

sudo certbot --nginx -d example.com -d www.example.com

# Auto-renewal setup

sudo crontab -e
# Add: 0 12 * * * /usr/bin/certbot renew --quiet

SSL Server Block

Example SSL configuration:

Example SSL configuration:

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

    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 ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
    ssl_prefer_server_ciphers off;
    
    root /var/www/example.com;
    index index.html;

    location / {
        try_files $uri $uri/ =404;
    }
}

# HTTP to HTTPS redirect

server {
    listen 80;
    server_name example.com www.example.com;
    return 301 https://$server_name$request_uri;
}

Security Hardening

Security Headers

Add security headers to protect against common attacks:

Add security headers:

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header X-Content-Type-Options "nosniff" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
add_header Content-Security-Policy "default-src 'self' http: https: data: blob: 'unsafe-inline'" always;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Rate Limiting

Implement rate limiting to prevent abuse:

# In http block

limit_req_zone $binary_remote_addr zone=api:10m rate=10r/m;
limit_req_zone $binary_remote_addr zone=login:10m rate=1r/m;

# In server block

location /api/ {
    limit_req zone=api burst=20 nodelay;
    proxy_pass http://backend;
}

location /login {
    limit_req zone=login burst=5 nodelay;
    proxy_pass http://backend;
}

Hide Server Information

Hide Nginx version and server information:

# In http block

server_tokens off;

Performance Optimization

Gzip Compression

Enable gzip compression for better performance:

Enable gzip compression:

gzip on;
gzip_vary on;
gzip_min_length 1024;
gzip_proxied expired no-cache no-store private auth;
gzip_types
    text/plain
    text/css
    text/xml
    text/javascript
    application/x-javascript
    application/xml+rss
    application/javascript
    application/json;

Caching

Set up proxy caching for improved performance:

# In http block

proxy_cache_path /var/cache/nginx levels=1:2 keys_zone=my_cache:10m max_size=10g 
                 inactive=60m use_temp_path=off;

# In location block

location / {
    proxy_cache my_cache;
    proxy_pass http://backend;
    proxy_set_header Host $host;
    proxy_cache_bypass $http_pragma;
    proxy_cache_revalidate on;
    proxy_cache_min_uses 1;
    proxy_cache_use_stale error timeout updating http_500 http_502 http_503 http_504;
    proxy_cache_lock on;
    add_header X-Cache-Status $upstream_cache_status;
}

Worker Configuration

Optimize worker processes and connections:

# In main context

worker_processes auto;
worker_connections 1024;
worker_rlimit_nofile 2048;

# In events block

events {
    worker_connections 1024;
    use epoll;
    multi_accept on;
}

Troubleshooting

Common Issues

502 Bad Gateway

Usually indicates backend server is not responding:

  • Check if backend service is running
  • Verify proxy_pass URL is correct
  • Check firewall settings
  • Review error logs: tail -f /var/log/nginx/error.log

403 Forbidden

Permission or configuration issue:

  • Check file permissions: sudo chmod -R 755 /var/www/
  • Verify nginx user has access to files
  • Check directory index configuration

Useful Commands

# Test configuration

sudo nginx -t

# Reload configuration

sudo systemctl reload nginx

# Check status

sudo systemctl status nginx

# View access logs

tail -f /var/log/nginx/access.log

# View error logs

tail -f /var/log/nginx/error.log

# Check active connections

sudo netstat -tulpn | grep :80

Debug Tips

Enable debug logging temporarily by adding error_log /var/log/nginx/debug.log debug; to your server block. Remember to remove it after debugging as it can impact performance.