Deploying your blog with CI

I am using a static site generator called hexo to publish posts on my blog which converts markdown files into html, css and js files. Now you could manually copy these files to your webserver, but where is the fun in that? One of the ways you could automate this is using CI. More specifically in my case the system integrated into GitLab, which I have been using for years now. This is a great way to publish a static site blog which should be version-controlled anyways.

If you are not familiar with Gitlab CI I am going to walk you through the build file I am using.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
image: node:14

before_script:
# check if variables are set in gitlab project
- if [ -z "$SSH_PRIVATE_KEY" ]; then exit 1; fi
- if [ -z "$SSH_USER" ]; then exit 1; fi
- if [ -z "$WEB_SERVER" ]; then exit 1; fi
- apt-get --quiet update --yes
stages:
- deploy

# This file is generated by GitLab CI
Deploy:
stage: deploy
script:
- apt-get --quiet install --yes openssh-client
# Setup ssh key
- mkdir -p ~/.ssh
- echo "$SSH_PRIVATE_KEY" | tr -d '\r' > ~/.ssh/id_webserver
- chmod 700 ~/.ssh/id_webserver
- eval "$(ssh-agent -s)"
- ssh-add ~/.ssh/id_webserver
- ssh-keyscan -p 22 -H $WEB_SERVER >> ~/.ssh/known_hosts
# generate static site
- npm install hexo-cli -g
- npm install
- npm install hexo --save
- npm install hexo-generator-index --save
- npm install hexo-generator-archive --save
- npm install hexo-generator-category --save
- npm install hexo-generator-tag --save
- npm install hexo-renderer-marked@0.2 --save
- npm install hexo-renderer-stylus@0.2 --save
- npm install hexo-generator-feed@1 --save
- npm install hexo-generator-sitemap@1 --save
- npm install hexo-generator-minify --save
- hexo generate
# deploy site
- scp -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -P 22 -r public $SSH_USER@$WEB_SERVER:/tmp
- ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -p 22 $SSH_USER@$WEB_SERVER sudo deploy_sysmike_net
type: deploy
tags:
except:
- tags
only:
# Only push changes to prod server on the master branch
- master

In the before_script section the script checks for certain variables that should be defined in Gitlab and updates the docker container it runs in. The deploy stage first installs the openssh client and adds the ssh-key specified in the gitlab environment variables. Then the actual static site is being build, in this case by hexo. The resulting files are then transfered to the remote server to a temporary directory using scp. Finally a script is being run on the server to copy the website into appropriate folders and set the right permissions. The last two lines allow the script only to be run on the master branch.

For this to work you need the define three self-explanatory environmental variables in your gitlab repository called SSH_PRIVATE_KEY, SSH_USER, WEB_SERVER.

The default git branch I use for writing is called drafts and when I want to publish an article I create a merge request to the default main branch.

With this kind of setup it does not matter on which machine I write my posts as I can either commit to the repository or just use the builtin editor of GitLab if I wanted to.