How to Install Nginx on Ubuntu, Debian, and CentOS

5 min read
Beginner Nginx Linux Web Server Installation How To

Prerequisites

  • A Linux server (Ubuntu, Debian, CentOS, or Fedora)
  • sudo/root access
  • A domain name (for HTTPS setup)

Quick Answer: Ubuntu/Debian: sudo apt install nginx -y && sudo systemctl enable --now nginx. Visit http://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:

  1. Verify you own the domain
  2. Get a free certificate from Let's Encrypt
  3. Modify your Nginx config to use HTTPS
  4. 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