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/jamesstout.github.io on master[!?$]
$ JEKYLL_ENV=production bundle exec jekyll build 2> /dev/null
Configuration file: /Users/james/Projects/jamesstout.github.io/_config.yml
            Source: /Users/james/Projects/jamesstout.github.io
       Destination: /Users/james/Projects/jamesstout.github.io/_site
 Incremental build: disabled. Enable with --incremental
      Generating...
       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/jamesstout.github.io/.git
$ cat config
[core]
	repositoryformatversion = 0
	filemode = true
	bare = false
	logallrefupdates = true
	ignorecase = true
[submodule]
	active = .
[remote "origin"]
	url = https://jamesstout@github.com/jamesstout/jamesstout.github.io.git
	fetch = +refs/heads/*:refs/remotes/origin/*
	sslVerify = true
[branch "master"]
	remote = origin
	merge = refs/heads/master
[remote "deploy"]
	url = xxxxx@111.111.111.111:/usr/src/stouty.git
	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/stouty.xyz/ && git pull
[[ ! -d "/var/www/html/stouty.xyz/_site/.well-known/acme-challenge" ]] && \
    { mkdir -vp  "/var/www/html/stouty.xyz/_site/.well-known/acme-challenge"; } && \
    { chown -R james:www-data "/var/www/html/stouty.xyz/_site/.well-known/acme-challenge";}  && \
    { chown -R james:www-data "/var/www/html/stouty.xyz/_site/.well-known";}

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.