I’m slowly simplifying and minimizing my home server environment for no particular reason other than enjoying the KISS principle.
To give some examples I am currently migrating repos from my old Gitlab instance to a new Gitea server I’ve set up on FreeBSD. The benefit is a platform that runs well on a significantly smaller VM, and where the key product actually does get updated by the operating system’s built-in package manager. Gitlab was notoriously bad at the latter.
In parallel with that, I’ve switched my web site from Wordpress to one that’s statically generated by Jekyll. In this case the migration was basically triggered by boredom.
One nice thing about Jekyll, is that you can have the contents of your entire site stored in version control: All pages are generated from Markdown files by the
jekyll executable, and the resulting output can be presented by any webserver - I use Nginx.
Of course it would be nice to have a simple workflow to add and update posts and web pages on the go, and following the KISS principle, I decided to use git hooks to solve this need.
Please note that the following solution is based on a Gitea server running on FreeBSD. The principles are applicable on Linux too, but specific paths may differ.
What we need to achieve
We want a
git push to trigger a new version of the web site to be generated based on what’s currently in the site repository, and then the finished site to be deployed to the web server, at a location that will be presented to the web.
Configuring the web server
I’ve set up a very basic web server running Nginx on FreeBSD. I’ve configured it to present its root from
To enable the necessary automation, I added a user,
deployer, I created the directory
_site in its home directory,
chown‘d the directory so its group ownership was set to
www, and finally I symlinked
Configuring the Gitea server
I started by installing the
rubygem-bundler packages, which are necessary for Jekyll to work.
Next step was to switch to the
git user and create an ssh key-pair. I then used
ssh-copy-id to allow the git user to authenticate without a passphrase as the
deployer user on my web server.
Git hooks are not enabled by default in Gitea, as a security precaution. In my case I accept the risk, so I added the following line to the
[security] section of
After restarting the
gitea service, a
Git Hooks menu option turned up in the project settings.
The relevant hook for this purpose is
post-receive, and I edited it to add the following little script:
#!/usr/local/bin/bash -l export HOME=/usr/local/git # Install Ruby Gems to ~/gems export GEM_HOME=$HOME/gems export PATH=$GEM_HOME/bin:$PATH if [ ! -d $HOME/tmp ]; then mkdir $HOME/tmp fi WEBSERVER=websrv2.oxcrag.net TMP_GIT_CLONE=$HOME/tmp/oxcrag.net GEMFILE=$TMP_GIT_CLONE/Gemfile PUBLIC_WWW=$TMP_GIT_CLONE/_site git clone $GIT_DIR $TMP_GIT_CLONE BUNDLE_GEMFILE=$GEMFILE bundle install BUNDLE_GEMFILE=$GEMFILE bundle exec jekyll build -s $TMP_GIT_CLONE -d $PUBLIC_WWW scp -r $PUBLIC_WWW deployer@$WEBSERVER: rm -Rf $TMP_GIT_CLONE exit
To keep the script under some sort of version control, I simply added a
git_hooks directory to my site repository and created a
post-receive file in it, with the above contents. In this specific case, the lack of automation between what’s in my repo and what actually gets run on the server is a good thing from a security perspective.
Once this was in place, I could verify that it all worked by making changes to the site repo and pushing the committed changes, whereupon my web site updated as expected.
The added benefit here is that I don’t need to use my laptop to update pages: Anything that can log on to my Gitea instance and browse the website repository via the Gitea web UI can also add new pages or modify existing ones: These changes to the repository also get treated as a git push, and therefore trigger the Git post-receive hook.