AWS LightSail CI / CD

Photo by the blowup on Unsplash

AWS LightSail CI / CD

Prerequisites

  • Project on GitHub (in this tutorial I’m using the Next js application).

  • Server SSH private key (the key you create while creating a new instance).

Step 1 - Create GitHub Action secrets

We need 3 Action secrets AWS_USERNAME AWS_HOSTNAME AWS_PRIVATE_KEY

  • Navigate to the main page of the repository.

  • Click on the Setting Tab (top right area).

  • Select Action under “Secrets”

  • Click on the “New repository secret” button (top right area)

  • Set Name to “AWS_PRIVATE_KEY".

  • Paste the content of the server SSH private key and remove ----BEGIN RSA PRIVATE KEY---— and ----END RSA PRIVATE KEY---—

  • Click on “Add secret”

  • follow the above point to add further “action secrets”

  • Set AWS_USERNAME value to your Linux users (most commonly centos, apache2) you can use whoami command to get your current user name.

  • Set AWS_HOSTNAME value to your server IP address.

You can also add any ENV variable as Action secrets by following the same guide above.

Step 2 - Setup Workflows

This is the part where all magic happens

  • Create folders in your project repository my-cool-app/.github/workflows

  • Set up your workflow by creating two .yml files. For the sake of simplicity, we named it build.yml and deploy.yml.

#build.yml

name: build

on:
    push:
    branches: [ main ]
  pull_request:
    branches: [ main ]
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    strategy:
      matrix:
        node-version: [16.x]
        # See supported Node.js release schedule at https://nodejs.org/en/about/releases/

    steps:
    - uses: actions/checkout@v2
    - name: Use Node.js ${{ matrix.node-version }}
      uses: actions/setup-node@v2
      with:
        node-version: ${{ matrix.node-version }}
        cache: 'npm'
    - run: npm ci
    - run: npm run build
      env:
        NEXT_PUBLIC_API_URL: ${{ secrets.NEXT_PUBLIC_API_URL }}

Add env variable under env: if any.

#deploy.yml

name: deploy

on:
  push:
    branches:
      - main
  workflow_dispatch:  

jobs:
  deploy:
      needs: [build]  # require build to pass before deploy runs
    name: Deploy
    runs-on: ubuntu-latest
    environment: production

    steps:
    - name: Checkout
      uses: actions/checkout@v2

    - name: SSH to Host
      env:
        AWS_PRIVATE_KEY: ${{ secrets.AWS_PRIVATE_KEY  }}
        AWS_HOSTNAME: ${{ secrets.AWS_HOSTNAME }}
        AWS_USERNAME : ${{ secrets.AWS_USERNAME  }}

      run: |
          echo "$AWS_PRIVATE_KEY" > private_key && chmod 600 private_key
          ssh -o StrictHostKeyChecking=no -i private_key ${AWS_USERNAME}@${AWS_HOSTNAME} '

            # 📌 Start your instance/server related tasks form here.
            # 1
            cat whereami.txt
            # 2
            bash ~/scripts/my-app-deploy.sh
          '

#1

Tip: Create whereami.txt a file on your server to test out the connection.

#2

You can run your .sh file stored on your LightSail server, the script will contain all the required commands to build and start your application.

#my-app-deploy.sh

pm2 stop my-app

git pull

npm install

npm run build

pm2 start my-app

echo "my-app-deploy script executed"

WTH is pm2?

it is a production process manager for Node.js applications with a built-in load balancer.