Quick Answer: Ubuntu/Debian:
sudo apt install nginx -y && sudo systemctl enable --now nginx. Visithttp://your-server-ip— you should see the Nginx welcome page. For HTTPS:sudo apt install certbot python3-certbot-nginx -y && sudo certbot --nginx -d yourdomain.com.
Need a VPS? Vultr (free credit), DigitalOcean ($200 free credit), or RackNerd (cheap annual deals).
What Is Nginx?
Nginx (pronounced "engine-x") is the most popular web server in the world. It handles:
- Serving websites — HTML, CSS, JavaScript, images
- Reverse proxy — forward requests to backend apps (Node.js, Python, etc.)
- Load balancing — distribute traffic across multiple servers
- SSL/TLS termination — handle HTTPS certificates
- Caching — speed up responses by caching content
It's fast, lightweight, and handles thousands of concurrent connections with minimal memory.
Install on Ubuntu/Debian
sudo apt update
sudo apt install nginx -y
Start and Enable
# Start Nginx
sudo systemctl start nginx
# Enable auto-start on boot
sudo systemctl enable nginx
# Check status
sudo systemctl status nginx
Allow Through Firewall
sudo ufw allow 'Nginx Full' # Allows both HTTP (80) and HTTPS (443)
# Or individually:
# sudo ufw allow 80/tcp
# sudo ufw allow 443/tcp
Verify
Open your browser and visit http://your-server-ip. You should see the "Welcome to nginx!" page.
# Or test from the command line
curl -I http://localhost
# HTTP/1.1 200 OK
Install on CentOS/RHEL/Fedora
sudo dnf install nginx -y
Start and Enable
sudo systemctl start nginx
sudo systemctl enable nginx
Allow Through Firewall
sudo firewall-cmd --permanent --add-service=http
sudo firewall-cmd --permanent --add-service=https
sudo firewall-cmd --reload
Nginx Files and Directories
Understanding where things are:
| Path | What It Is |
|---|---|
/etc/nginx/nginx.conf |
Main configuration file |
/etc/nginx/sites-available/ |
Available site configs (Ubuntu/Debian) |
/etc/nginx/sites-enabled/ |
Active site configs (symlinked from sites-available) |
/etc/nginx/conf.d/ |
Additional config files (CentOS/RHEL) |
/var/www/html/ |
Default web root (where your website files go) |
/var/log/nginx/access.log |
Access log (every request) |
/var/log/nginx/error.log |
Error log (problems and warnings) |
CentOS/RHEL note: CentOS uses /etc/nginx/conf.d/ instead of sites-available/sites-enabled/. Create .conf files directly in conf.d/.
Serve Your First Website
Create Website Files
sudo mkdir -p /var/www/mysite
sudo nano /var/www/mysite/index.html
<!DOCTYPE html>
<html>
<head><title>My Site</title></head>
<body><h1>Hello from Nginx!</h1></body>
</html>
Create Nginx Config
sudo nano /etc/nginx/sites-available/mysite
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
root /var/www/mysite;
index index.html;
location / {
try_files $uri $uri/ =404;
}
}
Enable the Site
# Create symlink to enable
sudo ln -s /etc/nginx/sites-available/mysite /etc/nginx/sites-enabled/
# Remove default site (optional)
sudo rm /etc/nginx/sites-enabled/default
# Test configuration for errors
sudo nginx -t
# Reload Nginx
sudo systemctl reload nginx
On CentOS: Create the file at /etc/nginx/conf.d/mysite.conf instead. No symlink needed.
Your site is now live at http://yourdomain.com (once DNS points to your server).
Set Up HTTPS with Let's Encrypt
Free SSL certificates with automatic renewal:
# Install Certbot
sudo apt install certbot python3-certbot-nginx -y # Ubuntu/Debian
# sudo dnf install certbot python3-certbot-nginx -y # CentOS/Fedora
# Get certificate and auto-configure Nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Certbot will:
- Verify you own the domain
- Get a free certificate from Let's Encrypt
- Modify your Nginx config to use HTTPS
- Set up automatic renewal (runs twice daily)
Verify Auto-Renewal
sudo certbot renew --dry-run
Check Certificate
sudo certbot certificates
Your site is now at https://yourdomain.com with automatic HTTP → HTTPS redirect.
Reverse Proxy (Proxy to Backend App)
If you're running a backend app (Node.js, Python, Go) on a port like 3000, use Nginx as a reverse proxy:
sudo nano /etc/nginx/sites-available/myapp
server {
listen 80;
server_name app.yourdomain.com;
location / {
proxy_pass http://localhost:3000;
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;
}
}
sudo ln -s /etc/nginx/sites-available/myapp /etc/nginx/sites-enabled/
sudo nginx -t && sudo systemctl reload nginx
# Then add HTTPS
sudo certbot --nginx -d app.yourdomain.com
Full guide: Nginx Reverse Proxy
Common Configuration
Increase Upload Size
Default max upload is 1MB. Increase it:
# In server or http block
client_max_body_size 50M;
Enable Gzip Compression
Add to /etc/nginx/nginx.conf inside the http block:
gzip on;
gzip_types text/plain text/css application/json application/javascript text/xml application/xml text/javascript;
gzip_min_length 1000;
gzip_comp_level 5;
Custom Error Pages
server {
# ...
error_page 404 /404.html;
error_page 500 502 503 504 /50x.html;
location = /404.html {
root /var/www/mysite;
internal;
}
}
Redirect www to non-www
server {
listen 80;
server_name www.yourdomain.com;
return 301 https://yourdomain.com$request_uri;
}
Manage Nginx
# Test config (always do this before reload!)
sudo nginx -t
# Reload config (no downtime)
sudo systemctl reload nginx
# Restart (brief downtime)
sudo systemctl restart nginx
# Stop
sudo systemctl stop nginx
# View access log
sudo tail -f /var/log/nginx/access.log
# View error log
sudo tail -f /var/log/nginx/error.log
Troubleshooting
# Test config syntax
sudo nginx -t
# Check if Nginx is running
sudo systemctl status nginx
# Check what's listening on port 80
ss -tlnp | grep :80
# Check error log
sudo tail -20 /var/log/nginx/error.log
| Problem | Fix |
|---|---|
Welcome to nginx still showing |
Remove default: sudo rm /etc/nginx/sites-enabled/default && sudo systemctl reload nginx |
nginx: [emerg] bind() to 0.0.0.0:80 failed |
Apache or another service is using port 80. Stop it: sudo systemctl stop apache2 |
403 Forbidden |
Check file permissions: sudo chown -R www-data:www-data /var/www/mysite and chmod 755 on directories |
502 Bad Gateway |
Backend app not running. Check: curl http://localhost:3000 |
413 Request Entity Too Large |
Add client_max_body_size 50M; to your server block |
| Config test fails | Check syntax: sudo nginx -t — it tells you exactly which line has the error |
Uninstall Nginx
# Ubuntu/Debian
sudo apt purge nginx nginx-common -y
sudo rm -rf /etc/nginx
# CentOS
sudo dnf remove nginx -y
Related Guides
- Nginx Cheat Sheet — every directive
- Nginx Reverse Proxy — proxy backend apps
- Complete Nginx Guide — deep dive
- Nginx vs Apache — comparison
- SSL/TLS Explained — understand certificates
- Server Hardening Guide — secure your server
- Cloudflare Setup — CDN in front of Nginx
- How to Install Docker — containerized alternative