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 https://download.docker.com/linux/centos/docker-ce.repo
    
  • install docker (have to use version 18.09.1 due to version of containerd.io available
      dnf install docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io
      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: https://gitlab.com
    • token: found under …
    • description: anything you want
    • tags: build/deploy
    • executor: 'docker' for both
    • base image: 'gcr.io/kaniko-project/executor:debug' 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: gcr.io/kaniko-project/executor:debug
          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 https://gitlab.com/pyratebeard/hugo-futuremyth.git themes/futuremyth
      echo 'theme = "futuremyth"' >> config.toml
      hugo new posts/my-first-post.md
    
  • 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 https://download.docker.com/linux/centos/docker-ce.repo
    
  • install docker (have to use version 18.09.1 due to version of containerd.io available
      dnf install docker-ce-18.09.1 docker-ce-cli-18.09.1 containerd.io
      systemctl enable docker
      systemctl start docker
    
  • set up kubernetes repo
      cat > /etc/yum.repos.d/kubernetes.repo << EOF
      [kubernetes]
      name=Kubernetes
      baseurl=https://packages.cloud.google.com/yum/repos/kubernetes-el7-x86_64
      enabled=1
      gpgcheck=1
      repo_gpgcheck=1
      gpgkey=https://packages.cloud.google.com/yum/doc/yum-key.gpg https://packages.cloud.google.com/yum/doc/rpm-package-key.gpg
      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 git@gitlab.com:<username>/<project_name>.git
    
  • add a theme to your site
      git submodule add https://github.com/budparr/gohugo-theme-ananke.git 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/initial_post.md
    
  • 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
      build:
        stage: build
        image: docker:latest
        services:
            - docker:dind
        before_script:
            - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
        script:
            - docker build --pull -t $CI_REGISTRY_IMAGE:latest .
            - docker push $CI_REGISTRY_IMAGE:latest
    	
      deploy:
        stage: deploy
        image: docker:latest
        services:
            - docker:dind
        tags:
            - deploy
        before_script:
            - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
        script:
            - 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
      ENV HUGO_WATCH=true
    	
      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 | registry.gitlab.com | | CI_REGISTRY_IMAGE | registry.gitlab.com// | | 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

new_gitlab_project

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@gitlab.com:pyratebeard/pyratelog.git
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.

inital_commit

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 https://gitlab.com/pyratebeard/hugo-futuremyth.git 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"]
EOF

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
[caches.images]
dir = ":cacheDir/_gen"
[caches.assets]
dir = ":cacheDir/_gen"
EOF

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/hello_world.md
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

hugo

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

AutoDevOps

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