Nginx serves websites, acts as a reverse proxy for backend applications, and handles load balancing across multiple servers. Whether you need to host WordPress sites, serve a Python or Node.js application behind a reverse proxy, or run static file hosting for your projects, Nginx handles these tasks efficiently while using minimal system resources. Before starting, ensure you have SSH access to your Ubuntu server if working remotely.
This guide walks you through how to install Nginx on Ubuntu, configure firewall rules, set up server blocks for hosting domains, and secure your site with free SSL certificates from Let’s Encrypt. By the end, you will have a fully functional web server ready for production use.
Update Ubuntu Before Nginx Installation
It is crucial to ensure that your system is up-to-date before starting the installation process. This practice helps prevent conflicts during the installation or configuration of Nginx.
To update your system, run the following command:
sudo apt update && sudo apt upgrade
Nginx is available in the Ubuntu repository by default, simplifying the installation process. However, if you prefer to install the Nginx mainline or a newer version of Nginx stable, refer to our tutorial, “How to Install Nginx Mainline on Ubuntu,” and then return here to complete the configuration and setup. Advanced users can also build Nginx from source on Ubuntu for complete control over compilation flags.
Choose Your Nginx Package
Ubuntu offers three Nginx packages with different module sets. Choose based on your requirements:
| Package | Channel | Modules Included | Best For |
|---|---|---|---|
| nginx | Ubuntu Repos | Core modules only (gzip, SSL, proxy, rewrite) | Most users running standard web servers |
| nginx-full | Ubuntu Repos | Core + additional modules (auth, geoip, image filter, DAV) | Users needing extended functionality |
| nginx-extras | Ubuntu Repos | Full + third-party modules (Lua, Perl, fancy index) | Advanced users who will stay on Ubuntu packages |
For most users, the standard nginx package is recommended because it includes all essential modules and allows upgrading to Nginx mainline later. The nginx-extras package locks you into Ubuntu’s packaged version since its third-party modules are not compatible with upstream Nginx releases.
Install Nginx on Ubuntu
Option 1: Install Standard Nginx Package
The standard nginx package includes all essential modules and is recommended for most users. Install it with:
sudo apt install nginx -y
Option 2: Install Nginx-Full Package
The nginx-full package includes additional modules like auth, geoip, image filter, and DAV. Install it with:
sudo apt install nginx nginx-full -y
Option 3: Install Nginx-Extras Package
The nginx-extras package adds third-party modules including Lua, Perl, and fancy index. Install it with:
sudo apt install nginx-extras -y
Note: Only install nginx-extras if you intend to retain the Ubuntu version of Nginx. Avoid this package if you plan to upgrade to upstream Nginx from Nginx.org or the official Launchpad PPA.
Verify Nginx Installation
After completing the installation, check the installed version:
nginx -v
You should see output similar to:
nginx version: nginx/1.24.0 (Ubuntu)
Verify the service is running:
systemctl status nginx
The output should show the service as active:
● nginx.service - A high performance web server and a reverse proxy server
Loaded: loaded (/lib/systemd/system/nginx.service; enabled; preset: enabled)
Active: active (running) since Sun 2025-11-30 10:00:00 UTC; 1min ago

