Skip to content

Instantly share code, notes, and snippets.

@JPCodaLot
Last active December 15, 2023 16:50
Show Gist options
  • Save JPCodaLot/7a88b2207437ff899cc84e2d4c193b91 to your computer and use it in GitHub Desktop.
Save JPCodaLot/7a88b2207437ff899cc84e2d4c193b91 to your computer and use it in GitHub Desktop.
Continuous deployment to a LAMP stack using Git and GitHub Actions

Using Git and GitHub Actions for deployment is overly complicated process. This document outlines what needs to be setup to get everything working together. This tutorial assumes you have already created or have access to you websites code in a GitHub repository and you have setup a LAMP stack server using a non root user.

If you havn't setup your LAMP stack yet check out this great tutorial https://www.digitalocean.com/community/tutorials/how-to-install-linux-apache-mysql-php-lamp-stack-on-ubuntu-20-04. You might also need to setup and enable HTTPS to your website using this tutorial https://www.digitalocean.com/community/tutorials/how-to-secure-apache-with-let-s-encrypt-on-ubuntu-20-04.

Overview

Changes originate inside the Desktop from your Text Editor. Those changes are saved to the Project Folder and uploaded to the Development Folder via SFTP on the Server for testing. Once the changes have been approved they are committed into the Desktop's Git and pushed to GitHub. When GitHub receives the changes it triggers a Push Event which starts up a GitHub Runner aka "Actions", or "Workflow". The GitHub Runner then triggers a Deploy Script via SSH that triggers Git to download the new changes from GitHub to the Production Folder.

Source Code Connections

The Deploy Script

Usage

A bash deploy script file could be saved on your server under ~/deploy.sh and can be run by typing sh ~/deploy.sh.

Note: Don't use the sudo command because the GitHub deploy key won't be stored under the root user

Example bash script:

#!/bin/sh
ssh [email protected]
cd /var/www/website
git switch main
git fetch origin
git reset --hard origin/main
git clean -fd

Line-by-line break down.

Connect to your origin Github repo using a deploy key.

Move to your website's root folder.

cd /var/www/somefolder

Switch to the branch you want to deploy from.

git switch main

Fetch all the new updates from your repo.

git fetch origin

Throw away all staged and unstaged changes.

git reset --hard origin/main

Remove all untracked directories and the files within them.

git clean -fd

Example output

Hi User/Repo! You've successfully authenticated, but GitHub does not provide shell access.
Connection to github.com closed.
Already on 'main'
Your branch is up to date with 'origin/main'.
HEAD is now at 15a1b5f Initial Commit

Setting up a GitHub deploy key

What is a deploy key

A deploy key is a SSH key set in your repo to grant client read-only (as well as r/w, if you want) access to your repo.

As the name says, its primary function is to be used in the deploy process in replace of username/password, where only read access is needed. Therefore, keep your repo safe from attack even if your server is breached.

How to add one

You can check out this video if you don't like reading https://www.youtube.com/watch?v=icfevBYas9s

  1. Generate a ssh key

    On your server run ssh-keygen -t rsa -b 4096 -C "[email protected]", leave the passphrase empty as you want the deploy process keyboard-less.

    After the generation, file id_rsa and id_rsa.pub can be found under ~/.ssh folder.

  2. Add ssh key to repo's "Deploy keys" setting

    On your server copy the contents of cat ~/.ssh/id_rsa.pub.

    Open https://github.com/username/repo/settings/keys and click Add deploy key. Enter a useful title and paste the previously stored text into the key field.

    If you would like the key be used to push to this repository checkoff the Allow write access box. Deploy keys always have pull access.

  3. Test the connection

    You can test the connection by:

    You might need to grant Github's key to known hosts.

    If everything went well, you will see:

      Hi User/Repo! You've successfully authenticated, but GitHub does not provide shell access.
      Connection to github.com closed.
    

    Then you are all set!

Using multiple deploy key with different repo on the same machine

You can use /.ssh/config file to config different ssh key for different repo. For more details take a look at Using Multiple Github Deploy Keys for a Single User on a Single Linux Server

Reference

For more information on GitHub SSH keys check out Generating SSH keys

GitHub Runner

About

GitHub Actions is a continuous integration and continuous delivery (CI/CD) platform that allows you to automate your build, test, and deployment pipeline. You can create workflows that build and test every pull request to your repository, or deploy merged pull requests to production.

GitHub Actions goes beyond just DevOps and lets you run workflows when other events happen in your repository. For example, you can run a workflow to automatically add the appropriate labels whenever someone creates a new issue in your repository.

GitHub provides Linux, Windows, and macOS virtual machines to run your workflows which all called runners.

For more information visit, https://docs.github.com/en/actions/learn-github-actions/understanding-github-actions

Example

Here is the deploy.yaml file GitHub uses to wait for a push on the main branch and then trigger the Deploy Script on your server over SSH.

name: Deploy Website

# Controls when the workflow will run
on:
  # Triggers the workflow on push or pull request events but only for the main branch
  push:
    branches: [ main ]

  # Allows you to run this workflow manually from the Actions tab
  workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  # This workflow contains a single job called "build"
  deploy:
    # The type of runner that the job will run on
    runs-on: ubuntu-latest

    # Steps represent a sequence of tasks that will be executed as part of the job
    steps:

      # Saves the private key and adds your server to the list of known hosts
      - name: SSH Setup
        run: |
          mkdir -p ~/.ssh/
          echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
          sudo chmod 600 ~/.ssh/id_rsa
          echo "$SSH_HOST_THUMBPRINT" > ~/.ssh/known_hosts
        shell: bash
        env:
          SSH_PRIVATE_KEY: ${{secrets.DBP_LOGIN_KEY}}
          SSH_HOST_THUMBPRINT: ${{secrets.DBP_THUMBPRINT}}

      # Connects to your server via ssh and runs the deploy bash script
      - name: Run Deploy Script
        run: ssh -i ~/.ssh/id_rsa [email protected] sh deploy.sh

GitHub Secrets

Note the ${{secrets.SOMETHING}} placeholders in the yaml file above. These are called secrets and they allow you to store sensitive information in your organization, repository, or repository environments.

For this deployment scheme you will need to create two secrets.

  1. DBP_LOGIN_KEY

    The private SSH key to login to your server.

  2. DBP_THUMBPRINT

    The thumbprint should be the thumbprint of your server. This is needed to make sure that the GitHub runner is connecting directly to your server and not to some man-in-the-middle.

For more information on how to create them visit, https://docs.github.com/en/actions/security-guides/encrypted-secrets

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment