Tutorial

How To Install Nginx on Ubuntu 20.04

Updated on January 5, 2022

Senior Manager, DevEd

English
How To Install Nginx on Ubuntu 20.04
Not using Ubuntu 20.04?Choose a different version or distribution.
Ubuntu 20.04

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 a lightweight choice that can be used as either a web server or reverse proxy.

In this guide, we’ll discuss how to install Nginx on your Ubuntu 20.04 server, adjust the firewall, manage the Nginx process, and set up server blocks for hosting more than one domain from a single server.

Simplify deploying applications with DigitalOcean App Platform. Deploy directly from GitHub in minutes.

Prerequisites

Before you begin this guide, you should have a regular, non-root user with sudo privileges configured on your server. You can learn how to configure a regular user account by following our Initial server setup guide for Ubuntu 20.04.

You will also optionally want to have registered a domain name before completing the last steps of this tutorial. To learn more about setting up a domain name with DigitalOcean, please refer to our Introduction to DigitalOcean DNS.

When you have an account available, log in as your non-root user to begin.

Step 1 – Installing Nginx

Because Nginx is available in Ubuntu’s default repositories, it is possible to install it from these repositories using the apt packaging system.

Since this is our first interaction with the apt packaging system in this session, we will update our local package index so that we have access to the most recent package listings. Afterwards, we can install nginx:

  1. sudo apt update
  2. sudo apt install nginx

After accepting the procedure, apt will install Nginx and any required dependencies to your server.

Step 2 – Adjusting the Firewall

Before testing Nginx, the firewall software needs to be adjusted to allow access to the service. Nginx registers itself as a service with ufw upon installation, making it straightforward to allow Nginx access.

List the application configurations that ufw knows how to work with by typing:

  1. sudo ufw app list

You should get a listing of the application profiles:

Output
Available applications: Nginx Full Nginx HTTP Nginx HTTPS OpenSSH

As demonstrated by the output, there are three profiles available for Nginx:

  • Nginx Full: This profile opens both port 80 (normal, unencrypted web traffic) and port 443 (TLS/SSL encrypted traffic)
  • Nginx HTTP: This profile opens only port 80 (normal, unencrypted web traffic)
  • Nginx HTTPS: This profile opens only port 443 (TLS/SSL encrypted traffic)

It is recommended that you enable the most restrictive profile that will still allow the traffic you’ve configured. Right now, we will only need to allow traffic on port 80.

You can enable this by typing:

  1. sudo ufw allow 'Nginx HTTP'

You can verify the change by typing:

  1. sudo ufw status

The output will indicated which HTTP traffic is allowed:

Output
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

At the end of the installation process, Ubuntu 20.04 starts Nginx. The web server should already be up and running.

We can check with the systemd init system to make sure the service is running by typing:

  1. systemctl status nginx
Output
● 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 Fri 2020-04-20 16:08:19 UTC; 3 days 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 process

As confirmed by this out, the service has started successfully. However, the best way to test this is to actually request a page from Nginx.

You can access the default Nginx landing page to confirm that the software is running properly by navigating to your server’s IP address. If you do not know your server’s IP address, you can find it by using the icanhazip.com tool, which will give you your public IP address as received from another location on the internet:

  1. curl -4 icanhazip.com

When you have your server’s IP address, enter it into your browser’s address bar:

http://your_server_ip

You should receive the default Nginx landing page:

Nginx default page

If you are on this page, your server is running correctly and is ready to be managed.

Step 4 – Managing the Nginx Process

Now that you have your web server up and running, let’s review some basic management commands.

To stop your web server, type:

  1. sudo systemctl stop nginx

To start the web server when it is stopped, type:

  1. sudo systemctl start nginx

To stop and then start the service again, type:

  1. sudo systemctl restart nginx

If you are only making configuration changes, Nginx can often reload without dropping connections. To do this, type:

  1. sudo systemctl reload nginx

By default, Nginx is configured to start automatically when the server boots. If this is not what you want, you can disable this behavior by typing:

  1. sudo systemctl disable nginx

To re-enable the service to start up at boot, you can type:

  1. sudo systemctl enable nginx

You have now learned basic management commands and should be ready to configure the site to host more than one domain.

When using the Nginx web server, server blocks (similar to virtual hosts in Apache) can be used to encapsulate configuration details and host more than one domain from a single server. We will set up a domain called your_domain, but you should replace this with your own domain name.

