How to Setup Nginx Web Server on Ubuntu Server (18.04, 20.04, 21.04)

Nginx is a free and open source web server software that can also be used as a caching server, load balancer, reverse proxymail proxy and more. It is known for its high performance, highly scalable, and highly available capability. Generally, it is used as a reverse proxy and load balancer to manage the traffic and distribute them across the multiple backend servers. NGINX consistently gaining popularity and now supports all the components of the modern Web including, HTTP/2, WebSocket, and gRPC. Currently, it is used by some of the largest and highest-traffic sites on the internet including, Hulu, Netflix, CloudFlare, GitHub, WordPress, and more.

Nginx Web Server

Nginx is lightweight and built for low memory usage and high concurrency. It uses an asynchronous and event-driven approach rather than creating new processes for each web request. In Nginx, one worker connection can take care of up to 1024 similar requests. Thus it can handle thousands of requests without any difficulties.

Nginx Web Server Features

  • Free and Open-source
  • Load balancing
  • Supports IPv4 and IPv6
  • Reverse proxy with caching
  • Handle static files, index files, and auto-indexing

In this guide, we will be going to explain how to set up an Nginx web server on Ubuntu 18.04, 20.04, 21.04.  Alternatively install Nginx in the Cloud.

Install Nginx Web Server on Ubuntu

Installing Nginx is a very straightforward process in Ubuntu. Because Nginx is available in Ubuntu’s default repository. It can be installed by just running the following command:

				
					apt-get install nginx -y
				
			

After the successful installation, verify the Nginx version using the command below:

				
					nginx -v
				
			

Sample output:

				
					nginx version: nginx/1.18.0 (Ubuntu)
				
			

Nginx service will start automatically after the installation. You can check the Nginx listening port using the following command:

				
					ss -antpl | grep nginx
				
			

Sample output:

				
					LISTEN    0         511                0.0.0.0:80               0.0.0.0:*        users:(("nginx",pid=1293,fd=6),("nginx",pid=1292,fd=6))                        
LISTEN    0         511                   [::]:80                  [::]:*        users:(("nginx",pid=1293,fd=7),("nginx",pid=1292,fd=7))                        
				
			

Managing the Nginx Service

At this point, Nginx is installed and running on port 80. By default, the Nginx service is managed by systemd. You can start, stop, enable and check the status of the Nginx easily with systemd.

To stop the Nginx service, run:

				
					systemctl stop nginx
				
			

To start the Nginx service, run:

				
					systemctl start nginx
				
			

To restart the Nginx service, run:

				
					systemctl restart nginx
				
			

To enable the Nginx service to start after the system reboot, run:

				
					systemctl enable nginx
				
			

To check the status of the Nginx service, run:

				
					systemctl status nginx
				
			

Sample 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 Thu 2021-09-02 14:36:37 UTC; 33s ago
       Docs: man:nginx(8)
   Main PID: 1292 (nginx)
      Tasks: 2 (limit: 2353)
     Memory: 6.7M
     CGroup: /system.slice/nginx.service
             ├─1292 nginx: master process /usr/sbin/nginx -g daemon on; master_process on;
             └─1293 nginx: worker process

Sep 02 14:36:37 ubuntu systemd[1]: Starting A high performance web server and a reverse proxy server...
Sep 02 14:36:37 ubuntu systemd[1]: Started A high performance web server and a reverse proxy server.

				
			

Configuring Ubuntu Firewall for Nginx

If you are using any firewall like UFW then you will need to allow access to the Nginx service in order to access the webserver over the internet.

To allow HTTP and HTTPS through the UFW firewall, run:

				
					ufw allow http
ufw allow https
				
			

Next, reload the UFW firewall using the following command:

				
					ufw disable
ufw enable
				
			

Next, check the status of the UFW with the following command:

				
					ufw status
				
			

Sample output:

				
					Status: active

To                         Action      From
--                         ------      ----
22/tcp                     ALLOW       Anywhere                  
80/tcp                     ALLOW       Anywhere                  
443/tcp                    ALLOW       Anywhere                  
22/tcp (v6)                ALLOW       Anywhere (v6)             
80/tcp (v6)                ALLOW       Anywhere (v6)             
443/tcp (v6)               ALLOW       Anywhere (v6)             
				
			

Testing Nginx Web Server

Now, you will need to verify the Nginx web server through the web browser. Open a web browser and type the URL http://your-server-ip in the address bar. If everything is fine, you should see the Nginx test page in the following screen:

testing nginx web server

Setting Up Nginx Virtual Host

Virtual Host allows you to host multiple websites on a single machine. This way you don’t need to purchase a separate machine for a new website. In this section, we will create a new virtual host and host a website on domain example.com.

First, create a directory named example.com to hold the website data:

				
					mkdir /var/www/html/example.com
				
			

Next, create an index.html file inside your website directory:

				
					nano /var/www/html/example.com/index.html
				
			

