Mid 2018 I switched my blog from Wordpress to Hugo . Main reason was performance and that I can use Asciidoctor to write the posts.
What happened the last 18 months? I stayed with the theme I selected 2018, but I tweaked it a little bit. So I added lunr
to implement searching, changed all scripts and fonts from CDN to local (privacy and tracking), updated Bootstrap 3 to 4.
Working with Bootstrap was quite fun, I haven’t done a lot of HTML
or CSS
the last years, but the grid and css classes from Bootstrap are working without checking each change on all browsers and are responsive.
Daily journal
After reading The Unicorn Project I started writing a daily journal with things I learned or figured out during the day. I tried this several times the last years, but never was happy with the result. This time I just use the same setup as my blog (Hugo, Theme and Asciidoctor), but deploy it to a local Docker container, which is started with podman
.
Gitlab CI/CD
Hugo generates static html pages from Asciidoctor or Markdown sources. The first months I just ran the hugo binary on my local machine and did a rsync
of the generated html to my blog and the container.
Updating Hugo, or reinstall my Notebook sometimes delayed a blog post. So I decided to automated the process through Gitlab CI/CD.
.gitmodules
I added the theme (which is stored as a seperate git repository) as a submodule (git add submodule …
) to the blog content. .gitmodules
can handle complete repository URL, or relative ones. The relative URL are easier to checkout in the pipeline, so I changed the file to
.gitmodules
[submodule "themes/stoeps-theme"]
path: themes/stoeps-theme
url: ../stoeps-theme.git
- Edit Url and replace with the relative path (I have the theme in the same git group)
Creating .gitlab-ci.yml
variables:
GIT_SUBMODULE_STRATEGY: recursive
stages:
- build
- deploy
build:
stage: build
image: "node:alpine"
before_script:
- 'which curl || ( apk update && apk add curl)'
- 'which gem || (apk add ruby)'
- curl -L https://github.com/gohugoio/hugo/releases/download/v0.61.0/hugo_0.61.0_Linux-64bit.tar.gz | tar -xz && mv hugo /usr/local/bin/hugo
- npm install
- gem install asciidoctor
script:
- npx gulp build
only:
refs:
- master
variables:
- $BUILDHTML
changes:
- content/**/*
artifacts:
paths:
- docs
expire_in: 2 hours
deploy:
image: "debian:buster"
stage: deploy
before_script:
- 'which ssh-agent || ( apt-get update -y && apt-get install openssh-client -y )'
- 'which rsync || ( apt-get update -y && apt-get install rsync -y )'
- eval $(ssh-agent -s)
- echo "$SSH_PRIVATE_KEY" | base64 --decode | tr -d '\r' | ssh-add - > /dev/null
- mkdir -p ~/.ssh
- chmod 700 ~/.ssh
- ssh-keyscan -t rsa home26617100.1and1-data.host >> ~/.ssh/known_hosts
script:
- rsync -az docs/ p7594620@home26617100.1and1-data.host:/kunden/homepages/13/d26617100/htdocs/stoeps.de --delete
only:
refs:
- master
variables:
- $DEPLOYBLOG
changes:
- content/**/*
Clone submodules with the main repository
Two stages, one builds html, one deploys the code
Check if curl is included in the container, if not install it
Run build with Gulp (see below)
Stage runs only for master-Branch, if variable
BUILDHTML
is set and changed files are in thecontent
-treeKeep directory
docs
as artifacts for the next stageI created a seperate SSH key just for the synchronisation, it is stored as a variable in the Gitlab project
Store SSH-Key as variable
Create Key
ssh-keygen
base64 encode the key and copy to clipboard
base64 -i ~/.ssh/id_gitlab |tr -d '\n' | xclip
Syntax is equal to Linux cron
, so the setting of this image will run the pipeline at 23:55 UTC every day. Other option could be hourly at 5 minutes past the full hour: 5 * * * *
I added a scheduler which runs hourly and sets the variables BUILDHTML
and DEPLYBLOG
, so I can check-in code to gitlab multiple times and the posts will only be build on a scheduled basis.
Just set the variables to true
.
Gulp
The article Continuously Deploy a Hugo Site with GitLab CI added Gulp to minify the built HTML. Cool idea and saves me some megabytes. I added css-minify and build the hugo page with:
npx gulp build
gulpfile.js
var gulp: require("gulp");
var htmlmin: require("gulp-htmlmin");
var cssmin: require("gulp-cssmin");
var shell: require("gulp-shell");
gulp.task("hugo-build", shell.task(["hugo"]));
gulp.task("minify-html", () => {
return gulp.src(["docs/**/*.html"])
.pipe(htmlmin({
collapseWhitespace: true,
minifyCSS: true,
minifyJS: true,
removeComments: true,
useShortDoctype: true,
}))
.pipe(gulp.dest("./docs"));
});
gulp.task('minify-css', () => {
return gulp.src(["docs/**/*.css"])
.pipe(cssmin())
.pipe(gulp.dest("./docs"));
});
gulp.task("build", gulp.series("hugo-build", "minify-html", "minify-css"));