Nginx is the most widely used web server on Linux servers: fast at static files, efficient under heavy concurrency, and an excellent reverse proxy for Node.js, Python, PHP and Docker apps. This guide installs it on Ubuntu and walks through the parts you need to know before you host a real site.

1. Install Nginx

Ubuntu’s repositories carry a stable, security-patched Nginx:

sudo apt update
sudo apt install -y nginx

The service starts immediately and is enabled at boot. Check it:

systemctl status nginx --no-pager
nginx -v

Want the newest version? The nginx.org repository offers the current “mainline” and “stable” branches. For most servers, Ubuntu’s package is the better choice: it receives security backports through normal updates and uses Ubuntu’s familiar sites-available layout.

2. Open the firewall

If UFW is enabled, allow HTTP and HTTPS. The Nginx package registers application profiles:

sudo ufw app list
sudo ufw allow 'Nginx Full'     # ports 80 and 443
sudo ufw status

Make sure SSH is also allowed (sudo ufw allow OpenSSH) before enabling UFW. More in the UFW guide.

3. Test in a browser

Visit http://YOUR_SERVER_IP. You should see the “Welcome to nginx!” page. From the server itself:

curl -I http://localhost

A HTTP/1.1 200 OK with Server: nginx confirms it’s serving.

4. Understand the configuration layout

Path Purpose
/etc/nginx/nginx.conf Main config: worker settings, global http {} options, includes
/etc/nginx/sites-available/ One file per site (server block)
/etc/nginx/sites-enabled/ Symlinks to the sites that are active
/etc/nginx/conf.d/*.conf Extra config included in http {}
/etc/nginx/snippets/ Reusable fragments (e.g. SSL settings)
/var/www/html Default document root
/var/log/nginx/access.log, error.log Logs

A site is enabled by symlinking its file from sites-available into sites-enabled.

5. Host your first site

Create a document root and a page:

sudo mkdir -p /var/www/example.com/html
echo '<h1>example.com works</h1>' | sudo tee /var/www/example.com/html/index.html
sudo chown -R www-data:www-data /var/www/example.com

Create /etc/nginx/sites-available/example.com:

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;

    root /var/www/example.com/html;
    index index.html;

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

    access_log /var/log/nginx/example.com.access.log;
    error_log  /var/log/nginx/example.com.error.log;
}

Enable it, test, reload:

sudo ln -s /etc/nginx/sites-available/example.com /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx

Point the domain’s DNS A record (and AAAA for IPv6) at your server, and the site is live. Hosting several domains works the same way — see Nginx server blocks.

6. Add HTTPS

Install a free Let’s Encrypt certificate with Certbot; it edits the server block for you and sets up renewal:

sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

Full walkthrough in Let’s Encrypt with Certbot on Nginx.

7. Managing the service

sudo nginx -t                    # test config syntax — always before reloading
sudo systemctl reload nginx      # apply config changes without dropping connections
sudo systemctl restart nginx     # full restart
sudo systemctl stop nginx
sudo systemctl disable nginx     # don't start at boot

Prefer reload over restart: it starts new workers with the new config and lets old ones finish their requests.

8. A few global settings worth changing

In /etc/nginx/nginx.conf, inside http {}:

server_tokens off;            # hide the version number in headers and error pages
client_max_body_size 20m;     # allow larger uploads (default is 1 MB)
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;

worker_processes auto; (the Ubuntu default) already starts one worker per CPU core.

Troubleshooting

nginx: [emerg] bind() to 0.0.0.0:80 failed (98: Address already in use) — another program (often Apache) holds port 80. Find it with sudo ss -tlnp | grep ':80' and stop or reconfigure it.

The default page still appears for your domain — your server_name doesn’t match, or the site isn’t enabled. Check ls -l /etc/nginx/sites-enabled/ and remove the default symlink once your own site works.

403 Forbidden — usually missing index.html or permissions. See fixing Nginx 403 Forbidden.

502 Bad Gateway — Nginx is proxying to an app that isn’t running. See fixing Nginx 502.

Always check the error log first:

sudo tail -n 50 /var/log/nginx/error.log

Next steps

Every Ubuntu VPS we offer comes with full root access, so you can follow these steps as soon as the server is ready.

  • Nginx
  • Ubuntu
  • Web Server