Add the following content:

				
					<html>
   <head>
      <h2>Welcome to Nginx Web Server!</h2>
   </head>
   <body>
      <h3>This message confirms that your Nginx web server is working.</h3>
   <script>class RocketElementorAnimation{constructor(){this.deviceMode=document.createElement("span"),this.deviceMode.id="elementor-device-mode-wpr",this.deviceMode.setAttribute("class","elementor-screen-only"),document.body.appendChild(this.deviceMode)}_detectAnimations(){let t=getComputedStyle(this.deviceMode,":after").content.replace(/"/g,"");this.animationSettingKeys=this._listAnimationSettingsKeys(t),document.querySelectorAll(".elementor-invisible[data-settings]").forEach(t=>{const e=t.getBoundingClientRect();if(e.bottom>=0&&e.top<=window.innerHeight)try{this._animateElement(t)}catch(t){}})}_animateElement(t){const e=JSON.parse(t.dataset.settings),i=e._animation_delay||e.animation_delay||0,n=e[this.animationSettingKeys.find(t=>e[t])];if("none"===n)return void t.classList.remove("elementor-invisible");t.classList.remove(n),this.currentAnimation&&t.classList.remove(this.currentAnimation),this.currentAnimation=n;let s=setTimeout(()=>{t.classList.remove("elementor-invisible"),t.classList.add("animated",n),this._removeAnimationSettings(t,e)},i);window.addEventListener("rocket-startLoading",function(){clearTimeout(s)})}_listAnimationSettingsKeys(t="mobile"){const e=[""];switch(t){case"mobile":e.unshift("_mobile");case"tablet":e.unshift("_tablet");case"desktop":e.unshift("_desktop")}const i=[];return["animation","_animation"].forEach(t=>{e.forEach(e=>{i.push(t+e)})}),i}_removeAnimationSettings(t,e){this._listAnimationSettingsKeys().forEach(t=>delete e[t]),t.dataset.settings=JSON.stringify(e)}static run(){const t=new RocketElementorAnimation;requestAnimationFrame(t._detectAnimations.bind(t))}}document.addEventListener("DOMContentLoaded",RocketElementorAnimation.run);</script></body>
</html>
				
			

Save and close the file then change the ownership of the example.com directory to www-data:

				
					chown -R www-data:www-data /var/www/html/example.com
				
			

Next, you will need to create a virtual host configuration file for Nginx to serve the above content. You can create it inside /etc/nginx/conf.d/ directory:

				
					nano /etc/nginx/conf.d/example.com
				
			

Add the following lines:

				
					server    {
listen 80;
server_name example.com www.example.com;
root /var/www/html/example.com;
index index.html index.htm index.nginx.debian.html;
error_log /var/log/nginx/example.com.error;
access_log /var/log/nginx/example.com.access;

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

Save and close the file when you are done.

  • listen: Define the Nginx listening port.
  • server_name: Define the domain name for your website.
  • root: Define the path of your website data directory.
  • index: Define the default file that you want to serve.
  • error_log: Define the path of the Nginx error log.
  • access_log: Define the path of the Nginx access log.

Now, verify the Nginx configuration file for any syntax error using the following command:

				
					nginx -t
				
			

Sample output:

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

Finally, reload the Nginx service to apply all the configuration changes.

				
					systemctl restart nginx
				
			

Verifying Nginx Virtual Host

At this point, your website is hosted on the example.com domain. To verify it, open your web browser and type the URL http://example.com. You should see your example.com default HTML page on the following screen:

verify nginx web server virtual host

Secure Nginx with Let's Encrypt SSL

If you are hosting a website using Nginx in a production environment, it is recommended to secure it using the Let’s Encrypt SSL. Let’s Encrypt is an open certificate authority and nonprofit Internet Security Research Group. It runs for the public’s benefit and provides a free SSL certificate to enable HTTPS (SSL/TLS) for websites.

In order to obtain a free SSL certificate from Let’s Encrypt, you will need to install the Certbot client package in your system. Certbot is a certificate installer that allows you to download and a certificate to your site in just a couple of minutes.

You can install the Certbot client package for Nginx using the following command:

				
					apt-get install python3-certbot-nginx -y
				
			

After installing Certbot package, run the following command to download and add a certificate to your website:

				
					certbot --nginx -d example.com
				
			

You will be asked to provide a valid email address and accept the term of service as shown below:

				
					Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): hitjethva@gmail.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.com
Waiting for verification...
Cleaning up challenges
Deploying Certificate to VirtualHost /etc/nginx/conf.d/example.com

				
			

Next, choose whether or not to redirect HTTP traffic to HTTPS as shown below:

				
					- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
				
			

Type 2 and hit Enter to finish the installation. You should see the following output:

				
					Redirecting all traffic on port 80 to ssl in /etc/nginx/conf.d/example.com

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://example.com

You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=example.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

IMPORTANT NOTES:
 - Congratulations! Your certificate and chain have been saved at:
   /etc/letsencrypt/live/example.com/fullchain.pem
   Your key file has been saved at:
   /etc/letsencrypt/live/example.com/privkey.pem
   Your cert will expire on 2020-10-30. To obtain a new or tweaked
   version of this certificate in the future, simply run certbot again
   with the "certonly" option. To non-interactively renew *all* of
   your certificates, run "certbot renew"
 - Your account credentials have been saved in your Certbot
   configuration directory at /etc/letsencrypt. You should make a
   secure backup of this folder now. This configuration directory will
   also contain certificates and private keys obtained by Certbot so
   making regular backups of this folder is ideal.
 - If you like Certbot, please consider supporting our work by:

   Donating to ISRG / Let's Encrypt:   https://letsencrypt.org/donate
   Donating to EFF:                    https://eff.org/donate-le

 - We were unable to subscribe you the EFF mailing list because your
   e-mail address appears to be invalid. You can try again later by
   visiting https://act.eff.org.

				
			

Now, your Nginx website is secured with Let’s Encrypt SSL. You can access it securely using the URL https://example.com.

Nginx Web Server Installation Complete

In the above guide, we explained how to set up an Nginx web server on Ubuntu. We also explained how to use virtual hosting to host a website using a domain name. I hope you have now enough knowledge to host your own website using Nginx.

Avatar for Hitesh Jethva
Hitesh Jethva

I am a fan of open source technology and have more than 10 years of experience working with Linux and Open Source technologies. I am one of the Linux technical writers for Cloud Infrastructure Services.

0 0 votes
Article Rating
Subscribe
Notify of
0 Comments
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x