Nginx Setup on Raspberry Pi 5 – Complete Guide

Nginx Setup on Raspberry Pi 5 – Complete Guide

Prerequisites

  • Raspberry Pi 5 with Raspberry Pi OS installed
  • Internet connection
  • Terminal access (SSH or direct)

Step 1: Update System

bash

# Update package lists
sudo apt update

# Upgrade installed packages
sudo apt upgrade -y

# Reboot if kernel was updated
sudo reboot

Step 2: Install Nginx

bash

# Install Nginx
sudo apt install nginx -y

# Check Nginx version
nginx -v

# Output: nginx version: nginx/1.22.1 (or similar)

Step 3: Check Nginx Status

bash

# Check if Nginx is running
sudo systemctl status nginx

# Expected output:
# ● nginx.service - A high performance web server
#    Active: active (running)

Step 4: Enable Nginx to Start on Boot

bash

# Enable Nginx service
sudo systemctl enable nginx

# Start Nginx (if not already running)
sudo systemctl start nginx

# Verify it's enabled
sudo systemctl is-enabled nginx
# Output: enabled

Step 5: Configure Firewall (if using UFW)

bash

# Check if UFW is installed
sudo apt install ufw -y

# Allow Nginx through firewall
sudo ufw allow 'Nginx Full'

# Or allow specific ports
sudo ufw allow 80/tcp    # HTTP
sudo ufw allow 443/tcp   # HTTPS

# Enable firewall
sudo ufw enable

# Check status
sudo ufw status

Step 6: Find Your Raspberry Pi IP Address

bash

# Get IP address
hostname -I

# Or use
ip addr show

# Example output: 192.168.1.100

Step 7: Test Nginx Installation

Option A: From Raspberry Pi (command line)

bash

# Test with curl
curl http://localhost

# Should show HTML of Nginx welcome page

Option B: From another device on network

Open browser and visit:
http://YOUR_PI_IP_ADDRESS

Example: http://192.168.1.100

You should see: “Welcome to nginx!” page


Step 8: Nginx Directory Structure

bash

# Main configuration file
/etc/nginx/nginx.conf

# Site configurations
/etc/nginx/sites-available/    # Available sites
/etc/nginx/sites-enabled/      # Enabled sites (symlinks)

# Web root (default)
/var/www/html/

# Logs
/var/log/nginx/access.log      # Access logs
/var/log/nginx/error.log       # Error logs

Step 9: Create Your First Website

Create Project Directory

bash

# Create directory for your site
sudo mkdir -p /var/www/mysite

# Set ownership
sudo chown -R $USER:$USER /var/www/mysite

# Set permissions
sudo chmod -R 755 /var/www/mysite

Create HTML File

bash

# Create index.html
nano /var/www/mysite/index.html

Add this content:

html

<!DOCTYPE html>
<html>
<head>
    <title>My Raspberry Pi Site</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            max-width: 800px;
            margin: 50px auto;
            padding: 20px;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }
        .container {
            background: rgba(255, 255, 255, 0.1);
            padding: 40px;
            border-radius: 10px;
            backdrop-filter: blur(10px);
        }
        h1 { margin-top: 0; }
    </style>
</head>
<body>
    <div class="container">
        <h1>🍓 Welcome to My Raspberry Pi 5!</h1>
        <p>This website is running on Nginx web server.</p>
        <p>Server Time: <span id="time"></span></p>
    </div>
    <script>
        setInterval(() => {
            document.getElementById('time').textContent = new Date().toLocaleString();
        }, 1000);
    </script>
</body>
</html>

Save: Ctrl+O, Enter, Ctrl+X


Step 10: Configure Nginx Server Block

bash

# Create new site configuration
sudo nano /etc/nginx/sites-available/mysite

Add this configuration:

nginx

server {
    listen 80;
    listen [::]:80;

    server_name mysite.local 192.168.1.100;  # Replace with your Pi's IP

    root /var/www/mysite;
    index index.html index.htm;

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

    # Logging
    access_log /var/log/nginx/mysite-access.log;
    error_log /var/log/nginx/mysite-error.log;
}

Save: Ctrl+O, Enter, Ctrl+X


Step 11: Enable the Site

bash

# Create symbolic link to enable site
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/

# Optional: Disable default site
sudo unlink /etc/nginx/sites-enabled/default

# Test Nginx configuration
sudo nginx -t

# Expected output:
# nginx: configuration file /etc/nginx/nginx.conf test is successful

Step 12: Reload Nginx

bash

# Reload Nginx to apply changes
sudo systemctl reload nginx

# Or restart
sudo systemctl restart nginx

# Check status
sudo systemctl status nginx

Step 13: Test Your Site

Visit in browser:

http://YOUR_PI_IP_ADDRESS

You should see your custom HTML page!


Step 14: Configure Multiple Sites (Virtual Hosts)

Create Second Site

bash

# Create directory
sudo mkdir -p /var/www/site2
sudo chown -R $USER:$USER /var/www/site2

# Create HTML file
nano /var/www/site2/index.html

Add content:

html

<!DOCTYPE html>
<html>
<head>
    <title>Site 2</title>
</head>
<body>
    <h1>This is Site 2</h1>
</body>
</html>

Create Configuration

bash

sudo nano /etc/nginx/sites-available/site2

Add:

nginx

