Serving Multiple Applications with Nginx
Tags: linux, centos, server, nginx
Published: 2020-05-01 22:28:36

Imagine this scenario, you just got your dream DevOps job. You are very excited. In no time, you get your first task to host a javascript, python and PHP application on a single Linux centos server. At first, you are confused about how you'll serve multiple applications from a single server. You do a little digging and then you strike gold. Nginx!

"**NGINX** is open-source software for web serving, reverse proxying, caching, load balancing, media streaming, and more. It started out as a web server designed for maximum performance and stability. In addition to its HTTP server capabilities, NGINX can also function as a proxy server for email (IMAP, POP3, and SMTP) and a reverse proxy and load balancer for HTTP, TCP, and UDP servers."

**Prerequisite:**
- Linux centos server

##STEP 1
Log in to your server using ssh 
```
ssh root@server_ip_address
```
You'll be asked to input your **password**.

**Installing Nginx on Centos**
Nginx packages can be gotten from EPEL repositories:
```
sudo yum install epel-release
```
Install Nginx:
```
sudo yum install nginx
```
Output should look like:

```output
Retrieving key from file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
Importing GPG key 0x352C64E5:
Userid     : "Fedora EPEL (7) <epel@fedoraproject.org>"
Fingerprint: 91e9 7d7c 4a5e 96f1 7f3e 888f 6a2f aea2 352c 64e5
Package    : epel-release-7-9.noarch (@extras)
From       : /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-7
Is this ok [y/N]:
```
Press **y** and **enter**

Upon completion, start Nginx and check it's status using:
```
sudo systemctl enable nginx
sudo systemctl start nginx
sudo systemctl status nginx
```

If all goes well, you should see this:
```
● nginx.service - The nginx HTTP and reverse proxy server
  Loaded: loaded (/usr/lib/systemd/system/nginx.service; enabled; vendor preset: disabled)
  Active: active (running) since Mon 2018-03-12 16:12:48 UTC; 2s ago
  Process: 1677 ExecStart=/usr/sbin/nginx (code=exited, status=0/SUCCESS)
  Process: 1675 ExecStartPre=/usr/sbin/nginx -t (code=exited, status=0/SUCCESS)
  Process: 1673 ExecStartPre=/usr/bin/rm -f /run/nginx.pid (code=exited, status=0/SUCCESS)
Main PID: 1680 (nginx)
  CGroup: /system.slice/nginx.service
          ├─1680 nginx: master process /usr/sbin/nginx
          └─1681 nginx: worker process
```

Open HTTP(**80**) and HTTPS(**433**) if you are behind a firewall with these commands:
```
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
```
Open http://YOUR_IP in your browser of choice, you should see an Nginx homepage displayed. Congratulation!!!

##Step 2
**Create a New User Account with *sudo* Privileges**
For security reasons, it is advisable not to use the root user to run commands but to create a new user with **sudo** privileges:
```
useradd username
```
- Replace **username** with your username with Sudo privileges.


**Set the User Password**
```
passwd username
```

You should get the output:
```
output
Changing password for user username.
New password:
Retype new password:
passwd: all authentication tokens updated successfully.
```
**Add User to the *sudo* Group**
```
usermod -aG wheel username
```

Switch to Newly Created User
```
su - username
```

Then list **\root** directory content:
```
sudo ls -l /root
```
You'll see a banner message the first time you **sudo** from this account:
```
output
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:

    #1) Respect the privacy of others.
    #2) Think before you type.
    #3) With great power comes great responsibility.

[sudo] password for username:
```

##Serve Multiple Applications

**Log in to the Server Using Your *username* with Root Privileges**

Our directory structure would look like this:
```
/var/www/
├── javascriptapp.com
│   └── public_html
├── pythonapp.com
│__ └── public_html
```

Let's create a directory where your javascript and python application would reside:
```
sudo mkdir -p /var/www/javascriptapp.com/public_html
sudo mkdir -p /var/www/pythonapp.com/public_html

```
`Important!`
To avoid any permission issues, let us change ownership to our **username** with sudo privileges:
```
sudo chown -R username: /var/www/javascriptapp.com
sudo chown -R username: /var/www/pythonapp.com
```
sudo vi /var/www/javascriptapp.com/public_html/index.html

Copy and paste the following lines:
```
\<!DOCTYPE html>
\<html lang="en" dir="ltr">
  \<head>
    \<meta charset="utf-8">
    \<title>Welcome to javascriptapp.com</title>
  \</head>
  \<body>
    \<h1>Success! javascriptapp.com home page!</h1>
  \</body>
\</html>
```

**Create a Server Block**
Server blocks are stored in the **/etc/nginx/conf.d** directory and must end with **.conf**
```
sudo vi /etc/nginx/conf.d/javascriptapp.com.conf
```

Copy and paste the following lines into the file, remember to replace the server name with your value:
```
server {
    listen 80;
    listen [::]:80;
    root /var/www/javascriptapp.com/public_html;
    index index.html;
    server_name example.com www.javascriptapp.com;
    access_log /var/log/nginx/javascriptapp.com.access.log;
    error_log /var/log/nginx/javascriptapp.com.error.log;
    location / {
        try_files $uri $uri/ =404;
    }
}
```

Save the file and check that configuration is right:
```
sudo nginx -t
```
Restart Nginx:
```
sudo systemctl restart nginx
```
Then visit your server name:
http://javascriptapp.com

NB: This must be a configured DNS to your server else just use the server IP address.

##Final Step
**Configure Nginx for Node JS Application**

Upload node project to **/var/www/javascriptapp.com/public_html**, build the application and start node application on a designated port.

Edit the application *.conf* file to look like this:
`sudo vi /etc/nginx/conf.d/javascriptapp.com.conf`

```
server {
    listen 80;
    listen [::]:80;
    root /var/www/javascriptapp.com/public_html;
    server_name example.com www.javascriptapp.com;
    access_log /var/log/nginx/javascriptapp.com.access.log;
    error_log /var/log/nginx/javascriptapp.com.error.log;
    location / {
        proxy_pass http://internal_server_ip:node_app_PORT;
        try_files $uri $uri/ =404;
    }
}
```
NB: You can get the **internal_server_ip** by running `hostname -I` on the terminal. See https://www.linuxtrainingacademy.com/determine-public-ip-address-command-line-curl/ for more.


Restart Nginx:
```
sudo systemctl restart nginx
```
And visit your server name or IP to verify that your application is served.

**Congratulation!** Your javascript app is successfully served!
You can follow a similar process to serve your python application in the created directory.

This post is inspired by https://www.linuxtrainingacademy.com/determine-public-ip-address-command-line-curl/