If, by some chance, the service is not active, use the following command to activate the Nginx service immediately.
sudo systemctl enable nginx --now
Configure UFW Firewall For Nginx
Ubuntu uses UFW (Uncomplicated Firewall) as its default firewall. For public-facing web servers, configuring UFW rules is essential for added security.
Install UFW
To install UFW, run the following command:
sudo apt install ufw -y
Enable UFW
Enable UFW using this command:
sudo ufw enable
You will see a warning about disrupting SSH connections. Type y to confirm:
Command may disrupt existing ssh connections. Proceed with operation (y|n)? y Firewall is active and enabled on system startup
By default, UFW blocks all incoming connections and allows all outgoing connections.
View Available UFW Application Profiles
List the application profiles that UFW recognizes:
sudo ufw app list
You should see Nginx profiles in the output:
Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH
Configure UFW Rules for Nginx
You can configure UFW to allow connections to Nginx on HTTP (Port 80), HTTPS (Port 443), or both (Full).
HTTP (Port 80) only:
sudo ufw allow 'Nginx HTTP'
HTTPS (Port 443) only:
sudo ufw allow 'Nginx HTTPS'
Allow both HTTP and HTTPS (Full):
sudo ufw allow 'Nginx FULL'
Confirm the firewall rules are active with the following command.
sudo ufw status
You should see output showing Nginx is allowed:
Status: active To Action From -- ------ ---- Nginx Full ALLOW Anywhere Nginx Full (v6) ALLOW Anywhere (v6)
For a more comprehensive guide on firewall configuration, see How to Install and Configure UFW Firewall on Ubuntu.
Test Nginx Access in Browser
To see if everything is working, open your web browser and go to your server’s IP address. If you don’t have a domain name pointed at your server, use the server’s IP address: http://your_server_ip
Alternatively, try accessing http://localhost if testing locally.
If you’ve set up everything correctly, the Nginx default landing page should appear.
Create and Configure Nginx Directory For Website
Unlike Apache virtual hosts, Nginx server blocks allow you to host multiple domains on a single server by encapsulating configuration details. We’ll use the example domain example.com in this tutorial, but you should replace this with your domain name.
Nginx comes with a pre-configured www directory located at /var/www/html/.
Create a Directory for Your Domain
First, create a directory for your domain using the -p flag to create any necessary parent directories (see mkdir command examples for more options):
sudo mkdir -p /var/www/example.com/
Assign Ownership For Nginx Directory
Next, assign ownership of the directory to the appropriate user and group:
sudo chown -R www-data:www-data /var/www/example.com/
Setup Test HTML Page For Nginx
Create a test page to confirm that your Nginx server is working correctly:
sudo nano /var/www/example.com/index.html
Inside the nano editor, paste the following HTML code to create a simple test page:
<html>
<head>
<title>Welcome to Linuxcapable.com</title>
</head>
<body>
<h1>Success! The tutorial server block is working! Thanks Linuxcapable.com :D</h1>
</body>
</html>
Save the file with CTRL+O and exit with CTRL+X.
Create Nginx Server Block
Now, create a server block for your website:
sudo nano /etc/nginx/sites-available/example.com.conf
Paste the following example code into the configuration file. This is a basic HTTP-only example for testing purposes:
server {
listen 80;
listen [::]:80;
root /var/www/example.com/;
index index.html index.htm index.nginx-debian.html;
server_name example.com www.example.com;
location / {
try_files $uri $uri/ =404;
}
}
This configuration listens on port 80 for both example.com and www.example.com. Replace example.com with your actual domain name throughout. For URL manipulation, see our guide on Nginx rewrite rules.
Enable Nginx Server Block
To enable the Nginx server block, you need to create a symbolic link from the sites-available directory to the sites-enabled directory in your Nginx installation:
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/
Verify the symlink was created:
ls -la /etc/nginx/sites-enabled/
lrwxrwxrwx 1 root root 43 Nov 30 10:00 example.com.conf -> /etc/nginx/sites-available/example.com.conf
Remember to replace example.com with your actual domain name throughout these steps.
For a complete web application stack, see our guide on installing WordPress with Nginx on Ubuntu. To improve performance for PHP applications, consider setting up FastCGI caching. You may also want to install PHP and MariaDB to complete a LEMP stack.
Configure Server Names Hash and Test Configuration
Before activating your server block, adjust the Nginx configuration to handle long domain names and test for syntax errors.
Edit Nginx Configuration File
Open the default nginx.conf file:
sudo nano /etc/nginx/nginx.conf
Find the following line within the http {} section of the nginx.conf file and uncomment it:
server_names_hash_bucket_size 64;
Save the changes with CTRL+O and exit with CTRL+X.
The server_names_hash_bucket_size directive increases the memory allocated for parsing domain names. Be cautious not to set this value too high.
Test Nginx Configuration
Before restarting Nginx, test the configuration to ensure there are no syntax errors:
sudo nginx -t
The output should be if there are no errors in the syntax:
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok nginx: configuration file /etc/nginx/nginx.conf test is successful
Verify Nginx Server Block
Open your web browser and enter your server’s domain name. You should see your custom test page, indicating that your server block is live and functioning correctly.

