May 23, 2019

Deploying a Website with goHugo.io and Gitlab CI/CD

When I need to build a website, I typically use Hugo to generate the .html from .md. However, one thing is a bit inconvenient: deployment. If not done right, you have to do that manually (edit -> hugo -> rsync). Alternatively, and much better, you can use the Hugo-Gitlab|Hub-Netlify-toolchain I described earlier.

These day, I needed a website for a new research project of mine and didn't want to ship the site with Netlify. Instead, we discovered that you can have a Hugo-GitLab CI/CD-webserver-toolchain, which also works pretty well.

In case you have no idea about GitLab CI/CD (which was true for me), hop over to Youtube and watch one or two tutorials. I can recommend that as I wasn't too fond of the documentation and a 20 minutes video gives you a good impression as this concept is not too difficult.

A really simply solution to deploy a Hugo website with GitLab CI/CD would be the following.

Generate and simply put the following .gitlab-ci.yml file into the root folder of your website project, and commit it to GitLab:

#.gitlab-ci.yml
stages:
    - build
    - deploy

image: ubuntu:cosmic

build:
    stage: build
    script:
        - apt-get update -qq && apt-get install -y -qq hugo
        - hugo
    artifacts:
        paths:
            - public/

deploy:
    stage: deploy
    script:
        - apt-get update -qq && apt-get install -y -qq lftp
        - lftp -c "set ftp:ssl-allow no; open -u USER,PASS SERVER; mirror -Rev public/ ./demo  --ignore-time --parallel=10"

In this file, you define two stages, build and deploy, which both run inside an ubuntu 18.10 docker container (image: ubuntu:cosmic). In both stages, you need to install extra software with apt-get update -qq && apt-get install -y -qq EXTRA. In the build stage, you need hugo, in the deploy stage you need lftp, which is some kind of rsync via ftp. (N.B.: You obviously could also use rsynch here, if you host supports ssh.)

Now, when ever you push new stuff to the repo, above pipeline is executed. At first, the webpage is built by invoking hugo. As usual the generated website will be stored in the public folder.

Now things get a bit strange: You have to know that the build and deploy stages run in different environment (think “machines” or “docker container”). So you have to transport the generated website from the first environment to the second. This is done by defining an artifact, i.e., the result of the build process.

When the build stage is finished successfully (N.B.: GitLab will yield an error if one of the commands return a return value different than 0!), the deploy stage awakes. Here, the artifact - the generated website - is simply copied via ftp to the remote server.

© holger 2015 - 2020 |