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_REPOsave priv & pub filespub in Deploy keys: github-deploy-key_REPO
SSH id_github-actionspaste pub in authorized_keyspriv 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

  1. Create a user account for the git workflows.
    1. If user account already exists, skip this step and run other steps with sudo in /home/github-actions
    2. sudo adduser github-actions # use simple passwd – will be removed
    3. sudo usermod -aG dockeruser github-actions # needs write access to /srv/docker/volumes/one137-web
    4. su - github-actions
    5. Do all steps below as user github-actions, then passwd -l to lock account
  2. Set up deploy key (web server github repo pull)
    1. 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
    
    1. Note: The repo needs to use SSH not HTTPS for the remote
    2. ssh-keygen -t ed25519 -C "github-deploy-key_one137-web" -f .ssh/github-deploy-key_one137-web
    3. chmod 600 .ssh/github-deploy-key_one137-web
    4. cat .ssh/github-deploy-key_one137-web.pub # and copy
    5. Go to GitHub > Repo > Settings > Deploy keys > Add deploy key
    6. Paste file name and outputted PUB key. Save
  3. Set up Wireguard config (github actions wireguard endpoint)
    1. Generate a new Wireguard config for GitHub Actions in the Wireguard Server
    2. Download and view the config file. Make sure no IPv6 is specified anywhere. Copy.
    3. Go to GitHub > repo > Settings > Secrets and variables > Actions > New Repo secret
    4. Name it “WIREGUARD_CONFIG” and paste copied config
  4. Set up actions’ key (wireguard endpoint web server)
    1. ssh-keygen -t ed25519 -C "id_github-actions" -f id_github-actions
    2. cat id_github-actions.pub >> .ssh/authorized_keys
    3. cat id_github-actions # and copy private key
    4. rm id_github-actions id_github-actions.pub
    5. Go to GitHub > Secrets and variables > Actions > New Repo secret
    6. Name it “WEBSERVER_SSH_ID” and paste outputted private key. Save
  5. sudo passwd -l github-actions # to lock password-login for account
  6. Create and commit one137-web/.github/workflows/deploy.yml
    1. 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