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.
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
.
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
#!/bin/sh
ssh [email protected]
cd /var/www/website
git switch main
git fetch origin
git reset --hard origin/main
git clean -fd
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
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
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.
You can check out this video if you don't like reading https://www.youtube.com/watch?v=icfevBYas9s
-
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
andid_rsa.pub
can be found under~/.ssh
folder. -
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. -
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!
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
For more information on GitHub SSH keys check out Generating SSH keys
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
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
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.
-
DBP_LOGIN_KEY
The private SSH key to login to your server.
-
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