How to install Nginx on Ubuntu

Install Nginx, serve your first site from its own folder, and learn the three commands you will use every time you change its configuration.

2–4 minutes
Inside a rack server with expansion cards

Nginx is a fast, widely used web server. This guide installs it on Ubuntu 24.04 and sets up one site in its own folder. The same steps work on Debian 12.

1. Install

sudo apt update
sudo apt install nginx

Nginx starts automatically. Check it:

systemctl status nginx

2. Open the firewall

If you use UFW (see firewall setup), allow web traffic:

sudo ufw allow 'Nginx Full'

Visit http://your-server-ip and you should see the Nginx welcome page.

3. Create a folder for your site

sudo mkdir -p /var/www/example.com/public
echo '<h1>It works</h1>' | sudo tee /var/www/example.com/public/index.html

4. Add a server block

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

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

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

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

Enable it by linking it into sites-enabled:

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

5. Test and reload

These are the commands you will use after every configuration change:

sudo nginx -t
sudo systemctl reload nginx

nginx -t checks the configuration for mistakes. Only reload when it reports syntax is ok and test is successful. A reload applies the change without dropping visitors.

Once your domain points to the server, visit it to see your page.

Add PHP

Nginx does not run PHP itself; it passes PHP requests to PHP-FPM. Install it:

sudo apt install php-fpm php-mysql php-curl php-gd php-mbstring php-xml php-zip

The extensions after php-fpm cover what WordPress and most PHP software needs. Check which version was installed, because the socket name includes it:

ls /run/php/

You will see something like php8.3-fpm.sock. In your server block, change the location / line to pass unknown addresses to index.php, and add a PHP block that uses that socket:

location / {
    try_files $uri $uri/ /index.php?$args;
}

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.3-fpm.sock;
}

location ~ /\.(?!well-known) {
    deny all;
}

The last block hides files such as .env and .git, while still allowing /.well-known/ for certificate checks. Test and reload, then check PHP works by creating a test file, opening it in the browser, and deleting it straight afterwards, since it reveals server details:

echo '<?php phpinfo();' | sudo tee /var/www/example.com/public/info.php
sudo rm /var/www/example.com/public/info.php

Sensible extras

Add these inside the http block of /etc/nginx/nginx.conf, or in a file under /etc/nginx/conf.d/:

server_tokens off;
client_max_body_size 64M;
gzip on;
gzip_types text/css application/javascript application/json image/svg+xml;

server_tokens off stops Nginx advertising its version number. client_max_body_size raises the upload limit from the default 1 MB, which otherwise causes “413 Request Entity Too Large” errors on uploads; PHP’s own upload_max_filesize must be raised to match. gzip compresses text files, often to a fifth of their size.

Browsers can keep static files for longer if you tell them to:

location ~* \.(css|js|jpg|jpeg|png|webp|svg|woff2)$ {
    expires 30d;
    access_log off;
}

If something goes wrong

ProblemLikely cause
nginx -t failsA missing semicolon or brace; the error names the file and line
bind() to 0.0.0.0:80 failed (98: Address already in use)Apache or another program is using port 80
Still seeing the welcome pageThe default site is answering; remove /etc/nginx/sites-enabled/default or check server_name
PHP files download instead of runningThe PHP location block is missing or not matching
502 Bad GatewayPHP-FPM stopped, or the socket path is wrong
403 ForbiddenNo index file, or permissions on the site folder

Where things are

PathWhat it holds
/etc/nginx/nginx.confMain settings
/etc/nginx/sites-available/One file per site
/etc/nginx/sites-enabled/Links to the sites that are switched on
/var/log/nginx/access.logEvery request
/var/log/nginx/error.logProblems, the first place to look

Next

Add HTTPS with a free Let’s Encrypt certificate. To run PHP or an app behind Nginx, see reverse proxies.

Something out of date? Software changes. If a step no longer works, tell us and we will check it and update the page.