Prepare the infrastructure

Important: this section describes preparing the infrastructure for self-hosted GitHub Runner

Requirements

Installing and registering GitHub Runner

Install and register GitHub Runner on its dedicated host by following the official instructions.

Setting up the build environment with Buildah

(For Ubuntu 23.10 and later) on the GitLab Runner host run:

{ echo "kernel.apparmor_restrict_unprivileged_userns = 0" && echo "kernel.apparmor_restrict_unprivileged_unconfined = 0";} | sudo tee -a /etc/sysctl.d/20-apparmor-donotrestrict.conf && sudo sysctl -p /etc/sysctl.d/20-apparmor-donotrestrict.conf

Configure the project

Requirements

  • GitHub Actions;

  • GitHub-hosted Runner or self-hosted runner.

Setting up a GitHub project

  • Create and save the access token to clean up the no longer needed images from the container registry with the following parameters:

    • Token name: werf-images-cleanup;

    • Scopes: read:packages and delete:packages.

  • Add the following variable to the project secrets:

    • Access token to clean up the no longer needed images:

      • Name: REGISTRY_CLEANUP_TOKEN;

      • Secret: <"werf-images-cleanup" access token you saved earlier>.

  • Save the kubeconfig file to access the Kubernetes cluster as a KUBECONFIG_BASE64 encrypted secret, pre-encoding it in Base64.

Configuring CI/CD of the project

This is how the repository that uses werf for build and deploy might look:

.github
app
werf.yaml
name: cleanup
on:
  schedule:
    - cron: "0 3 * * *"

jobs:
  cleanup:
    name: cleanup
    runs-on: self-hosted
    container:
      image: ghcr.io/werf/werf:2-stable-ubuntu
      options: --security-opt "seccomp:unconfined" --security-opt "apparmor:unconfined"
    steps:
      - uses: actions/checkout@v3
      - run: git fetch --prune --unshallow
      
      - run: |
          . "$(werf ci-env github --as-file)"
          werf cleanup
        env:
          WERF_KUBECONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64 }}
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          WERF_REPO_GITHUB_TOKEN: ${{ secrets.REGISTRY_CLEANUP_TOKEN }}
name: prod
on:
  push:
    branches:
      - main

jobs:
  prod:
    name: prod
    runs-on: self-hosted
    container:
      image: ghcr.io/werf/werf:2-stable-ubuntu
      # if you use fuse, then add the option --device /dev/fuse
      options: --security-opt "seccomp:unconfined" --security-opt "apparmor:unconfined"
      volumes:
        - /home/build/.werf
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      # Uncomment this block for cross-platform build
      # - name: Set up QEMU
      #   uses: docker/setup-qemu-action@v3
      #   with:
      #     platforms: linux/amd64, linux/arm64

      - run: |
          . "$(werf ci-env github --as-file)"
          werf converge
        env:
          WERF_ENV: prod
          WERF_BUILDAH_MODE: auto
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          WERF_KUBECONFIG_BASE64: ${{ secrets.KUBECONFIG_BASE64 }}
FROM node

WORKDIR /app
COPY . .
RUN npm ci

CMD ["node", "server.js"]

{
  "name": "app",
  "version": "1.0.0",
  "lockfileVersion": 2,
  "requires": true,
  "packages": {
    "": {
      "name": "app",
      "version": "1.0.0"
    }
  }
}

{
  "name": "app",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "start": "node server.js"
  }
}

const http = require('http');

const hostname = '127.0.0.1';
const port = 80;

const server = http.createServer((req, res) => {
  res.statusCode = 200;
  res.setHeader('Content-Type', 'text/plain');
  res.end('Hello World');
});

server.listen(port, hostname, () => {
  console.log(`Server running at http://${hostname}:${port}/`);
});

configVersion: 1
project: test

---
image: app
dockerfile: Dockerfile
context: ./app

Extras:

  • To use GitHub-hosted Runner, specify ubuntu-latest in runs-on;

  • If you do not use ghcr as a container registry, then enter WERF_REPO, run werf cr login, and also take into account features of your container registry when cleaning.