Nginx on Ubuntu 20.04 has one server block enabled by default that is configured to serve documents out of a directory at /var/www/html. While this works well for a single site, it can become unwieldy if you are hosting multiple sites. Instead of modifying /var/www/html, let’s create a directory structure within /var/www for our your_domain site, leaving /var/www/html in place as the default directory to be served if a client request doesn’t match any other sites.

Create the directory for your_domain as follows, using the -p flag to create any necessary parent directories:

  1. sudo mkdir -p /var/www/your_domain/html

Next, assign ownership of the directory with the $USER environment variable:

  1. sudo chown -R $USER:$USER /var/www/your_domain/html

The permissions of your web roots should be correct if you haven’t modified your umask value, which sets default file permissions. To ensure that your permissions are correct and allow the owner to read, write, and execute the files while granting only read and execute permissions to groups and others, you can input the following command:

  1. sudo chmod -R 755 /var/www/your_domain

Next, create a sample index.html page using nano or your favorite editor:

  1. sudo nano /var/www/your_domain/html/index.html

Inside, add the following sample HTML:

/var/www/your_domain/html/index.html
<html>
    <head>
        <title>Welcome to your_domain!</title>
    </head>
    <body>
        <h1>Success!  The your_domain server block is working!</h1>
    </body>
</html>

Save and close the file by pressing Ctrl+X to exit, then when prompted to save, Y and then Enter.

In order for Nginx to serve this content, it’s necessary to create a server block with the correct directives. Instead of modifying the default configuration file directly, let’s make a new one at /etc/nginx/sites-available/your_domain:

  1. sudo nano /etc/nginx/sites-available/your_domain

Paste in the following configuration block, which is similar to the default, but updated for our new directory and domain name:

/etc/nginx/sites-available/your_domain
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 we’ve updated the root configuration to our new directory, and the server_name to our domain name.

Next, let’s enable the file by creating a link from it to the sites-enabled directory, which Nginx reads from during startup:

  1. sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/

Note: Nginx uses a common practice called symbolic links, or symlinks, to track which of your server blocks are enabled. Creating a symlink is like creating a shortcut on disk, so that you could later delete the shortcut from the sites-enabled directory while keeping the server block in sites-available if you wanted to enable it.

Two server blocks are now enabled and configured to respond to requests based on their listen and server_name directives (you can read more about how Nginx processes these directives here):

  • your_domain: Will respond to requests for your_domain and www.your_domain.
  • default: Will respond to any requests on port 80 that do not match the other two blocks.

To avoid a possible hash bucket memory problem that can arise from adding additional server names, it is necessary to adjust a single value in the /etc/nginx/nginx.conf file. Open the file:

  1. sudo nano /etc/nginx/nginx.conf

Find the server_names_hash_bucket_size directive and remove the # symbol to uncomment the line. If you are using nano, you can quickly search for words in the file by pressing CTRL and w.

Note: Commenting out lines of code – usually by putting # at the start of a line – is another way of disabling them without needing to actually delete them. Many configuration files ship with multiple options commented out so that they can be enabled or disabled, by toggling them between active code and documentation.

/etc/nginx/nginx.conf
...
http {
    ...
    server_names_hash_bucket_size 64;
    ...
}
...

Save and close the file when you are finished.

Next, test to make sure that there are no syntax errors in any of your Nginx files:

  1. sudo nginx -t

If there aren’t any problems, restart Nginx to enable your changes:

  1. sudo systemctl restart nginx

Nginx should now be serving your domain name. You can test this by navigating to http://your_domain, where you should see something like this:

Nginx first server block

Step 6 – Getting Familiar with Important Nginx Files and Directories

Now that you know how to manage the Nginx service itself, you should take a few minutes to familiarize yourself with a few important directories and files.

Content

  • /var/www/html: The actual web content, which by default only consists of the default Nginx page you saw earlier, is served out of the /var/www/html directory. This can be changed by altering Nginx configuration files.

Server Configuration

  • /etc/nginx: The Nginx configuration directory. All of the Nginx configuration files reside here.
  • /etc/nginx/nginx.conf: The main Nginx configuration file. This can be modified to make changes to the Nginx global configuration.
  • /etc/nginx/sites-available/: The directory where per-site server blocks can be stored. Nginx will not use the configuration files found in this directory unless they are linked to the sites-enabled directory. Typically, all server block configuration is done in this directory, and then enabled by linking to the other directory.
  • /etc/nginx/sites-enabled/: The directory where enabled per-site server blocks are stored. Typically, these are created by linking to configuration files found in the sites-available directory.
  • /etc/nginx/snippets: This directory contains configuration fragments that can be included elsewhere in the Nginx configuration. Potentially repeatable configuration segments are good candidates for refactoring into snippets.

