Home

Manage Node.js Apps with Systemd: Complete Setup Guide

26 views

Yes, you can avoid using PM2 and rely solely on systemd to manage your Node.js applications and webhook listener. Systemd is a robust system and service manager for Linux-based systems, and it can efficiently handle the processes for you. Here’s how you can set up your deployment using only systemd:

Step 1: Prepare Your Server Environment

  1. Ensure Node.js and npm are Installed

    Make sure Node.js and npm are installed on your server:

    sudo apt update
    sudo apt install nodejs npm
    
  2. Install NGINX

    Install NGINX to reverse proxy the requests and handle SSL:

    sudo apt install nginx
    
  3. Install Certbot for SSL

    Install and configure Certbot to handle SSL certificates:

    sudo apt install certbot python3-certbot-nginx
    

Step 2: Set Up GitHub Webhooks

Set up GitHub Webhooks to automate the deployment process. You can use a Node.js express app to handle the webhooks:

  1. Set Up an Express App

    Set up a basic Express app to listen to GitHub webhooks:

    const express = require('express');
    const { exec } = require('child_process');
    const app = express();
    
    app.use(express.json());
    
    app.post('/webhook', (req, res) => {
      const branch = req.body.ref.split('/').pop();
    
      if (branch === 'main') {
        exec('cd /path-to-your-app && git pull && npm install && npm run build && systemctl restart main-app.service', (err, stdout, stderr) => {
          if (err) {
            console.error(`Error: ${stderr}`);
            return res.sendStatus(500);
          }
          console.log(stdout);
          res.sendStatus(200);
        });
      }
    
      if (branch === 'stage') {
        exec('cd /path-to-stage-app && git pull && npm install && npm run build && systemctl restart stage-app.service', (err, stdout, stderr) => {
          if (err) {
            console.error(`Error: ${stderr}`);
            return res.sendStatus(500);
          }
          console.log(stdout);
          res.sendStatus(200);
        });
      }
    });
    
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
    
  2. Set Up a Systemd Service for Webhook Listener

    Create a systemd service file for the webhook listener:

    sudo nano /etc/systemd/system/webhook.service
    

    Add the following configuration:

    [Unit]
    Description=GitHub Webhook Listener
    After=network.target
    
    [Service]
    ExecStart=/usr/bin/node /path-to-your-webhook.js
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    

    Enable and start the service:

    sudo systemctl enable webhook
    sudo systemctl start webhook
    

Step 3: Configure Systemd for Your Applications

  1. Create Systemd Service for the Main Branch Application

    Create and configure a systemd service file for your main application:

    sudo nano /etc/systemd/system/main-app.service
    

    Add the following content:

    [Unit]
    Description=Main App Service
    After=network.target
    
    [Service]
    WorkingDirectory=/path-to-your-app
    ExecStart=/usr/bin/npm run serve
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    

    Enable and start it:

    sudo systemctl enable main-app
    sudo systemctl start main-app
    
  2. Create Systemd Service for the Stage Branch Application

    Similarly, create a service for the stage branch:

    sudo nano /etc/systemd/system/stage-app.service
    

    Add the configuration:

    [Unit]
    Description=Stage App Service
    After=network.target
    
    [Service]
    WorkingDirectory=/path-to-stage-app
    ExecStart=/usr/bin/npm run serve
    Restart=always
    
    [Install]
    WantedBy=multi-user.target
    

    Enable and start the service:

    sudo systemctl enable stage-app
    sudo systemctl start stage-app
    

Step 4: Configure NGINX and SSL

  1. Configure NGINX for Your Domains

    Edit your NGINX configuration files to proxy the traffic:

    sudo nano /etc/nginx/sites-available/arisdomain.com
    
    server {
        listen 80;
        server_name arisdomain.com;
    
        location / {
            proxy_pass http://localhost:YOUR_MAIN_APP_PORT;
            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;
        }
    }
    

    Similarly, set up for the stage subdomain:

    sudo nano /etc/nginx/sites-available/stage.arisdomain.com
    
    server {
        listen 80;
        server_name stage.arisdomain.com;
    
        location / {
            proxy_pass http://localhost:YOUR_STAGE_APP_PORT;
            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;
        }
    }
    

    Link these configurations in the sites-enabled directory:

    sudo ln -s /etc/nginx/sites-available/arisdomain.com /etc/nginx/sites-enabled/
    sudo ln -s /etc/nginx/sites-available/stage.arisdomain.com /etc/nginx/sites-enabled/
    

    Test the NGINX configuration and restart:

    sudo nginx -t
    sudo systemctl restart nginx
    
  2. Set Up SSL with Certbot

    Use Certbot to automatically set up and configure SSL:

    sudo certbot --nginx -d arisdomain.com -d stage.arisdomain.com
    

    Certbot will automatically handle SSL renewals, but you can verify by running:

    sudo certbot renew --dry-run
    

By using systemd to manage both your applications and the webhook listener, you eliminate the need for PM2, and the services will be managed by your operating system's native service manager. This setup ensures your applications automatically restart on crash and on server reboots.