Using Git to Deploy a Static Website

1 minute read

This site is static, built using Jekyll and the Minimal Mistakes theme.

Once you have it set up, a new post is as simple as writing a new Markdown file, like this one, with the correct Front Matter:

Markdown file screenshot

Then building:

james@Jamess-iMac: ~/Projects/ on master[!?$]
$ JEKYLL_ENV=production bundle exec jekyll build 2> /dev/null
Configuration file: /Users/james/Projects/
            Source: /Users/james/Projects/
       Destination: /Users/james/Projects/
 Incremental build: disabled. Enable with --incremental
       Jekyll Feed: Generating feed for posts
                    done in 1.531 seconds.
 Auto-regeneration: disabled. Use --watch to enable.

Generating the new _site folder:

Git status screenshot

The Git repo for this site has the usual origin remote, but also a remote named deploy:

james@Jamess-iMac: ~/Projects/
$ cat config
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
	active = .
[remote "origin"]
	url =
	fetch = +refs/heads/*:refs/remotes/origin/*
	sslVerify = true
[branch "master"]
	remote = origin
	merge = refs/heads/master
[remote "deploy"]
	url = xxxxx@
	fetch = +refs/heads/*:refs/remotes/deploy/*

The deploy remote is a bare git repository on the Web server, that simply receives the latest git objects. There’s no working tree:

root@hkwarnings: /usr/src/stouty.git
$ ls
HEAD  branches  config  description  hooks  info  objects  packed-refs  refs

However, it’s configured with a post-receive Git hook:

These scripts run before and after pushes to the server.

The post-receive hook runs after the entire process is completed and can be used to update other services or notify users.

I have it configured to change directory to the Web root, which is also a Git repo, with the same origin as the working repo on my local machine, and simply execute git pull1:

root@hkwarnings: /usr/src/stouty.git/hooks
$ cat post-receive
#!/usr/bin/env bash
unset GIT_DIR && cd /var/www/html/ && git pull
[[ ! -d "/var/www/html/" ]] && \
    { mkdir -vp  "/var/www/html/"; } && \
    { chown -R james:www-data "/var/www/html/";}  && \
    { chown -R james:www-data "/var/www/html/";}

The deployment process is:

  1. Commit changed files to local repo.
  2. Push to origin.
  3. Push to deploy.

That’s it.

  1. The .well-known/acme-challenge is just to ensure the directory exists for Certbot challenges during certificate renewal.