# Deploying Node.js and React on Ubuntu: A Complete Tutorial

### 1\. To log in to your Linux (Ubuntu) server via SSH

**To log into your server, open a terminal on your local machine.**

```bash
ssh root@server_ip_address
```

Accept the warning about host authenticity, if it appears, and provide your root password.

1. **Install Node/NPM using NVM**
    

To install Node.js using NVM (Node Version Manager) on Ubuntu, follow these steps:

```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh | bash
```

2. **Load NVM Script:** The NVM install script updates your shell profile (`.bashrc`, `.zshrc`, etc.).
    
    > To start using NVM right away, you need to source this profile or restart your terminal.
    
    ```bash
    /*If you're using bash*/
    source ~/.bashrc
    
    /*If you're using zsh*/
    source ~/.zshrc
    ```
    
3. **Verify NVM Installation:** Verify that NVM has been installed correctly by checking its version:
    
    ```bash
    nvm --version
    ```
    
4. **Install Node.js:** Use NVM to install the latest LTS (Long Term Support) version of Node.js:
    
    ```bash
    nvm install --lts
    ```
    
    You can also install a specific version of Node.js:
    
    ```bash
    nvm install 18.17.0  # Replace with the desired version number
    ```
    
5. **Use Node.js:** Set the installed Node.js version as the default version:
    
    Or for a specific version:
    
    ```bash
    nvm use 18.17.0  # Replace with the desired version number
    ```
    
6. **Verify Node.js and NPM Installation:** Check that Node.js and NPM (Node Package Manager) were installed correctly:
    
    ```bash
    node -v
    npm -v
    ```
    

### 2\. To clone multiple private repositories

you'll need to follow a process that allows you to manage multiple SSH keys for each repository. Here’s a step-by-step guide:

**1\. Generate SSH Keys for Each Repository**

Generate a unique SSH key pair for each private repository. You can specify a different name for each key to distinguish them.

```bash
sudo ssh-keygen
```

When prompted, save the key with a unique name (e.g., `~/.ssh/id_rsa_repo1, ~/.ssh/id_rsa_repo2,` etc.).

**2\. Create SSH Config for Each Repository**

Create or modify the SSH config file to include entries for each repository. This file will tell SSH which key to use for each repository.

```bash
sudo nano ~/.ssh/config
```

Add the following entries to the file, customizing them for each repository:

```bash
Host repo1
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_rsa_repo1

Host repo2
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_rsa_repo2
```

**3\. Add SSH Keys to GitHub**

For each SSH key, copy the public key to your clipboard and add it to your GitHub repository’s deploy keys.

```bash
sudo cat ~/.ssh/id_rsa_repo1.pub
sudo cat ~/.ssh/id_rsa_repo2.pub
```

* Go to your GitHub repository settings.
    
* Navigate to "Deploy Keys".
    
* Add the new key and check "Allow write access" if necessary.
    

**4\. Test SSH Connection**

To verify that SSH is working correctly, run:

```bash
ssh -T git@repo1
ssh -T git@repo2
```

This should return a message saying you've successfully authenticated, which you already confirmed.

**5\. Clone the Repository**

Finally, attempt to clone the repository using the specified host from your SSH configuration:

```bash
cd /home/
git clone repo1:testuser/repo1.git (node app)
git clone repo2:testuser/repo2.git (React app)
```

This command tells Git to use the `repo1 and repo2` host configuration from your `~/.ssh/config` file.

### 3\. To set up PM2 to manage

1. **Install PM2 globally**
    

Install PM2 globally using npm:

```plaintext
sudo npm install -g pm2
```