server {
    listen 8080;
    listen [::]:8080;

    server_name site2.local;

    root /var/www/site2;
    index index.html;

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

Enable Site

bash

# Enable site
sudo ln -s /etc/nginx/sites-available/site2 /etc/nginx/sites-enabled/

# Allow port in firewall
sudo ufw allow 8080/tcp

# Test and reload
sudo nginx -t
sudo systemctl reload nginx

Access: http://YOUR_PI_IP:8080


Step 15: Set Up SSL/HTTPS (Optional)

Using Self-Signed Certificate

bash

# Create SSL directory
sudo mkdir -p /etc/nginx/ssl

# Generate self-signed certificate
sudo openssl req -x509 -nodes -days 365 -newkey rsa:2048 \
  -keyout /etc/nginx/ssl/nginx-selfsigned.key \
  -out /etc/nginx/ssl/nginx-selfsigned.crt

# During prompts, fill in your information

Update Nginx Configuration

bash

sudo nano /etc/nginx/sites-available/mysite

Update to:

nginx

server {
    listen 80;
    listen [::]:80;
    server_name mysite.local;
    return 301 https://$server_name$request_uri;
}

server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;

    server_name mysite.local;

    ssl_certificate /etc/nginx/ssl/nginx-selfsigned.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx-selfsigned.key;

    root /var/www/mysite;
    index index.html;

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

Reload Nginx:

bash

sudo nginx -t
sudo systemctl reload nginx

Access: https://YOUR_PI_IP (you’ll see a security warning because it’s self-signed)


Useful Nginx Commands

bash

# Start Nginx
sudo systemctl start nginx

# Stop Nginx
sudo systemctl stop nginx

# Restart Nginx
sudo systemctl restart nginx

# Reload configuration (no downtime)
sudo systemctl reload nginx

# Check status
sudo systemctl status nginx

# Test configuration
sudo nginx -t

# View error log
sudo tail -f /var/log/nginx/error.log

# View access log
sudo tail -f /var/log/nginx/access.log

# Enable service on boot
sudo systemctl enable nginx

# Disable service on boot
sudo systemctl disable nginx

Performance Optimization for Raspberry Pi

Edit Main Configuration

bash

sudo nano /etc/nginx/nginx.conf

Optimize for Raspberry Pi:

nginx

user www-data;
worker_processes 4;  # Raspberry Pi 5 has 4 cores
pid /run/nginx.pid;

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

http {
    # Basic Settings
    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;
    server_tokens off;

    # Gzip Compression
    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types text/plain text/css text/xml text/javascript 
               application/json application/javascript application/xml+rss;

    # Logging
    access_log /var/log/nginx/access.log;
    error_log /var/log/nginx/error.log;

    # Virtual Host Configs
    include /etc/nginx/conf.d/*.conf;
    include /etc/nginx/sites-enabled/*;
}

Test and reload:

bash

sudo nginx -t
sudo systemctl reload nginx

Serve PHP Applications (Optional)

bash

# Install PHP
sudo apt install php-fpm php-mysql -y

# Check PHP version
php -v

# Edit site configuration
sudo nano /etc/nginx/sites-available/mysite

Add PHP support:

nginx

server {
    listen 80;
    server_name mysite.local;

    root /var/www/mysite;
    index index.php index.html;

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

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/var/run/php/php8.2-fpm.sock;  # Check your PHP version
    }

    location ~ /\.ht {
        deny all;
    }
}

Test PHP:

bash

# Create PHP test file
nano /var/www/mysite/info.php

Add:

php

<?php
phpinfo();
?>

Reload Nginx:

bash

sudo systemctl reload nginx

Visit: http://YOUR_PI_IP/info.php


Security Best Practices

bash

# Change default Nginx user permissions
sudo nano /etc/nginx/nginx.conf

Add security headers:

nginx

# Add inside http block
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;

Disable directory listing:

nginx

# Add inside server block
autoindex off;

Reload:

bash

sudo systemctl reload nginx

Monitoring Resources

bash

# Check memory usage
free -h

# Check CPU usage
top

# Monitor Nginx processes
ps aux | grep nginx

# Check disk space
df -h

# Monitor logs in real-time
sudo tail -f /var/log/nginx/access.log

Troubleshooting

Nginx won’t start

bash

# Check configuration
sudo nginx -t

# Check error log
sudo tail -50 /var/log/nginx/error.log

# Check if port 80 is in use
sudo netstat -tulpn | grep :80

Permission Denied

bash

# Fix ownership
sudo chown -R www-data:www-data /var/www/mysite

# Fix permissions
sudo chmod -R 755 /var/www/mysite

Can’t Access from Other Devices

bash

# Check firewall
sudo ufw status

# Allow HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp

# Check Nginx is listening
sudo netstat -tulpn | grep nginx

Quick Reference

TaskCommand
Install Nginxsudo apt install nginx -y
Start Nginxsudo systemctl start nginx
Stop Nginxsudo systemctl stop nginx
Restart Nginxsudo systemctl restart nginx
Reload Configsudo systemctl reload nginx
Test Configsudo nginx -t
Check Statussudo systemctl status nginx
View Error Logsudo tail -f /var/log/nginx/error.log
Enable on Bootsudo systemctl enable nginx

Summary

You now have:

  • ✅ Nginx installed and running
  • ✅ Custom website configured
  • ✅ Multiple sites capability
  • ✅ SSL/HTTPS setup (optional)
  • ✅ PHP support (optional)
  • ✅ Performance optimized
  • ✅ Security hardened

Your Raspberry Pi 5 is now a fully functional web server! 🎉

Next steps:

  • Set up a domain name
  • Configure port forwarding for external access
  • Install a database (MySQL/MariaDB)
  • Deploy actual web applications
  • Set up automatic backups

Enjoy your Raspberry Pi web server! 🍓

Comments

No comments yet. Why don’t you start the discussion?

Leave a Reply

Your email address will not be published. Required fields are marked *