The goal is to implement the ubiquitous “push to deploy” – a simple continuous delivery mechanism that automatically redeploys a git repo when a commit is pushed to its master branch.
In my case, the server on which the git repo lives is only externally accessible through a Wireguard VPN. The aim with the chosen methods is to be simple and secure, while requiring as little setup as possible (esp. regarding installations & modifications of the repo’s server).
Method 1: GitHub Actions
TL;DR
| key name | /home/github-actions/.ssh/ | github.com’s repo settings |
|---|---|---|
| SSH github-deploy-key_REPO | save priv & pub files | pub in Deploy keys: github-deploy-key_REPO |
| SSH id_github-actions | paste pub in authorized_keys | priv in Secrets: WEBSERVER_SSH_ID |
| WG github-actions.conf | (download from WG server) | conf in Secrets: WIREGUARD_CONFIG |
Only github-deploy-key_REPO, where REPO is the repo’s name, needs to be re-created for each new repository.
Details
- Create a user account for the git workflows.
- If user account already exists, skip this step and run other steps with
sudoin/home/github-actions sudo adduser github-actions# use simple passwd – will be removedsudo usermod -aG dockeruser github-actions# needs write access to/srv/docker/volumes/one137-websu - github-actions- Do all steps below as user
github-actions, thenpasswd -lto lock account
- If user account already exists, skip this step and run other steps with
- Set up deploy key (web server → github repo pull)
cat >> .ssh/config(note this config allows for multiple deploy keys for github.com, needed if handling >1 repos)
Host github.com-one137-web Hostname github.com IdentityFile ~/.ssh/github-deploy-key_one137-web- Note: The repo needs to use SSH not HTTPS for the remote
git clone [email protected]:one137/web.git one137-web/, or if already set up:git remote set-url origin [email protected]:one137/web.git
ssh-keygen -t ed25519 -C "github-deploy-key_one137-web" -f .ssh/github-deploy-key_one137-webchmod 600 .ssh/github-deploy-key_one137-webcat .ssh/github-deploy-key_one137-web.pub# and copy- Go to GitHub > Repo > Settings > Deploy keys > Add deploy key
- Paste file name and outputted PUB key. Save
- Set up Wireguard config (github actions → wireguard endpoint)
- Generate a new Wireguard config for GitHub Actions in the Wireguard Server
- Download and view the config file. Make sure no IPv6 is specified anywhere. Copy.
- Go to GitHub > repo > Settings > Secrets and variables > Actions > New Repo secret
- Name it “WIREGUARD_CONFIG” and paste copied config
- Set up actions’ key (wireguard endpoint → web server)
ssh-keygen -t ed25519 -C "id_github-actions" -f id_github-actionscat id_github-actions.pub >> .ssh/authorized_keyscat id_github-actions# and copy private keyrm id_github-actions id_github-actions.pub- Go to GitHub > Secrets and variables > Actions > New Repo secret
- Name it “WEBSERVER_SSH_ID” and paste outputted private key. Save
sudo passwd -l github-actions# to lock password-login for account- Create and commit
one137-web/.github/workflows/deploy.yml- Up-to-date example here: https://github.com/one137/web/blob/main/.github/workflows/deploy.yml
Method 2: GitHub Webhook
This methods put less load on GitHub and more on the web server itself, but doesn’t require Wireguard (that is, no need to be able to log into the web server from the WAN). It would probably scale better to multi repos as well.
Steps 1 and 2 from Method 1 GitHub Actions should be identical. 3 and 4 are replaced by doing some Nginx setup, installing some apps on the server and writing a small script.
The idea is:
9. Create a Web Hook in the repo’s settings with a payload URL of https://one137.dev/github-hook or whatever
10. Configure a location in Nginx to match that URL
11. Proxy_pass it to a python/perl/whatever server & script that will trigger a git fetch in the repo’s folder
- To avoid running an extra server, fcgiwrap can be used to “directly” execute a e.g. shell script from Nginx