I goofed / use git to build and upload a Jekyll site
While moving my blog to NearlyFreeSpeech.net, I figured it would be handy if I could automate building and uploading. Euan Torano has a promising looking guide for Deploying Hugo on NearlyFreeSpeech.NET with Git, and Jesse Squires has Building a site with Jekyll on NearlyFreeSpeech.
While following these guides, I ran into issues with the site.git
directory
containing the actual git content under site.git/site
; I’m not by any means a
git expert (I’m learning as I go along with this site, picking it up in the last
couple of months), so I have no idea why my setup is off.
The next thing I wanted to solve was avoiding placing the actual remote git repo on NearlyFreeSpeech.net, instead using my diminutive print server at home, so that I could avoid duplicating the content on the server.
Finally, I wanted my Git hooks to build and then upload the blog content my web
directory on NearlyFreeSpeech.net. While doing that I discovered that missing a
/
uploaded my content into a subdirectory on the server.
So, here’s a slight remix of what I got working. In the following, my workstation is running Debian 11, my print server is running Ubuntu 22.04, and my web host is running FreeBSD 12.4-RELEASE.
Before you begin
Ensure that install Ruby and other prerequisites for Jekyll.
If you haven’t, place existing Jekyll content under Git version control.
Create a bare Git repository
Create a bare Git repository. Later you’ll use this as your remote to push blog changes from your workstation.
Run the following commands to create a bare Git repository. I ran the commands on my print server, the other tutorials suggest doing this on the NearlyFreeSpeech server.
# If you're using this on NearlyFreeSpeech.net, uncomment the following line
# cd $HOME
# If you're using this on NearlyFreeSpeech.net, comment the following line
cd $HOME/private
mkdir site.git
cd site.git
git init --bare
Create a checkout directory
This contains a checkout of the repository that Jekyll works on. What I gather happens is that a Git hook that you’ll create uses this directory to checkout the Jekyll content on the remote and then use that copy to build your site.
Run the following commands to create a checkout directory. Again, I ran the commands on my print server.
# If you're using this on NearlyFreeSpeech.net, uncomment the following line
# cd $HOME
# If you're using this on NearlyFreeSpeech.net, comment the following line
cd $HOME/private
mkdir site_checkout
cd site_checkout
# If you're using this on NearlyFreeSpeech.net, uncomment the following line
#git clone $HOME/site.git
# If you're using this on NearlyFreeSpeech.net, comment the following line
git clone /home/private/site.git/
Create a post-receive Git hook
The following script runs each time you run git push
to the remote repo. In
the site.git
directory (the bare git repo), there is a hooks/
directory with
sample scripts that you can look at for ideas of other things you can do with
hooks.
In this case, create a new file in /home/private/site.git/hooks/post-recieve
and add the following content:
#!/bin/bash
set -ex
# I set $HOME explicitly on my print server
export GEM_HOME=$HOME/.gems
export PATH="$HOME/.gems/bin:$PATH"
# If you're using this on NearlyFreeSpeech.net, uncomment the following line
# SITE_CHECKOUT=$HOME/site_checkout/site
# If you're using this on NearlyFreeSpeech.net, comment the following line
SITE_CHECKOUT=$HOME/private/site_checkout/site
GIT_DIR=$SITE_CHECKOUT/.git
BUILD_WWW=$HOME/www
# The following is the WWW directory on your actual web server
PUBLIC_WWW=/home/public/
cd $SITE_CHECKOUT
git --git-dir=$GIT_DIR status
git --git-dir=$GIT_DIR pull -f
git --git-dir=$GIT_DIR status
# Uncomment the following line to update your Ruby gems every time that you run
# git push
#bundle install
bundle exec jekyll build --destination $BUILD_WWW
# The following fix any permissions on directories and files before upload
find $BUILD_WWW -type d -exec chmod 755 {} \;
find $BUILD_WWW -type f -exec chmod 644 {} \;
# For the following rsync commands, change the following:
# username: your username
# web_server_ssh_address: the ssh address to connect to your web server
# Use the following rsync command to test that rsync uploads the files that
# you expect and to the locations that you expect:
rsync -v -rz --checksum --delete --dry-run $BUILD_WWW/ username@web_server_ssh_address:$PUBLIC_WWW
# After verifying that the test command works as expected, comment it out and
# uncomment the following line:
#rsync -v -rz --checksum --delete $BUILD_WWW/ username@web_server_ssh_address:$PUBLIC_WWW
exit
Run the following command to set the execute bit on the script:
chmod ug+x /home/private/site.git/hooks/post-receive
Create a remote repo on your workstation
Run the following command:
git remote add local_remote trunk ssh://username@local_server/home/private/site.git
Change the following:
- local_remote: a name for your local_remote repository
- trunk: the name for the main branch, typically
trunk
,main
, ormaster
- username: your username
- local_server: the server the remote is on; in my case, it’s my printserver
Edit, commit, build and upload
Create a blog entry with your desired editor. Then, run the following commands to commit your changes:
git add file_name
git commit
Replace file_name with file name(s) that you edited. When you run git commit, an editor is displayed; enter a commit message and save.
Then, push your changes to your remote:
git push local_remote
Pushing your content causes the post-receive script to run, which builds the site and uploads necessary changes to the web server (saving you space and network transit fees).