Generate and deploy mynt static sites with a git post-receive hook

Friday, September 12, 2014

Mynt is a great static site generator, which renders markdown pages to a beautiful blog. This includes an index page, tags, and an RSS feed. This article explains, how to go further and automate the process of deployment from your local machine to a webserver with git hooks. All you need is a webserver with SSH access.

Installing mynt on the webserver

To generate the mynt static pages, you have to install mynt on the webserver. A good way is to create a virtual environment first with virtualenv.

On the webserver:

mkdir /var/mynt && cd /var/mynt
virtualenv env --no-site-packages
source env/bin/activate
pip install mynt
deactivate

Creating the Git repositories

Let’s start from scratch: First create a bare git repository on the server. It will contain only version control stuff and no source files. Later this will be the repository you are pushing to.

On the webserver:

mkdir /var/repo.git && cd /var/repo.git
git --bare init

In addition to that, two directories are required on the server: a directory containing the the mynt source files (not the already generated static pages) and a directory containing the generated pages. The latter gets served by a webserver like Apache or nginx. These directories remain empty for now.

mkdir -p /var/mynt/<blog.domain.com>
mkdir -p /var/www/<blog.domain.com>

The next step is to create a repository on the local machine, which contains the mynt source files. In the following commands a git repository is initialized in the mynt sources directory. Then all files are added and committed.

On the local machine:

cd <path/to/mynt_sources>
git init
git add .
git commit

Then the Git repository on the webserver has to be added as a remote source in the local repo, so you can push the mynt files to the webserver later:

git remote add production ssh://<user>@<domain.com>:<port>/var/repo.git

Creating the Git post-receive hook

Now that the repositories are set, let’s create a Git hook! Git hooks are scripts, which are executed when certain Git-actions like pushing or committing occur. You can learn more in the Git documentation. There are client-side and server-side hooks. As you want to generate the static pages on the webserver, you have to create a post-recveive hook on the server-side, which runs after the entire push-process is completed.

On the webserver:

cd /var/repo.git/hooks
nano post-receive

post-receive:

1
2
3
4
5
#!/bin/sh
git --work-tree=/var/mynt/<blog.domain.com> --git-dir=/var/repo.git checkout -f
cd /var/mynt
echo ">> Starting mynt process:"
env/bin/mynt gen /var/www/<blog.domain.com>  -f

This post-receive hook script does a checkout to the working tree (the directory for the mynt source files we created earlier) and generates the static sites into the production webserver directory.

Testing the hook

To see the post-receive hook in action, just create some articles in your mynt project on your local machine. Then you can add, commit and push your changes to the server.

On the local machine:

cd <path/to/mynt_sources>
git add .
git commit
git push production master

If all went well, you should see something like the following in the terminal:

Delta compression using up to 4 threads.
Compressing objects: 100% (4/4), done.
Writing objects: 100% (4/4), 677 bytes | 0 bytes/s, done.
Total 4 (delta 2), reused 0 (delta 0)
remote: >> Starting mynt process:
remote: >> Parsing
remote: >> Rendering
remote: >> Generating
remote: Completed in 0.246s

The remote messages indicate, that the post-received hook got successfully called by Git. If you are running a configured Apache or nginx webserver, the generated pages should be live at http://<blog.domain.com>. If you want, you can extend the hook and add less compilation or minifying your css files for example. Last but not least thanks to @derroman, who pointed me to git hooks.