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 availablednf 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 repohugo 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 availablednf 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
flaghugo 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
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.
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