How to Set Up an Nginx Server on Ubuntu

Nginx is one of the most popular web servers for hosting websites and web applications. It is lightweight, fast, and commonly used as a reverse proxy, load balancer, and web server.

In this guide, we will set up Nginx on an Ubuntu server and configure it to serve a website.

Prerequisites

You should have:

  • An Ubuntu server
  • SSH access to the server
  • A user with sudo privileges
  • A domain name pointing to the server’s IP address

For this example, we will use:

website.com

And the website files will be stored in:

/var/www/website.com

1. Update Ubuntu Packages

First, update the package list:

sudo apt update

You can also upgrade the installed packages:

sudo apt upgrade -y

2. Install Nginx

Install Nginx using apt:

sudo apt install nginx -y

After installation, check the Nginx version:

nginx -v

You should see something similar to:

nginx version: nginx/1.24.x

3. Check Nginx Service

Check whether Nginx is running:

sudo systemctl status nginx

If it is not running, start it:

sudo systemctl start nginx

Enable Nginx to start automatically after a server reboot:

sudo systemctl enable nginx

You can verify that it is enabled with:

sudo systemctl is-enabled nginx

4. Configure the Firewall

If you are using UFW, allow HTTP and HTTPS traffic.

sudo ufw allow 'Nginx Full'

Check the firewall status:

sudo ufw status

You should see ports 80 and 443 allowed for Nginx.

If UFW is disabled, you don’t need to enable it just for Nginx. Be careful when changing firewall settings on a remote server because incorrect rules can lock you out of SSH.


5. Create the Website Directory

Create a directory for your website:

sudo mkdir -p /var/www/website.com

Create a simple HTML page:

sudo nano /var/www/website.com/index.html

Add:

<!DOCTYPE html>
<html>
  <head>
    <title>website.com</title>
  </head>
  <body>
    <h1>Hello from Nginx!</h1>
    <p>Nginx is working correctly.</p>
  </body>
</html>

Save the file.


6. Set Website Permissions

A simple approach is to make the website directory readable by Nginx:

sudo chown -R www-data:www-data /var/www/website.com

Set directory permissions:

sudo find /var/www/website.com -type d -exec chmod 755 {} \;

Set file permissions:

sudo find /var/www/website.com -type f -exec chmod 644 {} \;

This gives directories execute/read permissions and files read permissions for the web server.


7. Create an Nginx Server Block

Nginx configuration files are commonly stored under:

/etc/nginx/sites-available/

Create a configuration file:

sudo nano /etc/nginx/sites-available/website.com

Add:

server {
    listen 80;
    listen [::]:80;

    server_name website.com www.website.com;

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

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

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

Understanding the Configuration

The important directives are:

listen 80;

Nginx listens for HTTP requests on port 80.

server_name website.com www.website.com;

Defines the domain names handled by this server block.

root /var/www/website.com;

Defines the document root of the website.

index index.html;

Defines the default file served when a directory is requested.

try_files $uri $uri/ =404;

Attempts to find the requested file or directory. If it doesn’t exist, Nginx returns HTTP 404.


8. Enable the Website

Nginx uses two directories for virtual host configurations:

/etc/nginx/sites-available/

and:

/etc/nginx/sites-enabled/

The configuration is created in sites-available and enabled by creating a symbolic link in sites-enabled.

Run:

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

Check the symlink:

ls -l /etc/nginx/sites-enabled/

You should see something similar to:

website.com -> /etc/nginx/sites-available/website.com

9. Disable the Default Nginx Website

Ubuntu’s Nginx installation usually enables a default website.

You can disable it:

sudo rm /etc/nginx/sites-enabled/default

This prevents the default Nginx page from being served when your server block should handle the request.


10. Test the Nginx Configuration

Before reloading Nginx, always test the configuration:

sudo nginx -t

A successful result looks like:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful

This is an important habit when managing Nginx servers.

Never blindly reload Nginx after changing configuration. Test it first.


11. Reload Nginx

If the configuration test succeeds:

sudo systemctl reload nginx

You can also use:

sudo nginx -s reload

For normal configuration changes, a reload is preferable to restarting the service because existing connections can continue to be handled gracefully.


12. Verify the Website

Make sure your domain’s DNS record points to the server.

For example:

A     website.com      YOUR_SERVER_IP
A     www.website.com  YOUR_SERVER_IP

Then open:

http://website.com

You should see:

Hello from Nginx!
Nginx is working correctly.

You can also test from the command line:

curl -I http://website.com

A successful response should contain:

HTTP/1.1 200 OK

13. Check Nginx Logs

Nginx logs are extremely useful when troubleshooting.

For our website:

sudo tail -f /var/log/nginx/website.com.access.log

For errors:

sudo tail -f /var/log/nginx/website.com.error.log

You can also inspect the general Nginx logs:

sudo tail -f /var/log/nginx/access.log

and:

sudo tail -f /var/log/nginx/error.log

When debugging a website, the error log should usually be one of the first places you check.


14. Useful Nginx Commands

Here are some commands you will frequently use while managing Nginx.

Check status

sudo systemctl status nginx

Start Nginx

sudo systemctl start nginx

Stop Nginx

sudo systemctl stop nginx

Restart Nginx

sudo systemctl restart nginx

Reload configuration

sudo systemctl reload nginx

Test configuration

sudo nginx -t

Check version

nginx -v

View enabled websites

ls -la /etc/nginx/sites-enabled/

View available websites

ls -la /etc/nginx/sites-available/

15. Nginx Configuration Structure

After installation, an Ubuntu Nginx server typically has a structure similar to:

/etc/nginx/
├── nginx.conf
├── sites-available/
│   ├── default
│   └── website.com
├── sites-enabled/
│   └── website.com -> ../sites-available/website.com
├── conf.d/
├── snippets/
└── mime.types

The main configuration file is:

/etc/nginx/nginx.conf

Website-specific server blocks are generally maintained under:

/etc/nginx/sites-available/

and enabled through:

/etc/nginx/sites-enabled/

This separation makes it easier to manage multiple websites on the same server.


16. Hosting Multiple Websites

One of Nginx’s strengths is the ability to host multiple websites on a single server.

For example:

/var/www/
├── website.com/
├── example.com/
└── api.example.com/

Each website can have its own server block:

/etc/nginx/sites-available/
├── website.com
├── example.com
└── api.example.com

and corresponding symbolic links:

/etc/nginx/sites-enabled/
├── website.com
├── example.com
└── api.example.com

Nginx determines which configuration should handle a request based primarily on the requested hostname and port.


When making changes to an Nginx server, use this workflow:

sudo nano /etc/nginx/sites-available/website.com

Then test:

sudo nginx -t

If successful:

sudo systemctl reload nginx

Then verify:

curl -I http://website.com

And if something goes wrong:

sudo tail -f /var/log/nginx/website.com.error.log

This simple workflow prevents many common Nginx configuration problems.


Conclusion

Setting up Nginx on Ubuntu is straightforward once you understand the basic structure of Nginx server blocks.

The typical process is:

Install Nginx
Create website directory
Create server block
Enable server block
Test configuration
Reload Nginx
Verify website

The most important commands to remember are:

sudo apt install nginx -y
sudo nginx -t
sudo systemctl reload nginx
sudo systemctl status nginx

Once the basic Nginx setup is working, you can build on it with HTTPS/SSL using Certbot, PHP-FPM for PHP applications, reverse proxy configuration for Node.js applications, caching, compression, security headers, rate limiting, and load balancing.