cloudlaunch/guide

Chapter 06 · GitHub Actions

Deploy automatically from GitHub

Turn the manual git push → SSH → git pull process into a repeatable deployment every time the main branch changes.

1

Create and push the portfolio

Create a project with index.html, style.css, and script.js, then initialize Git and push it to a GitHub repository.

Local project
mkdir my-portfolio
cd my-portfolio
git init
git add .
git commit -m "Initial portfolio"
git branch -M main
git remote add origin https://github.com/USERNAME/student-portfolio.git
git push -u origin main
2

Deploy to EC2 once manually

On Ubuntu, install Git, clear the Apache document root, and clone the repository. Use a public repository for this classroom exercise so git pull does not need another credential.

EC2 terminal
sudo apt update
sudo apt install git -y
cd /var/www/html
sudo rm -rf /var/www/html/*
sudo git clone https://github.com/USERNAME/student-portfolio.git .
sudo chown -R ubuntu:ubuntu /var/www/html
3

Create a deployment key

Generate a dedicated key on your local computer, add its public key to ~/.ssh/authorized_keys on EC2, and verify that the new key can connect before touching GitHub Actions.

macOS / Linux
ssh-keygen -t ed25519 -C "github-actions-deploy"
cat ~/.ssh/github-actions-deploy.pub
ssh -i ~/.ssh/github-actions-deploy ubuntu@EC2_PUBLIC_IP
Windows PowerShell
ssh-keygen -t ed25519 -C "github-actions-deploy"
Get-Content $HOME\.ssh\github-actions-deploy.pub
ssh -i $HOME\.ssh\github-actions-deploy ubuntu@EC2_PUBLIC_IP
4

Add GitHub repository secrets

In Settings → Secrets and variables → Actions, create EC2_HOST with the public IP, EC2_USER with ubuntu, and EC2_SSH_KEY with the complete private key. Never commit private keys.

5

Add the workflow

Create .github/workflows/deploy.yml and commit it to the main branch.

.github/workflows/deploy.yml
name: Deploy Portfolio

on:
  push:
    branches:
      - main

jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - name: Deploy to EC2
        uses: appleboy/ssh-action@v1
        with:
          host: ${{ secrets.EC2_HOST }}
          username: ${{ secrets.EC2_USER }}
          key: ${{ secrets.EC2_SSH_KEY }}
          script: |
            cd /var/www/html
            git pull origin main
Test the pipeline: change the portfolio, run git add ., git commit -m "Update portfolio", and git push. Watch the Actions tab, then refresh http://EC2_PUBLIC_IP.
6

Jenkins alternative

If you prefer a self-hosted automation server, install Jenkins on a separate Ubuntu host, install the Git and SSH Agent plugins, then create a Pipeline job connected to your GitHub repository. Store the EC2 private key in Jenkins Credentials as an SSH credential and never paste it into the Jenkinsfile.

Jenkins host
sudo apt update
sudo apt install fontconfig openjdk-21-jre -y
sudo wget -O /etc/apt/keyrings/jenkins-keyring.asc https://pkg.jenkins.io/debian-stable/jenkins.io-2023.key
echo "deb [signed-by=/etc/apt/keyrings/jenkins-keyring.asc] https://pkg.jenkins.io/debian-stable binary/" | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt update
sudo apt install jenkins -y
sudo systemctl enable --now jenkins
Jenkinsfile
pipeline {
  agent any
  stages {
    stage("Deploy") {
      steps {
        sshagent(["ec2-deploy-key"]) {
          sh "ssh -o StrictHostKeyChecking=no ubuntu@${EC2_HOST} \"cd /var/www/html && git pull origin main\""
        }
      }
    }
  }
}