Publishing Jekyll website using Github Actions
I tend to suffer from the “if you have a hammer, everything starts to look like a nail” syndrome. So I started off with an Ansible deployment for this blog site.
That works just fine (I build the site locally, zip it, transfer it to my webserver, unzip and do an update of the site using rsync between 2 local directories). It’s included in my nginx deployment playbook.
But it’s a little complicated at the moment, since I have to manually run the Ansible playbook when I’m done editing the blog.
Enter Github actions!
Github nowadays allows you to run simple sites based on markdown documents as Github Pages, and these are also Jekyll-based. But some of the plugins I use are not compatible with Github Pages, so that is not an option for me.
Github actions will execute every time a push is done to the main branch, and deploy the changes to my nginx site.
I’ve mostly followed this blog entry : https://christianspecht.de/2020/05/03/building-and-deploying-a-jekyll-site-via-github-actions/.
I’ve moved all commands directly into the Github Action workflow, and I changed some of the actual commands.
This is the resulting Workflow Action.
name: build my Jekyll blog
on:
push:
branches:
- main
jobs:
build_job:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Build site
run: |
docker run \
-v $:/srv/jekyll -v $/_site:/srv/jekyll/_site \
jekyll/builder:latest /bin/bash -c "chmod -R 777 /srv/jekyll && JEKYLL_ENV=production jekyll build --config _config.yml,_config_prod.yml&& mkdir build && tar -czvf build/build.tar.gz -C _site ."
- name: Upload artifact
uses: actions/upload-artifact@v1
with:
name: build
path: build
deploy:
runs-on: ubuntu-latest
needs: build_job
steps:
- uses: actions/download-artifact@v1
with:
name: build
- name: Prepare SSH key and known hosts
run: |
mkdir -p ~/.ssh
echo "$" > ~/.ssh/id_rsa
chmod 600 ~/.ssh/id_rsa
ssh-keyscan $ >> ~/.ssh/known_hosts
- name: Copy the compressed file to webserver
run: |
rsync -rSlh --stats build/ $@$:/tmp
- name: Extract the zip and deploy
run: |
export GW_RND=${RANDOM}
echo " random directory: ${GW_RND} "
ssh -o StrictHostKeyChecking=yes ${{ secrets.SSH_USERNAME }}@${{ secrets.WEBHOST }} "mkdir /home/${{ secrets.SSH_USERNAME }}/$GW_RND; tar -xzf /tmp/build.tar.gz -C /home/${{ secrets.SSH_USERNAME }}/$GW_RND/"
ssh -o StrictHostKeyChecking=yes ${{ secrets.SSH_USERNAME }}@${{ secrets.WEBHOST }} "rsync -r --delete --chown=nginx:nginx /home/${{ secrets.SSH_USERNAME }}/$GW_RND/ /usr/share/nginx/gwbasics/_site"
ssh -o StrictHostKeyChecking=yes ${{ secrets.SSH_USERNAME }}@${{ secrets.WEBHOST }} "rm -rf /home/${{ secrets.SSH_USERNAME }}/$GW_RND/"
This depends on a couple of secrets to have been set in the repository settings.
I also modified some things on my webserver:
- set the setguid bit on the directory
- created a deploy user (referenced as
${{ secrets.SSH_USERNAME }}
) - prepared the ssh keys and added the public key for
${{ secrets.SSH_PRIVATE_KEY }}
to the authorized_keys of my deploy user - added my deploy user to the
nginx
group
I’m sure there’s better ways of doing certain things in Github Actions, but for a first exploration I’m happy with the result.