Introduction
Nginx is one of the most popular web servers in the world and is responsible for hosting some of the largest and highest-traffic sites on the internet. It is generally lighter on resources than Apache and can be used as a web server or a reverse proxy.
In this guide we will install Nginx on an Ubuntu server, adjust the firewall, verify the installation, learn the day-to-day service commands, and set up a server block so that one server can host multiple domains.
Prerequisites
To follow this tutorial, you will need:
- A server running Ubuntu 20.04 or 22.04.
- A regular user with
sudoprivileges. - (Optional) A domain name pointing at your server's IP address if you want to set up a server block in Step 5.
Step 1 — Installing Nginx
Nginx is available in Ubuntu's default repositories, so you can install it straight from apt. Start by refreshing the package index:
sudo apt updateThen install the nginx package:
sudo apt install nginxPress Y and ENTER to confirm. apt installs Nginx and any required dependencies.
Step 2 — Adjusting the Firewall
Before testing Nginx, the ufw firewall needs to allow connections to it. On installation, Nginx registers a few application profiles with ufw so opening ports is straightforward.
List the profiles ufw knows about:
sudo ufw app listYou should see output like this:
Output
Available applications:
Nginx Full
Nginx HTTP
Nginx HTTPS
OpenSSHThere are three Nginx profiles:
- Nginx Full: opens both port 80 (HTTP) and port 443 (HTTPS).
- Nginx HTTP: opens only port 80.
- Nginx HTTPS: opens only port 443.
It is recommended to enable the most restrictive profile that still allows the traffic you need. Since we have not configured SSL yet, only allow port 80 for now:
sudo ufw allow 'Nginx HTTP'If ufw is not enabled yet, make sure you allow SSH first so you do not lock yourself out, then enable the firewall:
sudo ufw allow OpenSSH
sudo ufw enableVerify the status:
sudo ufw statusOutput
Status: active
To Action From
-- ------ ----
OpenSSH ALLOW Anywhere
Nginx HTTP ALLOW Anywhere
OpenSSH (v6) ALLOW Anywhere (v6)
Nginx HTTP (v6) ALLOW Anywhere (v6)Step 3 — Checking Your Web Server
Ubuntu starts Nginx automatically after installation. Check with systemd:
systemctl status nginxOutput
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; vendor preset: enabled)
Active: active (running) since Mon 2026-09-01 08:12:31 UTC; 2min 5s ago
Docs: man:nginx(8)
Main PID: 2369 (nginx)
Tasks: 2 (limit: 1153)
Memory: 3.5M
CGroup: /system.slice/nginx.service
├─2369 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
└─2380 nginx: worker processThe most reliable test is to request a page from the server in your browser. If you do not know your server's public IP address, run:
curl -4 icanhazip.comThen open your browser and visit:
http://your_server_ipYou should see the default "Welcome to nginx!" landing page. This confirms Nginx is installed and running correctly.
Step 4 — Managing the Nginx Process
Here are the service commands you will use most often.
Stop the web server:
sudo systemctl stop nginxStart the web server:
sudo systemctl start nginxRestart it (stop and start, dropping open connections):
sudo systemctl restart nginxIf you only changed configuration files, use reload instead of restart. Nginx picks up the new configuration without dropping active connections:
sudo systemctl reload nginxNginx is enabled to start on boot by default. To turn that off:
sudo systemctl disable nginxAnd to turn it back on:
sudo systemctl enable nginxGet into the habit of testing the configuration syntax before every reload so a typo never takes Nginx down:
sudo nginx -tOutput
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successfulStep 5 — Setting Up a Server Block
Nginx uses server blocks (similar to Apache's virtual hosts) to serve multiple domains from a single server. In the example below we create a server block for the domain your_domain. Replace it with your real domain name.
By default Nginx serves content from /var/www/html. Rather than modifying that directory, create a separate one for each domain:
sudo mkdir -p /var/www/your_domain/htmlAssign ownership to the current user:
sudo chown -R $USER:$USER /var/www/your_domain/html
sudo chmod -R 755 /var/www/your_domainCreate a sample index.html page:
nano /var/www/your_domain/html/index.htmlPaste in the following:
<html>
<head>
<title>Welcome to your_domain!</title>
</head>
<body>
<h1>Success! The your_domain server block is working!</h1>
</body>
</html>Next, create a new server block configuration file in sites-available:
sudo nano /etc/nginx/sites-available/your_domainPaste in the following configuration:
server {
listen 80;
listen [::]:80;
root /var/www/your_domain/html;
index index.html index.htm index.nginx-debian.html;
server_name your_domain www.your_domain;
location / {
try_files $uri $uri/ =404;
}
}Notice that root points at the new directory and server_name matches your domain.
Enable the server block by creating a symbolic link from sites-available to sites-enabled, the directory Nginx reads on startup:
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/Two server blocks are now enabled: the default block answers requests on port 80 that do not match any other domain, and the your_domain block answers requests for your domain.
To avoid a hash bucket memory warning once you add more domains, open nginx.conf:
sudo nano /etc/nginx/nginx.confFind the server_names_hash_bucket_size directive and remove the # in front of it:
http {
...
server_names_hash_bucket_size 64;
...
}Test the syntax and reload Nginx:
sudo nginx -t
sudo systemctl reload nginxOpen http://your_domain in your browser and you should see the "Success!" page you just created.
Step 6 — Important Nginx Files and Directories
Now that you know the basics, it helps to know where the important files live.
Content
/var/www/html: the default web root. Can be changed in the configuration.
Configuration
/etc/nginx: the Nginx configuration directory./etc/nginx/nginx.conf: the main configuration file with global settings./etc/nginx/sites-available/: where server blocks are stored. Nginx ignores these unless they are linked intosites-enabled./etc/nginx/sites-enabled/: enabled server blocks, usually symbolic links to files insites-available./etc/nginx/snippets: reusable configuration fragments.
Logs
/var/log/nginx/access.log: every request to the web server./var/log/nginx/error.log: Nginx errors.
To follow the log in real time while debugging:
sudo tail -f /var/log/nginx/error.logConclusion
You have installed Nginx, opened the firewall, learned how to manage the service and set up a server block for your own domain. Next steps:
- Add a free SSL certificate with Let's Encrypt: How To Secure Nginx with Let's Encrypt on Ubuntu.
- Use Nginx as a reverse proxy for a Node.js or Next.js app: How To Deploy a Next.js App on an Ubuntu VPS with PM2 and Nginx.
- Pair Nginx with PHP-FPM and MySQL to complete a LEMP stack.