Essential Nginx Management Tasks
Secure Nginx Webserver Files
Many users often neglect to set proper permissions for files and folders, with some even granting full read, write, and execute access to the public. Avoid this using the following commands to establish secure permissions for all files and folders. Then, adjust permissions for specific files or directories as needed afterward (for example, phpBB requires setting some folders to 777).
sudo find /var/www/example.com/ -type d -exec chmod 755 "{}" \;
sudo find /var/www/example.com/ -type f -exec chmod 644 "{}" \;
Verify the permissions were applied correctly:
ls -la /var/www/example.com/
drwxr-xr-x 2 www-data www-data 4096 Nov 30 10:00 . drwxr-xr-x 3 root root 4096 Nov 30 10:00 .. -rw-r--r-- 1 www-data www-data 150 Nov 30 10:00 index.html
Make sure to replace /var/www/example.com/ with your root directory location.
Note: Remember that this doesn’t make your Nginx server entirely secure; it mitigates a common risk among many others.
Secure Nginx with Let’s Encrypt SSL
Run your Nginx server with HTTPS using an SSL certificate. Let’s Encrypt, provided by the nonprofit Internet Security Research Group (ISRG), represents one of the best options. This free, automated, open certificate authority supports secure, encrypted connections.
First, install the certbot package:
sudo apt install python3-certbot-nginx
Once installed, initiate the certificate creation process:
sudo certbot --nginx --agree-tos --redirect --hsts --staple-ocsp --email you@example.com -d www.example.com
This setup includes force HTTPS 301 redirects, a Strict-Transport-Security header, and OCSP Stapling. Make sure to adjust the email and domain name as needed.
Your URL will now use HTTPS (e.g., https://www.example.com) instead of HTTP. If you still use the old HTTP URL, it will automatically redirect to HTTPS.
Set Up Automatic Certificate Renewal
Modern Certbot installations include a systemd timer that handles automatic renewal. Check if the timer is already active using grep:
systemctl list-timers | grep certbot
If the timer is active, you will see output similar to:
Sun 2025-12-01 00:00:00 UTC 11h left Sat 2025-11-30 12:00:00 UTC 12h ago certbot.timer certbot.service
If the timer exists, no additional setup is needed. Otherwise, set up a cron job. First, test renewal with a dry run:
sudo certbot renew --dry-run
A successful dry run shows:
Congratulations, all simulated renewals succeeded: /etc/letsencrypt/live/example.com/fullchain.pem (success)
If the dry run succeeds, open your crontab to set up automatic renewal:
sudo crontab -e
Add the following line to check for renewal twice daily:
0 0,12 * * * /usr/bin/certbot renew --quiet
Access Nginx Server Logs
View Log Files
Nginx stores its logs in a default directory unless you’ve specified a different location. You can view the logs using the following commands.
First, navigate to the logs directory and list the files:
cd /var/log/nginx && ls -l
You should find the following access and error files:
- Access Log:
/var/log/nginx/access.log - Error Log:
/var/log/nginx/error.log
To monitor logs in real-time, use the tail -f command:
Example command:
tail -f /var/log/nginx/access.log
Note that you might need to use sudo with this command.
To display a specific number of lines (e.g., the last 30 lines), add the -n 30 flag:
sudo tail -f /var/log/nginx/access.log -n 30
These are just a few examples of how to read logs.
Configure Nginx Log Rotation
Nginx automatically sets up log rotation with daily rotations by default. To modify these settings, access the file:
sudo nano /etc/logrotate.d/nginx
The file includes adjustable settings like rotation frequency and log retention quantity. Retain the default settings unless specific log requirements for monitoring software like fail2ban necessitate changes.
The most common settings to change are:
- Daily: This can be changed to Weekly or Monthly, but daily is recommended for easier log file management.
- Rotate 14: Determines the number of logs to keep. Change this to 7 to store only one week’s worth of logs.
Avoid altering other settings unless you’re sure about their functions.
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 www-data adm
sharedscripts
prerotate
if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
run-parts /etc/logrotate.d/httpd-prerotate; \
fi \
endscript
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
Update Nginx
Nginx updates automatically when a new version is available in the repositories. Before upgrading, back up your Nginx directory or, at a minimum, the nginx.conf file.
To back up nginx.conf:
sudo cp /etc/nginx/nginx.conf /etc/nginx/nginx-backup.conf
To back up the entire Nginx folder:
sudo cp -r /etc/nginx/ /etc/nginx-bkup
Next, run the standard update command:
sudo apt update
If an upgrade is available, execute the upgrade:
sudo apt upgrade
Backing up before upgrading is crucial, especially for large Nginx configurations. Consider using Github or Gitlab for additional backup options.
Remove Nginx
If you decide to remove the web server, first stop it:
sudo systemctl disable nginx --now
Then, use the following command to remove Nginx altogether:
sudo apt remove nginx
Some leftover files might remain in the /etc/nginx folder. Remove this directory with:
The following command permanently deletes all Nginx configuration files including server blocks, SSL settings, and custom configurations. Back up any files you need before proceeding.
sudo rm -R /etc/nginx/
If you used Let’s Encrypt SSL certificates, they remain in /etc/letsencrypt/. Remove them separately if no longer needed:
sudo rm -rf /etc/letsencrypt/live/your_domain/
sudo rm -rf /etc/letsencrypt/archive/your_domain/
sudo rm -rf /etc/letsencrypt/renewal/your_domain.conf
This action will delete your custom configuration files, so back them up if you use them again (e.g., with Github or a similar service).
Nginx typically does not store user-specific configuration in home directories. If you created custom scripts or logs in your home directory, remove them manually.
Troubleshoot Common Nginx Issues
Port 80 Already in Use
If Nginx fails to start, another service may be using port 80. Check what is listening on the port:
sudo lsof -i :80
Common output showing Apache using the port (if you have Apache installed):
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME apache2 1234 root 4u IPv6 12345 0t0 TCP *:http (LISTEN)
Stop the conflicting service and start Nginx:
sudo systemctl stop apache2
sudo systemctl start nginx
Verify Nginx now starts successfully:
sudo systemctl start nginx && systemctl status nginx
● nginx.service - A high performance web server
Active: active (running)
Configuration Syntax Errors
If nginx -t reports errors, check the error message for the file and line number:
nginx: [emerg] unexpected ";" in /etc/nginx/sites-enabled/example.com.conf:12 nginx: configuration file /etc/nginx/nginx.conf test failed
Open the file at the indicated line and fix the syntax error. Common issues include missing semicolons, mismatched braces, and typos in directive names.
After fixing the error, verify the configuration is now valid:
sudo nginx -t
nginx: configuration file /etc/nginx/nginx.conf test is successful
Permission Denied Errors
If logs show permission denied errors when accessing files:
2025/11/30 10:00:00 [error] 1234#1234: *1 open() "/var/www/example.com/index.html" failed (13: Permission denied)
Fix ownership and permissions for the web directory:
sudo chown -R www-data:www-data /var/www/example.com/
sudo find /var/www/example.com/ -type d -exec chmod 755 {} \;
sudo find /var/www/example.com/ -type f -exec chmod 644 {} \;
Verify the fix:
sudo nginx -t && sudo systemctl reload nginx
Conclusion
You now have Nginx installed and configured with server blocks, firewall rules, and SSL certificates. To further optimize your setup, consider enabling gzip compression to reduce bandwidth, configuring security headers for better protection, or setting up rate limiting to prevent abuse. For production servers, adding Fail2Ban provides an additional layer of security against brute-force attacks.