2. **To run a Node (express) app application, follow these steps:**  
    For more detailed information, you can visit the [Deploy Your Node.js Application : A Complete guide](https://theshubham.hashnode.dev/how-to-clone-your-private-git-repository-and-deploy-on-digitalocean-your-node-js-application-with-nginx-and-ssl#heading-6-setup-pm2-process-manager-to-keep-your-app-running)
    

```bash
cd repo1
pm2 start app.js #(or whatever your file name)

# Other pm2 commands
pm2 show app
pm2 status
pm2 restart app
pm2 stop app
#(Show log stream)
pm2 logs
#(Clear logs)
pm2 flush
```

3. **To Make Sure app starts when reboot**
    

```bash
pm2 startup ubuntu
```

You should now be able to access your app using your IP and port. Now we want to setup a firewall blocking that port and setup NGINX as a reverse proxy so we can access it directly using port 80 (HTTP).

4. **To run a React application, follow these steps:**
    
    1. **Setup & Build Your React App**
        

If your React app is not yet built, build it using the following command:

```plaintext
cd repo2
npm install
npm run build
```

This will create a `build` directory containing the production-ready version of your React application.

2. **Serve the React App**
    

You can use a simple static file server like `serve` to serve your built React app. First, install `serve`:

```bash
npm install -g serve
```

3. **Create a PM2 Configuration File**
    

Create a PM2 configuration file to manage your React app. Create a file called `repo1.config.js` in your project directory:

```bash
module.exports = {
  apps: [
    {
      name: 'repo2',
      script: 'serve',
      args: '-s build',
      env: {
        PM2_SERVE_PORT: 3000,  // Change this to the port you want to use
        PM2_SERVE_PATH: './build',
        PM2_SERVE_SPA: 'true',
        PM2_SERVE_HOMEPAGE: '/index.html'
      }
    }
  ]
};
```

4. **Start the App with PM2**
    

Use PM2 to start the application:

```bash
pm2 start repo2.config.js
```

5. **Save the PM2 Process List and Enable Startup Script**
    

To ensure your application starts on system boot, save the PM2 process list and generate a startup script:

```bash
pm2 save
pm2 startup
```

The `pm2 startup` command will display an additional command to run. Copy and execute it. This command generates and configures the startup script for your operating system.

6. **Monitor Your Application**
    

You can monitor your application using the following PM2 commands:

* List all running processes:
    
    ```bash
    pm2 list
    ```
    
* View logs of your application:
    
    ```plaintext
    pm2 logs
    ```
    
* View detailed information about a specific process:
    
    ```plaintext
    pm2 info repo2
    ```
    

### 4\. Setup ufw firewall

```bash
sudo ufw enable
sudo ufw status
# Port 22
sudo ufw allow ssh  
# Port 80
sudo ufw allow http  
 # Port 443 
sudo ufw allow https
```

### 5\. Configuring Nginx and setting up a domain to serve

your React app involves several steps. Here’s a step-by-step guide to get you through the process:

1. **Install Nginx**
    

First, ensure Nginx is installed on your server:

```plaintext
sudo apt update
sudo apt install nginx -y
```

2. **Configure Nginx**
    

Create a new Nginx configuration file for your domain. Replace `your_domain_name or project_name` with your actual domain name.

```plaintext
sudo nano /etc/nginx/sites-available/your_domain
```

Add the following configuration:

```bash
server {
    listen 80;
    server_name  www.your_domain.com;

    location / {
        proxy_pass http://localhost:3000;  # Port where your React app is running
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
    }
}
```

3. **Enable the Configuration**
    

Create a symbolic link from this configuration file to the `sites-enabled` directory:

```bash
sudo ln -s /etc/nginx/sites-available/your_domain /etc/nginx/sites-enabled/
```

4. **Test Nginx Configuration**
    

Test the Nginx configuration for syntax errors:

```bash
sudo nginx -t
```

If the test is successful, restart Nginx to apply the changes:

```bash
sudo systemctl restart nginx
```

### 5\. Obtain an SSL Certificate (Optional but Recommended)

It is highly recommended to use HTTPS for your site. You can obtain a free SSL certificate from Let's Encrypt.

Install Certbot:

```bash
sudo apt install certbot python3-certbot-nginx -y
```

Obtain and install the SSL certificate for your domain:

```bash
bsudo certbot --nginx -d your_domain -d www.your_domain
```

Follow the prompts to complete the installation.

### 6\. Update DNS Settings

Ensure that your domain's DNS settings point to your server’s IP address. This can usually be done through your domain registrar’s website. Add an A record for `your_domain` and `www.your_domain` pointing to your server's public IP address.

### Conclusion

By following these steps, your React app should be served through Nginx and be accessible via your domain name. Additionally, using Certbot with Let's Encrypt provides HTTPS support, enhancing the security of your website.