Server Logs

  • /var/log/nginx/access.log: Every request to your web server is recorded in this log file unless Nginx is configured to do otherwise.
  • /var/log/nginx/error.log: Any Nginx errors will be recorded in this log.

Conclusion

Now that you have your web server installed, you have many options for the type of content to serve and the technologies you want to use to create a richer experience.

If you’d like to build out a more complete application stack, check out the article How To Install Linux, Nginx, MySQL, PHP (LEMP stack) on Ubuntu 20.04.

In order to set up HTTPS for your domain name with a free SSL certificate using Let’s Encrypt, you should move on to How To Secure Nginx with Let’s Encrypt on Ubuntu 20.04.

Want to easily configure a performant, secure, and stable Nginx server? Let us spin up an Nginx virtual machine for you in seconds, so you can focus on building a great application.

Check it out here

About the authors
Default avatar

Senior Manager, DevEd

Open source advocate and lover of education, culture, and community.

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
54 Comments
Leave a comment...

This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

Just an FYI, For me the UFW was not active. I had to run sudo ufw enable on Step 2.

this happens with me all time, I am thinking why the documentation/tutorial doesn’t update and adds this commands.

I just wanted to mention to all those who may be having problems - Be sure you allow SSL/port 443 connections in your firewall!

sudo ufw allow https -or- sudo ufw allow 443

Hours spent trying all kinds of different configurations, turns out the solution was as simple as adding this firewall rule!

Thank you for this.

I had the same issue… instead of doing:

sudo ufw allow 'Nginx HTTP'

I did:

sudo ufw allow 'Nginx Full'

If you already allowed Nginx HTTP I would recommend resetting your ufw configuration. Make sure to re-allow OpenSSH too. The whole process I did is as follows:

sudo ufw disable
sudo ufw reset
sudo ufw allow 'Nginx Full'
sudo ufw allow 'OpenSSH'
sudo ufw enable

it’s kinda irrelevant, http should just work if everything is configured correctly. looks like most people are running into DNS issues instead of ngnix configuring issues.

but if the DNS can’t resolve your domain example.com and hit your server, the ngnix is kinda useless as it never receives traffic.

The link is broken for “Introduction to DigitalOcean DNS” in the first paragraph of the Server Blocks section.

i followed this exactly replacing your_domain with the word ‘happy’, i could not connect and only got 404 error when trying to access http://happy or http://www.happy or even my ip/happy or localhost/happy, all variants, with and without http://

assuming i did something wrong i tried again… verbatim… using your_domain this time. i copy pasta the whole way. still 404 error.

but just my ip or localhost always returns the welcome to nginx page. any ideas?

your_domain is supposed to be a domain that you own. Also http://happy is never going to work unless you specify a valid top level domain like .com or .net or even .xyz. But again, you would have to own happy.xyz for this work. I suggest checking out freenom to get a free domain you can play around with. Or namecheap if you don’t mind spending a few bucks.

Thanks for the response. I am only going to serve locally fir testing purposes and my understanding is i can loopback and use any name I want. Its been awhile but I remember that being what localhost is all about. Thanks again for responding.

Hey— I assume you figured this out because it was well over a year ago, but if someone else here has the same question…

short answer: for your use case, you probably just need to specify the host name happy in your system’s DNS resolution file which is probably in resolv.conf and probably will require some other ceremony with resolvconf depending on your OS/configuration.

long explanation:

mattbrannonn is right on the mark in interpreting the intent of the tutorial. It’s intended to be a domain name, so your intended configuration is different from that in the tutorial, which is why it does not work. However, you can absolutely get http://happy to work locally with some quick DNS configuration.

Oversimplified but really important background info: When a computer/server/etc is connected to any network (including the internet) it uses IP addresses to actually connect to other machines and send/receive information. Think of domain and host names as easier to remember labels for IP addresses. DNS, or Domain Name Service is just a directory where computers can see which IP address belongs to a specific domain name or host name.

The (oversimplified) workflow: if you type ‘http://google.com/’ into your web browser address bar:

  1. the web browser asks your OS to figure out what IP address belongs to google.com
  2. your computer uses its DNS system to find out, or ‘resolve’ the IP address for google.com. It probably first checks to see if you’ve specified a specific IP address to use for google.com in the DNS settings, and you probably haven’t, so it asks whichever DNS server it’s configured to use
  3. the DNS server responds with 172.217.165.142 or whatever google has configured at the moment
  4. your web browser connects to 172.217.165.142 and tells the web server there that a user is requesting ‘http://google.com/’ and the server sends whatever it’s been configured to send in that instance. In this case, the google homepage. You’d have likely had the same experience typing http://172.217.165.142 into your address bar.

