Skip to main content

Command Palette

Search for a command to run...

Setting up CI/CD Through Github Actions

Updated
3 min read
Setting up CI/CD Through Github Actions
B

Full-Stack Developer | MERN + Next.js | DevOps & Cloud Enthusiast

I specialize in building dynamic web applications using the MERN stack and Next.js. Currently exploring DevOps and cloud technologies to streamline workflows, automate deployments, and optimize cloud infrastructure for scalable, efficient solutions.

Step 1 — Generate a CI/CD-friendly SSH key on your EC2

Open your EC2 terminal and run:

# Generate a new SSH key specifically for GitHub Actions
ssh-keygen -t rsa -b 4096 -m PEM -C "github-actions" -f ~/github_ec2_ci_key -N ""

Explanation:

  • -t rsa → RSA key type

  • -b 4096 → 4096-bit for strong encryption

  • -m PEM → ensures compatibility (some tools like GitHub Actions need PEM format)

  • -C "github-actions" → a comment for identification

  • -f ~/github_ec2_ci_key → saves key in your home directory

  • -N ""no passphrase (required for CI/CD)

This will create two files:

~/github_ec2_ci_key      → private key
~/github_ec2_ci_key.pub  → public key

Step 2 — Add the public key to authorized_keys

# Ensure the .ssh directory exists
mkdir -p ~/.ssh

# Append the public key to authorized_keys
cat ~/github_ec2_ci_key.pub >> ~/.ssh/authorized_keys

# Set proper permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

✅ Now your EC2 trusts this key for SSH login.


Step 3 — Test SSH locally

ssh -i ~/github_ec2_ci_key ubuntu@<EC2_PUBLIC_IP>
  • You should log in without typing a passphrase.

  • If it works, your key setup is correct.


Step 4 — Copy private key to GitHub Secrets

  1. Run:
cat ~/github_ec2_ci_key
  1. Copy everything starting from:
-----BEGIN RSA PRIVATE KEY-----

…to:

-----END RSA PRIVATE KEY-----
  1. Go to GitHub → Settings → Secrets → Actions → New repository secret

  2. Name it: EC2_KEY

  3. Paste the private key there

No passphrase needed, so you don’t need a passphrase: field in GitHub Actions.


Step 5 — Create GitHub Actions workflow

Create .github/workflows/deploy.yml in your repository:

name: Deploy to EC2

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Deploy to EC2
        uses: appleboy/ssh-action@v0.1.9
        with:
          host: ${{ secrets.EC2_HOST }}        # Your EC2 public IP
          username: ${{ secrets.EC2_USER }}    # Typically 'ubuntu'
          key: ${{ secrets.EC2_KEY }}          # Private key secret
          port: 22
          script: |
            cd /var/www/artistic_backend
            git pull origin main
            npm install
            npm run build
            pm2 restart all

OR

name: Deploy to EC2

on:
  push:
    branches:
      - master

jobs:
  deploy:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Deploy to EC2
        uses: appleboy/ssh-action@v0.1.9
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USER }}
          key: ${{ secrets.EC2_KEY }}
          port: 22
          script: |
            # Load Node.js environment (handles nvm or global install)
            if [ -f ~/.nvm/nvm.sh ]; then
              echo "Using nvm environment"
              source ~/.nvm/nvm.sh
              nvm use node
            else
              echo "Using system-wide Node.js"
              export PATH=$PATH:/usr/local/bin:/usr/bin
            fi

            cd /home/ubuntu/quick-test/backend
            echo "Pulling latest code..."
            git pull origin master

            echo "Installing dependencies..."
            npm install

            echo "Building TypeScript..."
            npx tsc -b

            echo "Restarting PM2 process..."
            pm2 restart all || pm2 start ecosystem.config.js --update-env

Step 6 — Secrets you need in GitHub

  • EC2_HOST → your EC2 public IP

  • EC2_USER → usually ubuntu

  • EC2_KEY → the private key you copied

No passphrase is required because the key is unencrypted.


Optional: Remove passphrase from an existing key

If you already generated a key with a passphrase, you can remove it:

ssh-keygen -p -f ~/existing_key
# Enter current passphrase
# For new passphrase: press ENTER
# Confirm: press ENTER

Step 7 — Verify workflow

  1. Push to the main branch.

  2. GitHub Actions will:

  • Checkout the code

  • SSH into your EC2

  • Pull latest code, install dependencies, build, and restart PM2

No more ssh: handshake failed errors because:

  • The key is trusted by EC2

  • The private key is unencrypted

  • GitHub Actions can use it in Docker without needing a passphrase

12 views

🖥️ Devops

Part 1 of 5

Explore the world of DevOps in this comprehensive series! Learn about automation, CI/CD, infrastructure as code, and best practices. Dive into tools like Docker, Kubernetes, Jenkins, and more to streamline development and operations efficiently.

Up next

Valkey Installation on ubuntu

Install Docker for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done # Add Docker's official GPG key: sudo apt-get update sudo apt-get install ca-certificates curl sudo inst...

More from this blog

"

"Mastering DevOps, Full Stack Development, AWS & Cutting-Edge Tech | Insights & Tutorials

13 posts

sudo certbot -d '*.host.deploylite.tech' --manual --preferred-challenges dns certonly