# App Server Setup

> Setup a Node / Express, Nginx, PM2, Postgres App Server

## 1. Pre-Steps

1. Build an Linux server first. See Gist Ubuntu Server Setup <https://gist.github.com/julian-iFactory/f24cc00c9e8b1984139340391c58680e>
2. SSH into server as non-root user - typically 'ifactory'
3. Have password for non-root user as its requested the first time 'sudo' is used
4. Makre sure server is up to date

```
$ sudo apt update   [ Ensure package manager is up to date ]
```

## 2. Setup NodeJS

```
$ cd ~
$ curl -sL https://deb.nodesource.com/setup_14.x -o nodesource_setup.sh   [ Download Node V14 into users directory ]
$ sudo bash nodesource_setup.sh                                           [ Run node setup script. Enter password for user. ]
$ sudo apt install nodejs                                                 [ Install node ]
$ node -v                                                                 [ Check node version ]
$ npm -v                                                                  [ Check npm version ]
$ sudo apt install build-essential                                        [ Install node build essential - required for some npm packages ]
```

<https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-20-04>

## 3. Setup PM2

```
$ sudo npm install pm2@latest -g    [ Install pm2 - node production process runner ]
$ pm2 startup systemd               [ Configures a startup script to launch PM2 and its managed processes on server reboot ]
```

This previous command generates the next command to run. Example output below for 'ifactory'.

```
$ sudo env PATH=$PATH:/usr/bin /usr/lib/node_modules/pm2/bin/pm2 startup systemd -u ifactory --hp /home/ifactory
$ pm2 save      [ 
```

To remove the PM2 startup script:

```
$ pm2 unstartup systmed
```

For more information on PM2 configuration:

<https://www.digitalocean.com/community/tutorials/how-to-set-up-a-node-js-application-for-production-on-ubuntu-20-04>

## 4. Setup Postgres

Note: there is two different postgres users. Both callsed 'postgres':

1. Linux user 'postgres' - Used to administer the database typically fromt the bash command line
2. Database user 'postgres' - Used this to login to database and perform SQL commands etc. Apps use this user.

### A. Install Postgres

```
$ sudo apt install postgresql postgresql-contrib  [ install postgres packages ]
```

### B. Change User Passwords

```
$ sudo passwd postgres                            [ Change the Linux 'postgres' user password ]
$ su - postgres                                   [ Switch to Linux Postgres user ]
$ psql -d template1 -c "ALTER USER postgres WITH PASSWORD 'new-password';"  [ Change Database 'postgres' user password ]
```

### C. Allow Remote Connections

Check firewall allows connections over default Postgres port 5432:

```
$ sudo ufw status verbose                             [ Displays firewall list ]   
$ sudo ufw allow from 119.18.38.68 to any port 5432   [ Allow connections from iFactory office IP ]
```

Allow Postgress to listen to external connections:

```
$ nano /etc/postgresql/12/main/postgresql.conf    [ Edit postgres connection file ]
```

Add a line below in the 'CONNECTIONS AND AUTHENTCIATION' section :

```
# listen_addresses = 'localhost'     [ default value is commented out ]
listen_addresses = '*'               [ listen on all IP's ] 
```

Open config file

```
nano /etc/postgresql/12/main/pg_hba.conf
```

Comment out old line and add new line

```
# IPv4 local Connections
# host all all 127.0.0.1/32 md5
host all all 0.0.0.0/0 md5          [ Accept connectionson all IP's ]
```

Exit and restart postgres

```
exit                              [ exit out of postgres user and return to ifactory user ]
sudo service postgresql restart   [ will request ifactory user password ]
```

Resources <https://www.digitalocean.com/community/tutorials/how-to-install-postgresql-on-ubuntu-20-04-quickstart> <https://www.linode.com/docs/guides/how-to-install-postgresql-on-ubuntu-16-04/>

## 5. Setup Nginx

### A. Set ownership and permssions of www folder

```
$ sudo chown -R ifactory /var/www           [ set ifactory owner of www folder ]
$ sudo chgrp -R www-data /var/www           [ set www folder to be in group www-data ]
$ sudo adduser ifactory www-data            [ add user to the www-data group that will be the app folder owner ]
$ grep ^www-data /etc/group                 [ show users in www-data group ]     
```

### B. Create website/app location

```
$ mkdir /var/www/example.com                [ create folder for a domain ]
$ chown -R ifactory /var/www/example.com    [ set ifactory owner of the folder ]
$ chmod 755 -R /var/www/example.com/        [ Set permissions ]
$ chmod g+s /var/www/example.com/           [ ensure any new files or folders inherit the set permisions ]
```

<https://unix.stackexchange.com/questions/182212/chmod-gs-command>

### C. Install & Configure Nginx

```
$ sudo apt install nginx                                    [ Install nginx package ]
$ sudo unlink /etc/nginx/sites-enabled/default              [ Disable the default configuration file by removing the symlink ]
$ sudo touch  /etc/nginx/sites-available/example.com.conf   [ Create a new site config for example.com ]
$ sudo nano /etc/nginx/sites-available/example.com.conf     [ Paste in site nginx config from above URL ]
$ sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf [ Create symlink to new site ]
$ sudo nginx -t                     [ Check nginx config syntax ]
$ sudo systemctl restart nginx      [ Restart nginx ]
```

Related Commands

```
$ find . -type l -ls                                              [ Show all symbolic links i.e symlinks ]
$ sudo nginx -t -c /etc/nginx/sites-available/example.com.conf    [ Check nginx config syntax ] 

```

<https://www.linode.com/docs/guides/how-to-install-nginx-ubuntu-18-04/>


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.nesula.com/server/untitled-1.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
