GitHub Action Autodeploy
What
I need a way to pull from GitHub when new content has been pushed to the repo. The builtin method for GitHub is actions which be used to run a script when certain conditions are met, like a push to the main branch.
Why
Simply I wanted a way that when I pushed this website to GitHub, the server would automatically pull the latest version compile and then host the site. A cron job can do this on a set schedule, but for the way that I work that would be wastful.
How
Server Setup
- Create a new user with no sudo access
sudo adduser <USERNAME> - Create SSH keys:
ssh-keygen -t rsa -b 4096
No additional information is needed, you can just press enter at each question - Add the public key to the authorized_keys file:
cat /root/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys - Copy private key into your clipboard:
cat /root/.ssh/id_rsa
This is needed by the GitHub Action - To increase the security of allowing SSH connections from WAN the config
can be edited to disable logging in with a password unless the connection is
comming from a LAN address
/etc/ssh/sshd_config.d/50-cloud-init.conf
#Default config PasswordAuthentication no AuthenticationMethods publickey Match Address 192.168.1.0/24 PasswordAuthentication yes AuthenticationMethods publickey passwordCaution
Pay attention to the fact the the file name/path may be slightly different on your machine and the LAN address range might be different
GitHub Setup
- Go to “Settings > Secrets and Variables > Actions”
- Create the following secrets:
SSH_PRIVATE_KEYPrivate key that shoule be in your clipboardSSH_USERnon sudo user created earlierSSH_HOSThostname/ip-address of your serverSSH_PORTport to connect over (default 22)
- Go to the “Actions” tab in your GitHub repository
- Click on “set up a workflow yourself →”
on:
push:
branches:
- main
workflow_dispatch:
jobs:
run_pull:
name: run pull
runs-on: ubuntu-latest
steps:
- name: install ssh keys
# check this thread to understand why its needed:
# https://stackoverflow.com/a/70447517
run: |
install -m 600 -D /dev/null ~/.ssh/id_rsa
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/id_rsa
echo "${{ secrets.SSH_HOST }}" > ~/.ssh/my_hosts
grep -h "" ~/.ssh/my_hosts | xargs -r -n1 ssh-keyscan -H -p ${{ secrets.SSH_PORT }} >> ~/.ssh/known_hosts
- name: connect and pull
run: |
echo "${{ secrets.SSH_PRIVATE_KEY }}" > ~/.ssh/machine.key
chmod 600 ~/.ssh/machine.key
ssh -i ~/.ssh/machine.key ${{ secrets.SSH_USER }}@${{ secrets.SSH_HOST }} -p ${{ secrets.SSH_PORT }} "./deploy.sh && exit"
- name: cleanup
run: rm -rf ~/.sshAdditional Notes
The code may not be the most effecient, but it works after many trial and error attempts.
cd ~/mostdiv
git checkout main
git pull
hugoIn getting this to work some possibly silly things were done with permissions
including doing chmod -R 777 ~/ in an attempt to get nginx to read files in
the users home directory
Caution
It is imperative that the home folder has 755 or stricter permissions set or
you will get Permission denied (publickey).
Also of note:
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys