Success!
  Setting up CI/CD for Node.js with GitHub Actions can streamline your deployment by automating steps like dependency installation, environment management, and secure SSH access.
Setting up CI/CD for your Node.js app using GitHub Actions can save time and reduce errors by automating repetitive deployment tasks. In this guide, you’ll learn to configure a workflow that pulls code, installs dependencies, manages SSH securely, and deploys with PM2.
What You’ll Need
- GitHub Repository: For hosting your Node.js code.
- VPS: A server with SSH access to deploy your app.
- Secrets Setup: Add credentials (SSH key, IP, user, and environment variables) in GitHub Secrets for secure access.
GitHub Actions Workflow
Here’s a full YAML configuration with each step explained:
    name: CI/CD for Node.js App with PM2
on:
  push:
    branches:
      - main
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      # 1. Checkout Code
      - name: Checkout code
        uses: actions/checkout@v3
      # 2. Set Up Node.js
      - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '18'
      # 3. Install Dependencies
      - name: Install dependencies
        run: npm ci
      # 4. Set Up SSH for Deployment
      - name: Set up SSH key
        uses: webfactory/ssh-agent@v0.8.0
        with:
          ssh-private-key: ${{ secrets.SSH_PRIVATE_KEY }}
      # 5. Add VPS to Known Hosts
      - name: Add VPS to known hosts
        run: |
          mkdir -p ~/.ssh
          ssh-keyscan -H "${{ secrets.VPS_IP }}" >> ~/.ssh/known_hosts
      # 6. Deploy Files to VPS
      - name: Deploy to temporary directory on VPS
        env:
          VPS_USER: ${{ secrets.VPS_USER }}
        run: |
          rsync -avz --delete ./ ${VPS_USER}@${{ secrets.VPS_IP }}:/tmp/node-hello/
      # 7. Move Files to Final Directory on VPS
      - name: Move files to /root/node-hello
        env:
          VPS_USER: ${{ secrets.VPS_USER }}
        run: |
          ssh ${VPS_USER}@${{ secrets.VPS_IP }} "
            sudo rsync -avz /tmp/node-hello/ /root/node-hello/
          "
      # 8. Set Up Environment and Manage PM2
      - name: Configure environment and manage PM2
        env:
          VPS_USER: ${{ secrets.VPS_USER }}
          MONGO_URI: ${{ secrets.MONGO_URI }}
          JWT_SECRET: ${{ secrets.JWT_SECRET }}
          BCRYPT_SALT_ROUNDS: ${{ secrets.BCRYPT_SALT_ROUNDS }}
          PORT: ${{ secrets.PORT }}
          NODE_ENV: 'production'
        run: |
          ssh ${VPS_USER}@${{ secrets.VPS_IP }} "
            sudo bash -c '
            cd /root/node-hello
            # Write environment variables to .env
            cat > .env < /dev/null; then
              npm install -g pm2
            fi
            pm2 startOrRestart server.js --name \"server\" --update-env
            '
          "
      # 9. Clean Up Known Hosts
      - name: Clean up known hosts
        run: |
          ssh-keygen -R "${{ secrets.VPS_IP }}" 
  
  Workflow Breakdown
- Checkout Code: Pulls your latest code from the main branch.
- Node.js Setup: Sets up Node.js (version 18 or higher) for compatibility with modern libraries.
- Install Dependencies: npm ciis preferred overnpm installfor faster installs and consistency withpackage-lock.json.
- SSH Key Setup: Uses webfactory/ssh-agentto securely handle SSH. This action adds your SSH key to the agent without saving it locally.
- Add VPS to Known Hosts: Adds your server’s IP to the SSH known hosts list, avoiding interactive prompts during SSH.
- Deploy Files to VPS: Uses rsyncto deploy files to a temporary directory on the VPS, ensuring only the latest files are uploaded.
- Move Files to Final Directory: Moves files from the temporary to the final directory, requiring root privileges to write to /root/node-hello.
- Set Environment and PM2: Writes environment variables to a .envfile on the server, then starts or restarts the app using PM2. ThestartOrRestartcommand is efficient and reduces downtime.
- Clean Up Known Hosts: Removes the VPS IP from known hosts after deployment. This step prevents clutter and mitigates risks from SSH fingerprint changes.
Warning!
    This is a beginner setup and may not cover all scenarios. We’re open to suggestions and feedback to improve this guide, so feel free to share any ideas or tips you have.
  