If you replace google.com with some domain name you own, properly configured, the same process takes place.

In your case, rather than being a TLD, happy would resolve locally as a host name. The Nginx setup would be easy— the docs say the server_name line should just have your intended host name, so it should be server_name happy though I haven’t tested it.

But Nginx only accepts incoming connections, looks at the request, and sends back the configured response— it has nothing at all to do with your OS resolving domain names.

When you type http://happy into your web browser address bar, your web browser would ask the OS to see which IP address belongs to the host happy and it would have no way to know. happy could be another machine on your local network, an alias for a machine across the globe, another network card in your machine, or in your case, the very network interface you’re making the request from. You need to tell your local DNS system to use 127.0.0.1.

ugh… trying localhost and expecting it to hit a server you are renting from a paas company will probably never work.

when i try to run sudo systemctl restart nginx i recieve the following error:

Job for nginx.service failed because the control process exited with error code.
See "systemctl status nginx.service" and "journalctl -xe" for details.

running journalctl -xe it says:

pam_unix(sudo:auth): Couldn't open /etc/securetty: No such file or directory

I’m not sure what this means or what step i could have messed up in order to recieve this error message. Any help would be appreciated!

I am seeing the same issue

make file sudo nano /etc/securetty

contents:

         tty1
         #tty2
         #tty3
         #tty4
         #tty5
         #tty6
         #tty7
         #tty8

save… try again

KFSys
Site Moderator
Site Moderator badge
November 15, 2023

I don’t think the two are connected to be honest. Check your Nginx error log and you’ll see the exact error. There is no reason for PAM and Nginx to be connected like that. Only if you have added some other custom rules.

Investigating Nginx Issues: The Nginx error is likely caused by something else. To diagnose the Nginx issue, you should:

  • Run systemctl status nginx.service to get the status and recent logs of the Nginx service. This will often provide a more specific error message related to Nginx.
  • Check the Nginx error log, typically located at /var/log/nginx/error.log. This log can provide more details on what’s causing Nginx to fail.

Make sure you sudo ufw allow 'OpenSSH' or you might not be able to log back in.

Hi, I’m stuck at this step: “Nginx should now be serving your domain name. You can test this by navigating to http://your_domain, where you should see something like this” I’ve followed the tutorial verbatim so far but I’m getting “This site can’t be reached” error when I navigate to http://<mydomainname>.com Could someone please help me out?

I 've gotten as far as sudo nginx -t and restarting. I do own my domain, its a .me domain. When I go to the domain I just get “This site can’t be reached”. Is there anything I need to do on the namecheap side of things?

After you buy a domain, you have to point it to your server and the server must point back to the domain name

this tutorial will help you:

https://www.digitalocean.com/community/tutorials/how-to-point-to-digitalocean-nameservers-from-common-domain-registrars

I tried this but it did not still work. I think it is becuase of the instruction on the namecheap site that says “It may take about 24-48 hours for your domain to propagate after the nameservers update to be resolving properly all over the world.”

Bobby Iliev
Site Moderator
Site Moderator badge
January 20, 2025

Yep, this is correct!

DNS propagation can take 24-48 hours after updating nameservers. During this time, your domain might not resolve everywhere.

You can check back later or use a DNS checker to confirm if the changes have fully propagated:

https://www.digitalocean.com/community/tools/dns

