new blog

setting up docker

  • create new centos8 droplet
  • log in (as root) and update dnf update systemctl reboot
  • set up docker repo dnf config-manager --add-repo
  • install docker (have to use version 18.09.1 due to version of available dnf install docker-ce-18.09.1 docker-ce-cli-18.09.1 systemctl enable docker systemctl start docker

create and register gitlab runner

  • install gitlab-runner on server

- register (shell executor)

  • build and run gitlab-runner image - we need two, one to build and one to deploy (use tags) docker run -d --name gitlab-runner1 --restart always -v /var/run/docker.sock:/var/run/docker.sock -v /srv/gitlab-runner/config:/etc/gitlab-runner:Z gitlab/gitlab-runner:latest docker exec -ti gitlab-runner1 gitlab-runner register need to add --privileged to runner2
  • when prompted enter
    • coordinator URL:
    • token: found under ...
    • description: anything you want
    • tags: build/deploy
    • executor: 'docker' for both
    • base image: '' for 1, 'docker:latest' for 2

configure gitlab ci

- build and deploy using simple docker commands

  • copy the following into a file called 'gitlab-ci.yml' in the project repo build: stage: build image: name: entrypoint: [""] script: - echo "{\"auths\":{\"$CI_REGISTRY\":{\"username\":\"$CI_REGISTRY_USER\",\"password\":\"$CI_REGISTRY_PASSWORD\"}}}" > /kaniko/.docker/config.json - /kaniko/executor --context $CI_PROJECT_DIR --dockerfile $CI_PROJECT_DIR/Dockerfile --destination $CI_REGISTRY_IMAGE:$CI_COMMIT_TAG only: - tags
  • the env variables need to be added into the gitlab project ci/cd settings

setting up static site generator

  • requires hugo to be installed
  • start a new site, the --force option is because we already have files in the project repo hugo new site . --force git submodule add themes/futuremyth echo 'theme = "futuremyth"' >> config.toml hugo new posts/
  • run server in development mode hugo server -D
  • change 'title' in 'config.toml'
  • build static pages hugo -D
  • to deploy drafts update head to say draft: false

setting up kubernetes (minikube - single node)

  • create new centos8 droplet
  • log in (as root) and run dnf update
  • set up docker repo dnf install device-mapper-persistent-data lvm2 dnf config-manager --add-repo
  • install docker (have to use version 18.09.1 due to version of available dnf install docker-ce-18.09.1 docker-ce-cli-18.09.1 systemctl enable docker systemctl start docker
  • set up kubernetes repo cat > /etc/yum.repos.d/kubernetes.repo << EOF [kubernetes] name=Kubernetes baseurl= enabled=1 gpgcheck=1 repo_gpgcheck=1 gpgkey= EOF
  • install kubectl dnf install kubectl

attempt 2

  • create new empty project on gitlab
  • on local machine create new hugo site hugo new site hugo_blog cd hugo_blog git init git remote add origin<username>/<project_name>.git
  • add a theme to your site git submodule add themes/ananke echo 'theme = "ananke"' >> config.toml
  • change the resource cache so gitlab ci/cd doesn't break cat >> config.toml <<EOF [caches.images] dir = ":cacheDir/_gen" [caches.assets] dir = ":cacheDir/_gen" EOF
  • create your first new post hugo new posts/
  • to view your site locally run the development server with the -D flag hugo server -D
  • to publish your post change the 'draft' header to 'false'
  • create a file called '.gitlab-ci.yml' with the following

      stage: build
      image: docker:latest
          - docker:dind
          - docker build --pull -t $CI_REGISTRY_IMAGE:latest .
          - docker push $CI_REGISTRY_IMAGE:latest
      stage: deploy
      image: docker:latest
          - docker:dind
          - deploy
          - docker pull $CI_REGISTRY_IMAGE
          - docker run -d --name "blog_test_2" -p 80:1313 -v $(pwd):/site $CI_REGISTRY_IMAGE
  • create a Dockerfile with the following

    FROM jojomi/hugo
    COPY . /site
    WORKDIR /site
    # enable hugo watch to keep container alive
    RUN hugo
    # saw an issue with the resource directory permissions
    RUN chown -R docker: /site/resources/
  • in you gitlab account settings under 'access tokens' add a new personal access token with 'api' scope enabled
  • in your gitlab project ci/cd settings under variables add the following | key | value | | --- | --- | | CI_REGISTRY | | | CI_REGISTRY_IMAGE | | | CI_REGISTRY_USER | | | CI_REGISTRY_PASSWORD | | | CONTAINER_NAME | |
  • mark the CI_REGISTRY_PASSWORD variable as 'Protected'
  • create a gitlab runner on your server. you must have docker installed and working for the runner to work
    • use the registration token found under the runners section in the ci/cd settings
    • apply the tag 'deploy'
    • select the 'shell' executor
  • make sure you have docker running on your server and add the gitlab-runner user to the docker group sudo usermod -aG docker gitlab-runner
  • you can now commit and push your repo to trigger the pipeline

    git add .
    git commit -m "initial commit"
    git push -u origin master
  • update submodule

    git submodule update --remote

final attempt

Getting setup

Generate a new Hugo site, for this example I will be calling my 'pyratelog'

hugo new site pyratelog

Navigate into the new directory and initialise it as a git repository

cd pyratelog
git init

Create a new project in Gitlab


Add your new Gitlab project as a remote repo to your Hugo site and make an inital commit if you want

git remote add origin
git add .
git commit -m "initial commit"
git push -u origin master

Your Gitlab project should now be populated with a config.toml file and the 'archetypes' directory.


I won't keep mentioning when to commit changes to git as we all work differently. We will come to it a bit later when we configure our CI/CD pipeline.

Configure Hugo

Let us add a theme to our Hugo project, in this case I will use my own 'futuremyth' theme

git submodule add themes/futuremyth
echo 'theme = "futuremyth"' >> config.toml

I have added in the 'pagination' variable to change the default of 10 items to 5, and also set a static directory for use with images in my log entries

cat >> config.toml << EOF
pagination = "5"
staticDir = ["static"]

I found it is a good idea to change some of the cache directories. There was an issue I had in my Gitlab CI/CD pipeline with root permissions being set on a directory, causing the pipeline to fail

cat >> config.toml << EOF
dir = ":cacheDir/_gen"
dir = ":cacheDir/_gen"

You should also edit the 'baseURL' and 'title' variables in your config.toml

You can start Hugo on your local machine in development mode using

hugo server -D

If you navigate to http://localhost:1313 you should see a fairly empty page. To add new content you run

hugo new posts/
You change the path to whatever you want, and it will be created under the 'content' directory.

If you left your deployment server running you should see that in your browser the site should automatically updates. You first entry should show the title of your post and the date. You can open the markdown file in your favourite editor and start writing below the second set of hyphens (---). Everything between the hyphens is metadata for the page. You can add more if you like, I add a 'summary', 'categories', and 'tags' in the following way

summary: How I set up a Hugo website and deployed with Gitlab's CI/CD pipeline
categories: [tech]
tags: [website, hugo, devops, gitlab, automation]

We can now build our site by running


This won't include our first post because we have left the draft variable as true. When you are ready to publish change it to false and build the site again. You can build with drafts included by running

hugo -D


There a many ways you can host a website, and many ways you can use Gitlab's CI/CD pipeline to automate the process. The method I have opted for is to run my Hugo site in a docker container on a DigitalOcean droplet. I have chosen not to use docker-compose to include the Nginx reverse proxy as I host other things behind Nginx and don't want it to be controlled by my Hugo container