Step 5: Configure Reverse Proxy with Nginx

Lecture Slides

Either click on the slide area below or click here to view it in fullscreen. Use your keypad to navigate the slides.

A PDF printable handout version of the slides is available here

Introduction

In this step, you’ll configure Nginx as a reverse proxy for your Spring Boot application. This setup improves performance, provides better security, and enables you to serve static content efficiently while forwarding dynamic requests to your Java application.

Understanding Reverse Proxy Architecture

A reverse proxy sits between client requests and your Spring Boot application, acting as an intermediary that forwards requests to your backend service. This architecture provides several benefits:

  • Performance: Nginx can serve static content directly and cache responses
  • Security: Hides your application server details from external clients
  • Load Balancing: Can distribute requests across multiple application instances
  • SSL Termination: Handles SSL/TLS encryption and decryption
TipWhy Use Nginx with Spring Boot?

While Spring Boot has an embedded Tomcat server, using Nginx as a front-end proxy is a production best practice that improves scalability and security.

Installing and Configuring Nginx

Step 1: Install Nginx on Your Lightsail Instance

Connect to your Lightsail instance via SSH and install Nginx:

# Update package lists
sudo apt update

# Install Nginx
sudo apt install nginx -y

# Check if Nginx is running
sudo systemctl status nginx

# Enable Nginx to start on boot
sudo systemctl enable nginx

Step 2: Configure Firewall Rules

Update your Lightsail instance’s firewall to allow HTTP and HTTPS traffic:

# Allow HTTP traffic (port 80)
sudo ufw allow 'Nginx HTTP'

# Allow HTTPS traffic (port 443)
sudo ufw allow 'Nginx HTTPS'

# Check firewall status
sudo ufw status
NoteLightsail Networking Tab

Also ensure that ports 80 (HTTP) and 443 (HTTPS) are open in your Lightsail instance’s Networking tab in the AWS console.

Step 3: Create Nginx Configuration for Your Spring Boot App

Create a new Nginx server block configuration:

# Create configuration file
sudo nano /etc/nginx/sites-available/spring-boot-app

Add the following configuration:

server {
    listen 80;
    server_name your-domain.com www.your-domain.com;
    
    # 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 "no-referrer-when-downgrade" always;
    
    # Gzip compression
    gzip on;
    gzip_vary on;
    gzip_min_length 1024;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript application/javascript application/xml+rss application/json;
    
    # Static content location (if you have static assets)
    location /static/ {
        alias /home/ubuntu/app/static/;
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
    
    # Health check endpoint (bypass proxy for quick responses)
    location /actuator/health {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_connect_timeout 2s;
        proxy_read_timeout 2s;
    }
    
    # Main application proxy
    location / {
        proxy_pass http://localhost:8080;
        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;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 300s;
        proxy_connect_timeout 75s;
    }
    
    # Custom error pages
    error_page 502 503 504 /50x.html;
    location = /50x.html {
        root /var/www/html;
    }
}

Step 4: Enable the Configuration

# Create symbolic link to enable the site
sudo ln -s /etc/nginx/sites-available/spring-boot-app /etc/nginx/sites-enabled/

# Remove default Nginx site
sudo rm /etc/nginx/sites-enabled/default

# Test Nginx configuration
sudo nginx -t

# Reload Nginx to apply changes
sudo systemctl reload nginx

Advanced Nginx Configuration

Implementing Rate Limiting

Add rate limiting to protect your application from abuse:

# Add this to the http block in /etc/nginx/nginx.conf
http {
    # Rate limiting zones
    limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
    limit_req_zone $binary_remote_addr zone=api:10m rate=10r/s;
    limit_req_zone $binary_remote_addr zone=general:10m rate=1r/s;
    
    # Include your site configuration
    include /etc/nginx/sites-enabled/*;
}

Then update your site configuration to use rate limiting:

# Add these location blocks to your server configuration
location /api/auth/login {
    limit_req zone=login burst=3 nodelay;
    proxy_pass http://localhost:8080;
    # ... other proxy settings
}

location /api/ {
    limit_req zone=api burst=20 nodelay;
    proxy_pass http://localhost:8080;
    # ... other proxy settings
}

location / {
    limit_req zone=general burst=10 nodelay;
    proxy_pass http://localhost:8080;
    # ... other proxy settings
}

Setting Up Log Files

Configure custom log files for better monitoring:

server {
    # Custom log files
    access_log /var/log/nginx/spring-boot-app.access.log;
    error_log /var/log/nginx/spring-boot-app.error.log;
    
    # ... rest of configuration
}

Optimizing for Static Content

If your Spring Boot app serves static content, optimize Nginx for better performance:

# Add to your server block
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
    expires 1y;
    add_header Cache-Control "public, immutable";
    access_log off;
    try_files $uri @proxy;
}

location @proxy {
    proxy_pass http://localhost:8080;
    # ... other proxy settings
}

Testing Your Configuration

Step 1: Verify Nginx is Running

# Check Nginx status
sudo systemctl status nginx

# Check if Nginx is listening on port 80
sudo netstat -tlnp | grep :80

Step 2: Test the Reverse Proxy

# Test from your server (should show Spring Boot app response)
curl -I http://localhost

# Check Nginx logs
sudo tail -f /var/log/nginx/access.log
sudo tail -f /var/log/nginx/error.log

Step 3: Access from Browser

  1. Open your browser and navigate to your Lightsail instance’s public IP
  2. You should see your Spring Boot application served through Nginx
  3. Check the browser’s developer tools to verify response headers include Nginx security headers
WarningTroubleshooting Common Issues
  • 502 Bad Gateway: Your Spring Boot app isn’t running on port 8080
  • Connection refused: Check if ports 80/443 are open in Lightsail firewall
  • Configuration errors: Run sudo nginx -t to validate your config

Monitoring and Maintenance

Setting Up Log Rotation

Configure log rotation to prevent disk space issues:

# Create log rotation configuration
sudo nano /etc/logrotate.d/nginx-spring-boot

# Add the following content:
/var/log/nginx/spring-boot-app.*.log {
    daily
    missingok
    rotate 52
    compress
    notifempty
    create 0644 www-data www-data
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

Performance Monitoring

Monitor your reverse proxy performance:

# Check Nginx processes
ps aux | grep nginx

# Monitor active connections
curl http://localhost/nginx_status

# Check system resources
htop

Summary and Key Takeaways

In this step, you’ve successfully configured Nginx as a reverse proxy for your Spring Boot application. This setup provides:

  • Enhanced Security: Security headers and request filtering
  • Improved Performance: Static content serving and compression
  • Better Monitoring: Detailed logging and health checks
  • Production Readiness: Rate limiting and error handling

Key configuration points: - Nginx listens on port 80 and forwards requests to Spring Boot on port 8080 - Security headers protect against common web vulnerabilities - Gzip compression reduces bandwidth usage - Custom error pages provide better user experience - Rate limiting prevents abuse and DDoS attacks

Your application is now accessible through Nginx, providing a professional and secure front-end to your Spring Boot service. In the next step, we’ll add a custom domain and SSL certificate to complete your production deployment.