Hi. Today I would like to go over how I changed things up a bit and am now able to push my site updates to GitHub, which then pushes the updates to the live production server. This should allow me to add checks within GitHub to ensure my site it updated only if everything is correct. Though I won’t go into that here today. I will be focusing on the GitHub Action.
The Idea
Again the basic idea is pretty simple. I will push updates to my GitHub repo. This will then cause GitHub to trigger an action that will push the updates to my live production site server. In this case I will be using the actions/checkout instead of pushing directly to the production server. Less risk of mistakes, if you have checks in place on GitHub.
Requirements
- Actions must be done by unprivileged users.
- Connect over SSH
Getting Everything we Need
SSH
- We need to generate a new ssh key pair. For simplicity I went with the standard rsa with 4096.
ssh-keygen -t rsa -b 4096 -C "[identifier]@linode" -f linode
This creates two files. linode the private key. The one we need to keep really safe. And linode.pub the public key that we usually share.
Things are going to be a little different here since we are actually going to put the private key into GitHub as a repository secret. And add the public key to the remote, linode, server.
Before we do that we also need to get some information about the destination server. We need the information that would normally be stored in the known_hosts file when we connect to a remote server using standard ssh
We can get this information with:
ssh-keyscan -t rsa [host address/IP address]
You should see that I used -t rsa
here because my ssh keys are also rsa
.
- Add these ssh details to our GitHub repo. We have to open our repo on GitHub and add our secrets to the repo we will be pushing to.
Access Settings -> Secrets and create the following two secrets. Using the New Respository Secret button.
Name: LINODE_KEY
Contents:
-----BEGIN OPENSSH PRIVATE KEY-----
b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAACFwAAAAdzc2gtcn
--snip--
-----END OPENSSH PRIVATE KEY-----
I know this looks odd but, Github will keep this safe. And I would use a unique key anyway. Just in case you need to burn it in the future.
Next we need to add the second secret.
Name: LINODE_KNOWN_HOSTS
Contents: This will be the output you get from the ssh-keyscan
command listed earlier.
- We next need to add the contents of
linode.pub
to the remote server’sauthorized_keys
under.ssh
for the user we plan to connect as. There are lots of guides online for this.
GitHub Action
At this point we can start putting the GitHub Action together. We do this under .github/workflows/
name: Linode Push Update
on:
push:
branches:
- master
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Prepare ssh keys
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.LINODE_KEY }}
known_hosts: ${{ secrets.LINODE_KNOWN_HOSTS }}
- name: Checkout the Repo
uses: actions/checkout@v2
with:
ssh-key: ${{ secrets.LINODE_KEY }}
fetch-depth: 0
ref: master
- name: Push to Linode
run: |
git config user.name github-actions
git config user.email github-actions@github.com
git remote add prod ssh://[username]@[host]:/var/repos/[remote-repo-name].git
git push prod
Most of this is pretty straight forward. But I was missing an important step initially. That is the use to of the shimataro/ssh-key-action. This action is needed as it will add our secret ssh data so that we authenticate when we connect to the remote server. It adds the LINODE_KEY and the LINODE_KNOWN_HOSTS information.
If you are wondering about the remote-repo-name.git this is because it should be created as a bare git repo. If you want to know more about how I created it and the post-receive script that is eventually triggered. Take a look at my previous post here
Using this approach I was able to reuse my previously written post-receieve hook script on the remote server to update the live site. So I didn’t need to change anything on the remote server.
Closing
I hope that was interesting and helps others.