GitLab CI/CD and building containers

date:

tags: Hugo git markdown blog containers docker

categories: Containers

GitLab CI/CD is a feature of the GitLab platform that is used in software development for Continuous Integration, Delivery, and Deployment of software. The idea is that software source code will grow and evolve over time but you do not want to have to manually compile your code each time a change is made. This is especially true when you develop software as a team and multiple changes might be made in a single day.

Building a container to host hugo sites

Building container images is a good use case for a continuous deployment pipeline. If you are not familiar with docker or containers, check out a previous post.

Instead of running a command like docker build $image:tag every time you make a change to your Dockerfile, GitLab CI can detect changes to the source code file and trigger scripts to generate the container image and deploy it to a container registry.

Create a git repository with two files:

  • Dockerfile
  • .gitlab-ci.yml

In the example, the primary protected branch is called “main”.

In a previous post, I demonstrated how this site is hosted on the internet using markdown templates and hugo. Check that out for more details and how to set up a new git repository.

It is also possible to build a container image with static files to host a site with a simple webserver such as nginx.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Build static site
ARG HUGOVERSION=0.83.1

FROM klakegg/hugo:${HUGOVERSION}-ext-onbuild AS hugo

# Build stateless image with static site files
FROM nginx:alpine

WORKDIR /usr/share/nginx/html/

COPY --from=hugo /target /usr/share/nginx/html

Building from this container file will use the image klakegg/hugo from the Docker Hub to render the site with Hugo. Once the site files have been generated, the final image is based on nginx:alpine and simply adds the site files to the nginx web server.

This image can be hosted on any container platform. The final image should be very small in size as the hugo container is only used during the build process.

By default, this image will start a web server on port 80 using the content copied to usr/share/nginx/html

You can run the image on port 80 of the host or use a proxy server to do things like SSL/TLS encryption, or copy the image to a container platform such as kubernetes.

GitLab CI config

When changes are made to protected branches, the GitLab CI pipeline will build the container image based on the latest changes to the container file template.

This pipeline uses a tool called kaniko to build container images based on a Dockerfile all within a container (or container platform such as kubernetes).

Update the .gitlab-ci.yml file to include the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
---
stages:
  - build
buildTesting:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  script:
    - mkdir -p /kaniko/.docker
    - 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_SHA      
  only:
    - testing
buildProduction:
  stage: build
  image:
    name: gcr.io/kaniko-project/executor:debug
    entrypoint: [""]
  variables:
    GIT_SUBMODULE_STRATEGY: recursive
  script:
    - mkdir -p /kaniko/.docker
    - 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:latest      
  only:
    - main

This will define a build stage. There is one stage defined for building the image. Any changes made to origin/testing branch will generate a container image tagged with a CI variable that is the SHA hash value of associated git commit.

The second stage defined is the primary stage that will build from the main branch and tag the container image with the “latest” tag.

Pulling the new image

The image is now on the GitLab registry and can be pulled from registry.gitlab.com.

For example to pull the image, add your GitLab username and repository name and image tag like this:

1
docker pull registry.gitlab.com/acaylor/hugobuild:latest

The GitLab CI file uses variables recognized by the CI system so this can be used in any number of container build repos with no modification.

comments powered by Disqus