This comment has been deleted

    I seem to have the same problem as many other users here, I can use cURL from the server terminal or my own computer’s terminal and I’d get the correct page contents. However, trying to access domain from a browser just gives me “This site can’t be reached” and that the server “refused to connect”.

    I’ve reset my VPS and restarted the process three times now, does anyone know what might be the reason? Thanks!

    P.S. I have the DNS setup properly at the domain registrar, and A records are pointing to my server’s IP address.

    Solved - my website is working now after adding an SSL certificate, followed this guide.

    I suspect this has something to do with the domain having been associated with an SSL from a different host, as I never ran into this problem when I followed this guide with a fresh domain name.

    Daryl, I could kiss you! I’ve been pulling what little hair I have left out of my scalp with frustration, but this fixed it!

    A quick comment for those who may be frustrated like I was-- when it says to update your server_name value to ‘your domain,’ that value needs to include the closer. IE ‘example.com’ or ‘example.net’ or whatever. Makes a big difference!

    Another really helpful article on Digital Ocean. Thanks!

    Points of critique:

    1. It was not clear to me that “your_domain” refers to a string like “example.com”; I thought it was referring to the “example” part in “example.com”. (That’s my fault, but it might help others like me to refer to “example.com” when introducing “your_domain”.)

    2. I think “sudo chmod -R 755 /var/www/your_domain” should have been “sudo chown -R 755 /var/www/your_domain”; that is, “chmod” should be “chown” there.

    3. I think “nano /var/www/your_domain/html/index.html” should have been “sudo nano /var/www/your_domain/html/index.html”; that is, there was a missing “sudo”.

    The silver lining to having little issues like this is that it forced me to do some trouble-shooting and exploring and perform the instructions more than once.

    I think I was wrong on points 2 and 3. If everything is executed correctly beforehand, the command in point 3 (without “sudo”) should work fine.

    @awforrester can you remove the part that is wrong from your comment? it will save other people time not reading what’s wrong and realize later that it is wrong. thanks.

    Doesn’t seem to work as of August 2021. Following the steps exactly (other than having to manually enable ufw with sudo ufw enable) and trying to visit http://your_domain (with .com obviously) or https results in an error in my browser reading:

    Unable to connect
    
    Firefox can’t establish a connection to the server at YOUR_DOMAIN
    

    However, directly visiting the address of my server does work, so it must be an issue with the configuration of the server blocks section

    I know my DNS records are configured correctly because I’m migrating from a functioning server on Ubuntu 16 to one using Ubuntu 20/this guide

    Any ideas anyone? Is this assuming that I’m using a specific version of nginx?

    @hak33m16 I’m facing the exact same issue. Did you figure out why this is happening?

    One thing i noticed in my case was that, when I added custom DNS in my namecheap dashboard, it notified that it may take 48 hours to appay changes. perhaps thats what’s causing this.

    KFSys
    Site Moderator
    Site Moderator badge
    November 15, 2023

    Heya,

    I’ve checked the tutorial and it does work. This does sound like a DNS issue.

    You can use this site to check if your DNS change has propagated:

    https://www.digitalocean.com/community/tools/dns

    @hak33m16, i think it might be your DNS, not the nginx block. the block actually deals with the request when it reaches to the nginx server, but the error says the domain can’t be resolved, which means nginx never actually received the request.

    this article assumes the following

    1. you already own a domain e.g. example.com, thus having a dashboard from your domain host to manage your domain.
    2. you’ve added this domain to one of your projects (DNS records will be created for you automatically. The records basically say when you hit http://example.com use digital ocean’s name server to resolve the domain to your droplet server.
    3. your domain is configured to use digital ocean as its nameserver.

    see this article.

    @hak33m16

    Directly visiting the address of your server works it’s because you use ip address in your url directly, so there is no DNS needed to resolve your domain name to the ip address, if the nginx server works on your droplet server, you will see the default page.

    I know my DNS records are configured correctly if by that you mean it use to work on another server, it means your domain name can be resolved to your old server’s ip. when you switch to a different server, the domain name needs to be resolved to the new server’s ip. that’s why you need to configure in your domain host’s dashboard to use digital ocean’s name server, and add your domain name to your new server’s DNS record. when that is done, you can say your DNS records are configured correctly.

    Thank you for this tutorial, each step is very well explained… and it worked :D

    Regarding the people who have had trouble:

    Where the guide says “your_domain”, you really need to enter the FQDN to your server, not just your domain name.

    For example, my server FQDN is “log.contoso.local” and that is what I can successfully ping, so that is what I must enter for all occurrences of “your_domain”.

    If you followed every instructions, and your_domain (which has a format of example.com or www.example.com), won’t open: reboot your whole machine

    sudo reboot

    I just got it work, but NOT on the first try, here are the gotchas i had

    • the domain_name is something like example.com, not just example.
    • in this article that talks about enabling https, one of the prerequisites says you need a A record to point example.com to your droplet server IP. This can be configured in the networking tab of your dashboard.
    • the nameserver needs to point to digitalocean. see this article

    I wish I can request the author of this article to replace domain_name to example.com in this article. This article is so far the worst I’ve ever read on this site. I will update this statement when I come across a worse one.

    I have tried this guide three times now, and continue to run into the issue with server blocks. The default nginx page continues to show.

    I was able to make it show a custom page, but I can’t make it show my django app’s homepage

    nice Informations Providing

    nice article Posting

    I followed this tutorial exactly, and I don’t see any blocks or firewalls set up within the dashboard. Should those be shown there? I can run the console commands and verify the steps listed worked though.

    Thanks its very knowledgable article I had one query let say I am running node application on port 3000 and by sudo ufw allow 'Nginx HTTP' this will enabled port 80 and I am listing to port 3000. What needs to do to whitelist ports ?

    Thanks its very knowledgable article I had one query let say I am running node application on port 3000 and by sudo ufw allow 'Nginx HTTP' this will enabled port 80 and I am listing to port 3000. What needs to do to whitelist ports ?

    Can some one please explain what should I do to host a static web page if I don’t have the domain name configured. I just want to host the web page with the ip itself - basically landing to a different page with a different route ?

    Thanks Aashay

    KFSys
    Site Moderator
    Site Moderator badge
    November 15, 2023

    Heya,

    In order to host a static website using your Droplet IP address you’ll need to update your Nginx config to look something like that:

    server { 
        listen 80 default_server;
        listen [::]:80 default_server;
        
        index index.html index.htm index.nginx-debian.html;
        server_name _;
    
        location / {
            try_files $uri $uri/ =404;
        }
    

    Everything else you can follow from the tutorial.

    This comment has been deleted

      This comment has been deleted

        Article is not accurate I’m afraid. If you are new to digital ocean and are looking to work with nginx among other things. Take a turn and look at other alternatives. It will save you countless hours

        KFSys
        Site Moderator
        Site Moderator badge
        November 15, 2023

        Heya,

        Can you let us know what is not accurate about the article? It’s always good to know that so that it can be fixed to help out people when they are going through it.

        Article is not accurate I’m afraid. If you are new to digital ocean and are looking to work with nginx among other things. Take a turn and look at other alternatives. It will save you countless hours

        This article is 100% accurate. What problems are you having?

        Easy Peasy

        peace of Cake

        Thank you

        I enjoyed

        Best Step Ever

        I followed this tutorial exactly, and I don’t see any blocks or firewalls set up within the dashboard. Should those be shown there? I can run the console commands and verify the steps listed worked though.

        Thanks its very knowledgable article I had one query let say I am running node application on port 3000 and by sudo ufw allow 'Nginx HTTP' this will enabled port 80 and I am listing to port 3000. What needs to do to whitelist ports ?

        Thanks its very knowledgable article I had one query let say I am running node application on port 3000 and by sudo ufw allow 'Nginx HTTP' this will enabled port 80 and I am listing to port 3000. What needs to do to whitelist ports ?

        Can some one please explain what should I do to host a static web page if I don’t have the domain name configured. I just want to host the web page with the ip itself - basically landing to a different page with a different route ?

        Thanks Aashay

        KFSys
        Site Moderator
        Site Moderator badge
        November 15, 2023

        Heya,

        In order to host a static website using your Droplet IP address you’ll need to update your Nginx config to look something like that:

        server { 
            listen 80 default_server;
            listen [::]:80 default_server;
            
            index index.html index.htm index.nginx-debian.html;
            server_name _;
        
            location / {
                try_files $uri $uri/ =404;
            }
        

        Everything else you can follow from the tutorial.

        This comment has been deleted

          This comment has been deleted

            Article is not accurate I’m afraid. If you are new to digital ocean and are looking to work with nginx among other things. Take a turn and look at other alternatives. It will save you countless hours

            KFSys
            Site Moderator
            Site Moderator badge
            November 15, 2023

            Heya,

            Can you let us know what is not accurate about the article? It’s always good to know that so that it can be fixed to help out people when they are going through it.

            Article is not accurate I’m afraid. If you are new to digital ocean and are looking to work with nginx among other things. Take a turn and look at other alternatives. It will save you countless hours

            This article is 100% accurate. What problems are you having?

            Easy Peasy

            peace of Cake

            Thank you

            I enjoyed

            Best Step Ever

            I followed this tutorial exactly, and I don’t see any blocks or firewalls set up within the dashboard. Should those be shown there? I can run the console commands and verify the steps listed worked though.

            Thanks its very knowledgable article I had one query let say I am running node application on port 3000 and by sudo ufw allow 'Nginx HTTP' this will enabled port 80 and I am listing to port 3000. What needs to do to whitelist ports ?

            Thanks its very knowledgable article I had one query let say I am running node application on port 3000 and by sudo ufw allow 'Nginx HTTP' this will enabled port 80 and I am listing to port 3000. What needs to do to whitelist ports ?

            Can some one please explain what should I do to host a static web page if I don’t have the domain name configured. I just want to host the web page with the ip itself - basically landing to a different page with a different route ?

            Thanks Aashay

            KFSys
            Site Moderator
            Site Moderator badge
            November 15, 2023

            Heya,

            In order to host a static website using your Droplet IP address you’ll need to update your Nginx config to look something like that:

            server { 
                listen 80 default_server;
                listen [::]:80 default_server;
                
                index index.html index.htm index.nginx-debian.html;
                server_name _;
            
                location / {
                    try_files $uri $uri/ =404;
                }
            

            Everything else you can follow from the tutorial.

            This comment has been deleted

              This comment has been deleted

                Article is not accurate I’m afraid. If you are new to digital ocean and are looking to work with nginx among other things. Take a turn and look at other alternatives. It will save you countless hours

                KFSys
                Site Moderator
                Site Moderator badge
                November 15, 2023

                Heya,

                Can you let us know what is not accurate about the article? It’s always good to know that so that it can be fixed to help out people when they are going through it.

                Article is not accurate I’m afraid. If you are new to digital ocean and are looking to work with nginx among other things. Take a turn and look at other alternatives. It will save you countless hours

                This article is 100% accurate. What problems are you having?

                Easy Peasy

                peace of Cake

                Thank you

                I enjoyed

                Best Step Ever

                I am using this multi time …

                sudo ufw status this will not show the status active list, it will instead show Status: inactive, it needs enabling sudo ufw enable

                This article forgets to mention that you must allow ssh through nginx. After installing nginx I lost access to my server and had to start over :/ sudo ufw allow ssh

                This happened to me as well. Had to spin up a new EC2 instance. This time I got AWS’ Session Manager setup in case I get locked out of SSH again.

                The guide above got me 90% of the way there. This is what I ended up with. I am using Cloudflare, but I’m sure it works for others.

                • Set up your DNS records:

                  A  domain.com  123.234.12.23   A  www    123.234.12.23

                • Set your SSL/TLS encryption mode to “Full”.

                • Create an origin certificate. This will generate two keys that you will need later. You will not be able to see the private key again.

                • SSH to the server.

                • Run nano server-setup.sh.

                • Paste in the script below.

                • Update proxy_pass http://zbook:3000; with your service address and port.

                • Run sh server-setup.sh.

                • Enter 1 for full.

                • The first nano file edit will appear. Paste in your origin key (not the private one).

                • The second nano file edit will appear. Paste in your private key.

                • The third nano file edit will appear. Uncomment server_names_hash_bucket_size 64; in nginx.conf.

                • The listed IP at the end is your server’s public IP. It will show you NGINX’s default welcome page. Using your domain name will display the page that the script created.

                #!/bin/bash
                
                set -e  # Exit immediately if a command exits with a non-zero status
                
                # Define domain
                DOMAIN="yoursite.com"
                WEBROOT="/var/www/$DOMAIN/html"
                
                echo "Updating package lists..."
                sudo apt update -y
                
                # Install and setup Tailscale
                echo "Installing Tailscale..."
                # curl -fsSL https://tailscale.com/install.sh | sudo sh
                
                echo "Enabling and starting Tailscale service..."
                sudo systemctl enable tailscaled
                sudo systemctl start tailscaled
                
                echo "Starting Tailscale with SSH enabled..."
                sudo tailscale up --ssh
                
                # Install Nginx
                echo "Installing Nginx..."
                sudo apt install -y nginx
                
                # Opening ports in firewall
                sudo ufw allow 80
                sudo ufw allow 443
                
                # Prompt user to choose a firewall rule
                echo "Choose a firewall rule to apply:"
                echo "1) Nginx Full (Allows both HTTP & HTTPS)"
                echo "2) Nginx HTTP (Allows only HTTP)"
                echo "3) Nginx HTTPS (Allows only HTTPS)"
                echo "4) Skip firewall setup"
                
                read -p "Enter selection [1-4]: " FIREWALL_CHOICE
                
                case "$FIREWALL_CHOICE" in
                    1)
                        echo "Applying 'Nginx Full' firewall rule..."
                        sudo ufw allow 'Nginx Full'
                        ;;
                    2)
                        echo "Applying 'Nginx HTTP' firewall rule..."
                        sudo ufw allow 'Nginx HTTP'
                        ;;
                    3)
                        echo "Applying 'Nginx HTTPS' firewall rule..."
                        sudo ufw allow 'Nginx HTTPS'
                        ;;
                    4)
                        echo "Skipping firewall adjustments..."
                        ;;
                    *)
                        echo "Invalid choice! Defaulting to 'Nginx Full'."
                        sudo ufw allow 'Nginx Full'
                        ;;
                esac
                
                sudo ufw reload
                
                # Verify firewall status (optional)
                sudo ufw status
                
                # Enable
                yes | sudo ufw enable
                
                # Enable Nginx on boot
                echo "Enabling Nginx to start on boot..."
                sudo systemctl enable nginx
                
                # Start Nginx Now
                echo "Starting Nginx..."
                sudo systemctl start nginx
                
                # Create Web Root and Set Permissions
                echo "Setting up web root directory..."
                sudo mkdir -p $WEBROOT
                sudo chown -R $USER:$USER /var/www/$DOMAIN
                sudo chmod -R 755 /var/www/$DOMAIN
                
                sudo mkdir /var/www/$DOMAIN/certs
                sudo nano /var/www/$DOMAIN/certs/origin.pem
                sudo nano /var/www/$DOMAIN/certs/private.pem
                
                # Create a sample index.html page
                echo "Creating index.html..."
                sudo tee "$WEBROOT/index.html" > /dev/null <<EOF
                <html>
                    <head>
                        <title>Welcome to $DOMAIN!</title>
                    </head>
                    <body>
                        <h1>Success! The $DOMAIN server block is working!</h1>
                    </body>
                </html>
                EOF
                
                # Create Nginx Server Block
                echo "Configuring Nginx server block..."
                sudo tee /etc/nginx/sites-available/$DOMAIN > /dev/null <<EOF
                server {
                    listen 80;
                    listen [::]:80;
                    server_name $DOMAIN www.$DOMAIN;
                    return 301 https://$host$request_uri;  # Redirect all HTTP to HTTPS
                }
                
                server {
                    listen 443 ssl;
                    listen [::]:443 ssl;
                
                    server_name $DOMAIN www.$DOMAIN;
                
                    ssl_certificate /var/www/$DOMAIN/certs/origin.pem;
                    ssl_certificate_key /var/www/$DOMAIN/certs/private.pem;
                
                    location / {
                        proxy_pass http://zbook:3000;
                        proxy_set_header Host $host;
                        proxy_set_header X-Real-IP $remote_addr;
                        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
                        proxy_set_header X-Forwarded-Proto $scheme;
                    }
                }
                EOF
                
                # Enable server block
                echo "Enabling Nginx site configuration..."
                sudo ln -s /etc/nginx/sites-available/$DOMAIN /etc/nginx/sites-enabled/
                
                # Search and replace: Uncomment 'server_names_hash_bucket_size 64;'
                echo "Uncommenting 'server_names_hash_bucket_size 64;' in nginx.conf..."
                sudo nano /etc/nginx/nginx.conf
                
                # Test Nginx config and reload
                echo "Testing Nginx configuration..."
                if sudo nginx -t; then
                    echo "Restarting Nginx..."
                    sudo systemctl restart nginx
                else
                    echo "Nginx configuration test failed. Please check manually."
                    exit 1
                fi
                
                # Display the public IP of the server
                echo "Installation completed! Your server should now be accessible at:"
                curl -4 icanhazip.com
                echo ""
                echo "Set your SSL/TLS setting to full on cloudflare. You will only see the server"
                echo "block if you acces it with your domain name. If you visit the site with the "
                echo "address above, you will see the standard NGINX welcome page."
                
                

                Try DigitalOcean for free

                Click below to sign up and get $200 of credit to try our products over 60 days!

                Sign up

                Join the Tech Talk
                Success! Thank you! Please check your email for further details.

                Please complete your information!

                Become a contributor for community

                Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

                DigitalOcean Documentation

                Full documentation for every DigitalOcean product.

                Resources for startups and SMBs

                The Wave has everything you need to know about building a business, from raising funding to marketing your product.

                Get our newsletter

                Stay up to date by signing up for DigitalOcean’s Infrastructure as a Newsletter.

                New accounts only. By submitting your email you agree to our Privacy Policy

                The developer cloud

                Scale up as you grow — whether you're running one virtual machine or ten thousand.

                Get started for free

                Sign up and get $200 in credit for your first 60 days with DigitalOcean.*

                *This promotional offer applies to new accounts only.