Skip to content

Welcome!

Just notes, without bullsh*t

How this website is made?

The website is built with MkDocs Material and runs on K3s with following deployment. The idea is to auto-rebuild the website from scratch with every commit or restart of the pod.

deployment

apiVersion: apps/v1
kind: Deployment
metadata:
  name: digital-garden
  labels:
    [...]
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: digital-garden
  template:
    metadata:
      labels:
        app.kubernetes.io/name: digital-garden
    spec:
      serviceAccountName: digital-garden
      securityContext:
        fsGroup: 65533
      containers:
      - name: website
        image: "docker.io/nginxinc/nginx-unprivileged:1.21.6" # {"$imagepolicy": "flux-system:nginx-unprivileged"}
        imagePullPolicy: IfNotPresent
        ports:
        - name: http
          containerPort: 8080
          protocol: TCP
        readinessProbe:
          httpGet:
            path: /
            port: http
        resources:
            [...]
        volumeMounts:
        - name: website
          mountPath: /usr/share/nginx/html

      initContainers:
      - name: git-sync
        image: "k8s.gcr.io/git-sync/git-sync:v3.5.0" # {"$imagepolicy": "flux-system:git-sync"}
        imagePullPolicy: IfNotPresent
        volumeMounts:
        - name: repository
          mountPath: /var/repository
        env:
        - name: GIT_SYNC_REPO
          value: https://gitlab.com/drakkai/digital-garden
        - name: GIT_SYNC_BRANCH
          value: master
        - name: GIT_SYNC_ROOT
          value: /var/repository
        - name: GIT_SYNC_DEST
          value: mkdocs
        - name: GIT_SYNC_ONE_TIME
          value: "true"
        resources:
            [...]
        securityContext:
          runAsUser: 65533
      - name: mkdocs-build
        image: "docker.io/squidfunk/mkdocs-material:8.2.13" # {"$imagepolicy": "flux-system:mkdocs-material"}
        imagePullPolicy: IfNotPresent
        command: ["/bin/sh"]
        args:
        - -c
        - >-
          pip install mkdocs-git-revision-date-plugin && mkdocs build -d /usr/share/nginx/html
        workingDir: /var/repository/mkdocs/
        volumeMounts:
        - name: repository
          mountPath: /var/repository
        - name: website
          mountPath: /usr/share/nginx/html
        resources:
            [...]
      volumes:
      - name: repository
        emptyDir: {}
      - name: website
        emptyDir: {}

service

apiVersion: v1
kind: Service
metadata:
  name: digital-garden
  labels:
    [...]
spec:
  type: ClusterIP
  ports:
    - port: 80
      protocol: TCP
      targetPort: http
      name: http
  selector:
    app.kubernetes.io/name: digital-garden

ingress

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: digital-garden
  annotations:
    cert-manager.io/cluster-issuer: letsencrypt-prod
    kubernetes.io/ingress.class: traefik
    traefik.ingress.kubernetes.io/router.middlewares: default-redirect-https@kubernetescrd
  labels:
    [...]
spec:
  rules:
    - host: "khorium.pl"
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: digital-garden
                port:
                  number: 80
  tls:
  - hosts:
    - khorium.pl
    secretName: khorium-pl-tls

Deployment .spec.template:

  • .spec.securityContext.fsGroup - gid 65533 allows to run nginx as unprivileged
  • .spec.initContainers - first init container syncs the repo, second one builds the website
  • .spec.volumes - volumes allow to share results between containers, base code is removed with init containers

Service .spec.ports - port 8080 from unprivledge nginx is exposed to port 80

Ingress .metadata.annotations - allow automatic request for a certificate from let's encrypt via cert-manager

Additionally, a simple python script checks if the pod has been restarted since the last commit in the repository with the page content - if not, it restarts it.