Introduction

I wanted to migrate my blog from Wordpress to statically generated HTML blog. But on the other hand I wanted to keep history of all my changes in blog. Finally I decided to go with Git repo for files and Hugo as file generator.

To automate generation and deployment of site I’m using GitLab and its CI.

Overview

Here is how looks like my setup for blog:

  • Files are hosted on personal VM
  • Blog content is hosted in a private repo at VM with GitLab
  • DNS for my zone is hosted in Cloudflare
  • Theme for site is included as git submodule into repo
  • After editing something or adding content I commit and push changes to repository
  • When content is pushed to GitLab instance CI runs pipeline to build site
  • GitLab CI contains two steps:
    • Building and generation site artifact
    • Pushing site artifact to web server

As example I used this article.

Detailed description with examples

GitLab CI

I’m using next pipeline to create site:

stages:
  - build
  - deploy

build-site:
  image: docker-hugo
  stage: build
  script:
    - git submodule update --init --recursive
    - hugo
    - tar -czf site.tar.gz public
  artifacts:
    paths:
      - site.tar.gz
  cache:
    paths:
      - public
  only:
  - master

deploy:
  stage: deploy
  image: docker-rsync-ssh
  script:
  - echo "${SSH_PRIVATE_KEY}" > id_rsa
  - ls -la ./
  - tar xf site.tar.gz
  - chmod 600 id_rsa
  - rsync -hrvz --delete --exclude=_ -e 'ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i id_rsa' public/ "${SSH_USER_HOST_LOCATION}"
  only:
  - master

The only problem I faced in setup from article was theme added as git submodule. Issue is caused by GitLab CI: it doesn’t clone submodules from external git repositories. That’s why I added next line to pipeline:

    - git submodule update --init --recursive

SSH_PRIVATE_KEY and SSH_USER_HOST_LOCATION should be defined in CI/CD settings for git repository in GitLab web interface.

Docker

Dockerfile for build container

FROM alpine:latest

RUN apk add --update \
    git \
    python \
    py-pip \
    icu \
    icu-libs \
    icu-dev \
  && pip install pygments \
  && rm -rf /var/cache/apk/*

ENV HUGO_VERSION=0.37.1
ENV HUGO_BINARY=hugo
ENV HUGO_RESOURCE=hugo_${HUGO_VERSION}_Linux-64bit
ENV LANG=ru_RU.UTF-8
ENV LC_ALL=ru_RU.UTF-8
ENV LANGUAGE=ru_RU.UTF-8

ADD https://github.com/gohugoio/hugo/releases/download/v${HUGO_VERSION}/${HUGO_RESOURCE}.tar.gz /tmp

RUN  tar -xvzf /tmp/${HUGO_RESOURCE}.tar.gz -C /tmp/ \
    && mv /tmp/${HUGO_BINARY} /usr/bin/hugo && rm -rf /tmp/hugo*

Dockerfile for deploy container

FROM alpine:latest

RUN apk --update add \
  rsync \
  openssh \
  && \
  rm -rf /var/cache/apk/*