CI/CD

Problem

Have you ever built an app then forgotten to deploy it? Or pushed a commit, but

forgotten to rebuild conatiners based on the code you just built? These sort of problems go out the window with a CI/CD workflow.

What is CI/CD?

Continous Integration and Continous Delivery have been talked about at length, but at its core, its way to design your systems to automate the more tedious parts of your work flow. This is typically a maojor need for big corporations with large software stacks, but it can also be utilized by small homelabbers as well. For example you can have a script that runs whenever your code is checked into a git repo that triggers a chain of events that pushes your code all the way to production. In fact, that’s how this blog is created. Let’s take a closer look at this example.

Example

Step 0 - Build locally

Before we get started, there’s a few prerequisites that need to be in place. You need to be able to build your app into a container using either podman or docker, you will need a repo created in GitLab, a working Quay.io account, and lastly, access to an OpenShift cluster.

This is quite a bit, but all of this infrastructure can be reused if you have multiple containers.

Step 1 - Build to Quay

The first step does a lot of the magic. Assuming you can build your container using something like podman build -f Containerfile ., then you can get GitLab to build your container for you, as well as automatically push the container to Quay.io once it’s built.

All you need to do is add the following file into your repo and name it .gitlab-ci.yml:

variables:
  GIT_SUBMODULE_STRATEGY: recursive

stages:
  - build

podman-build:
  stage: build

  image:
    name: quay.io/podman/stable

  script:
    - podman login -u "${CI_REGISTRY_USER}" -p "${CI_REGISTRY_PASSWORD}" "${CI_REGISTRY}"
    - podman build -t "${CI_REGISTRY_IMAGE}:latest" .
    - podman push "${CI_REGISTRY_IMAGE}:latest"
    - podman build --build-arg quay_expiration=8w -t "${CI_REGISTRY_IMAGE}:$(date +%Y-%m-%d)" .
    - podman push "${CI_REGISTRY_IMAGE}:$(date +%Y-%m-%d)"

You will obviously need to fill out the CI_REGISTRY_* variables in the repo variables page, but then GitLab should automatically build and push your containers to Quay. Once the image is in Quay, it will kick off the next step.

Step 2 - Deploy to OpenShift

This part is a quite a bit easier. All you need to do is create an application in OpenShift based off of your new Quay image. This should deploy an app based on your image, but, more importantly, also redeploy your app whenever there is a new container. And since there is a new container automatically built whenever you check in code, you can gaurantee your deployed image is based on your most recent code.

It is worth noting, if you want to turn off the automatic redeploying feature of OpenShift, you can turn it off or on at will.