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
| Task | Command |
|---|---|
| Install Nginx | sudo apt install nginx -y |
| Start Nginx | sudo systemctl start nginx |
| Stop Nginx | sudo systemctl stop nginx |
| Restart Nginx | sudo systemctl restart nginx |
| Reload Config | sudo systemctl reload nginx |
| Test Config | sudo nginx -t |
| Check Status | sudo systemctl status nginx |
| View Error Log | sudo tail -f /var/log/nginx/error.log |
| Enable on Boot | sudo 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! 🍓
