helm-charts

👋 Welcome to my Helm Charts repository. This repo contains Helm charts that I have developed to run applications in my cluster.


Installation

Helm must be installed to use the charts in this repository.

The Helm repository can be installed as follows:

helm repo add thewolfnl https://thewolfnl.github.io/helm-charts

You can then run helm search repo thewolfnl to search the charts.


🔎 Support

If you like this project, please consider supporting my work through my GitHub sponsorship page.


🔏 License

See LICENSE

Common library

Note

The Common library chart is not meant to be installed directly, application charts use the Common library as a dependency. See the app template for an example how to deploy it.

Background

In Helm 3, their team introduced the concept of a Library chart.

A library chart is a type of Helm chart that defines chart primitives or definitions which can be shared by Helm templates in other charts. This allows users to share snippets of code that can be re-used across charts, avoiding repetition and keeping charts DRY.

The common library was created because I saw many charts requiring only a few select configuration options in their Helm charts.

Note

Take one of the many applications like sonarr or nzbget. Each of these charts only require setting service, port, persistence, ingress and image since state and app configuration is handled by the application itself.

In order to stay somewhat DRY (Don't Repeat Yourself) and keeping with Helm 3 usage for a Library chart, I saw this pattern and decided it was worth it to create a library. This means each one of these app charts has a dependency on what we call the common library.

Source code

The source code for the common library chart can be found here.

Common library add-ons

The common library chart supplies a few add-ons which are meant to simplify some features you might be looking for. These are sidecars that run in the same pod as your application you configured it with.

Code Server

The code-server add-on can be used to access and modify persistent volume data in your application. This can be useful when you need to edit the persistent volume data, for example with Home Assistant.

Example values

Below is a snippet from a values.yaml using the add-on. More configuration options can be found in our common chart documentation.

Note

This example will mount /config into the code-server sidecar.

addons:
  codeserver:
    enabled: true
    image:
      repository: codercom/code-server
      tag: 3.9.0
    workingDir: "/config"
    args:
    - --auth
    - "none"
    - --user-data-dir
    - "/config/.vscode"
    - --extensions-dir
    - "/config/.vscode"
    ingress:
      enabled: true
      annotations:
        kubernetes.io/ingress.class: "nginx"
      hosts:
      - host: app-config.domain.tld
        paths:
        - path: /
          pathType: Prefix
      tls:
      - hosts:
        - app-config.domain.tld
    volumeMounts:
    - name: config
      mountPath: /config

Common library Storage

This page describes the different ways you can configure and attach storage to charts using the common library.

Permissions

Charts do not modify file or folder permissions on volumes out of the box.

This means that you will have to make sure that your storage can be written to by the application.

Storage types

Here you can find information on the different types of storage available in the common library chart.

Persistent Volume Claim

This is probably the most common storage type, therefore it is also the default when no type is specified.

It can be attached in two ways.

Dynamically provisioned

Charts can be configured to create the required persistentVolumeClaim manifests on the fly.

FieldMandatoryDocs / Description
enabledYes
typeYes
accessModeYeslink
sizeYeslink
mountPathNoWhere to mount the volume in the main container. Defaults to /<name_of_the_volume>.
readOnlyNoSpecify if the volume should be mounted read-only.
nameOverrideNoOverride the name suffix that is used for this volume.
storageClassNoStorage class to use for this volume.
retainNoSet to true to retain the PVC upon helm uninstall.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: pvc
    accessMode: ReadWriteOnce
    size: 1Gi

This will create a 1Gi RWO PVC named RELEASE-NAME-config with the default storageClass, which will mount to /config.

Existing claim

Charts can be configured to attach to a pre-existing persistentVolumeClaim.

FieldMandatoryDocs / Description
enabledYes
typeYes
existingClaimYesName of the existing PVC
mountPathNoWhere to mount the volume in the main container. Defaults to /<name_of_the_volume>.
subPathNoSpecifies a sub-path inside the referenced volume instead of its root.
readOnlyNoSpecify if the volume should be mounted read-only.
nameOverrideNoOverride the name suffix that is used for this volume.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: pvc
    existingClaim: myAppData

This will mount an existing PVC named myAppData to /config.

Empty Dir

Sometimes you need to share some data between containers, or need some scratch space. That is where an emptyDir can come in.

See the Kubernetes docs for more information.

FieldMandatoryDocs / Description
enabledYes
typeYes
mediumNoSet this to Memory to mount a tmpfs (RAM-backed filesystem) instead of the storage medium that backs the node.
sizeLimitNoIf the SizeMemoryBackedVolumes feature gate is enabled, you can specify a size for memory backed volumes.
mountPathNoWhere to mount the volume in the main container. Defaults to /<name_of_the_volume>.
nameOverrideNoOverride the name suffix that is used for this volume.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: emptyDir

This will create an ephemeral emptyDir volume and mount it to /config.

Host path

In order to mount a path from the node where the Pod is running you can use a hostPath type persistence item.

This can also be used to mount an attached USB device to a Pod. Note that this will most likely also require setting an elevated securityContext.

See the Kubernetes docs for more information.

FieldMandatoryDocs / Description
enabledYes
typeYes
hostPathYesWhich path on the host should be mounted.
hostPathTypeNoSpecifying a hostPathType adds a check before trying to mount the path. See Kubernetes documentation for options.
mountPathNoWhere to mount the volume in the main container. Defaults to the value of hostPath.
readOnlyNoSpecify if the volume should be mounted read-only.
nameOverrideNoOverride the name suffix that is used for this volume.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: hostPath
    hostPath: /dev

This will mount the /dev folder from the underlying host to /dev in the container.

ConfigMap

In order to mount a configMap to a mount point within the Pod you can use the configMap type persistence item.

FieldMandatoryDocs / Description
enabledYes
typeYes
nameYesWhich configMap should be mounted. Supports Helm templating.
defaultModeNoThe default file access permission bit.
itemsNoSpecify item-specific configuration. Will be passed 1:1 to the volumeSpec.
readOnlyNoExplicitly specify if the volume should be mounted read-only. Even if not specified, the configMap will be read-only.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: configMap
    name: mySettings

This will mount the contents of the pre-existing mySettings configMap to /config.

Secret

In order to mount a Secret to a mount point within the Pod you can use the secret type persistence item.

FieldMandatoryDocs / Description
enabledYes
typeYes
nameYesWhich Secret should be mounted. Supports Helm templating.
defaultModeNoThe default file access permission bit.
itemsNoSpecify item-specific configuration. Will be passed 1:1 to the volumeSpec.
readOnlyNoExplicitly specify if the volume should be mounted read-only. Even if not specified, the Secret will be read-only.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: secret
    name: mySecret

This will mount the contents of the pre-existing mySecret Secret to /config.

NFS Share

To mount an NFS share to your Pod you can either pre-create a persistentVolumeClaim referring to it, or you can specify an inline NFS volume:

Note

Mounting an NFS share this way does not allow for specifying mount options. If you require these, you must create a PVC to mount the share.

FieldMandatoryDocs / Description
enabledYes
typeYes
serverYesHost name or IP address of the NFS server.
pathYesThe path on the server to mount.
readOnlyNoExplicitly specify if the volume should be mounted read-only. Even if not specified, the Secret will be read-only.

Minimal configuration:

persistence:
  config:
    enabled: true
    type: nfs
    server: 10.10.0.8
    path: /tank/nas/library

This will mount the NFS share /tank/nas/library on server 10.10.0.8 to /config.

Custom

When you wish to specify a custom volume, you can use the custom type. This can be used for example to mount configMap or Secret objects.

See the Kubernetes docs for more information.

FieldMandatoryDocs / Description
enabledYes
typeYes
volumeSpecYesDefine the raw Volume spec here.
mountPathNoWhere to mount the volume in the main container. Defaults to the value of hostPath.
readOnlyNoSpecify if the volume should be mounted read-only.
nameOverrideNoOverride the name suffix that is used for this volume.

How to...

Here you can find information on how to accomplish specific scenario's.

Multiple subPaths for 1 volume

It is possible to mount multiple subPaths from the same volume to the main container. This can be achieved by specifying subPath with a list instead of a string.

Note

It is not possible to define mountPath at the top level when using this feature

Examples:

persistence:
  config:
    enabled: true
    type: custom
    volumeSpec:
      configMap:
        name: myData
    subPath:
      - path: myFirstScript.sh
        mountPath: /data/myFirstScript.sh
      - path: myCertificate.pem
        mountPath: /certs/myCertificate.pem
        readOnly: true
persistence:
  config:
    enabled: true
    type: pvc
    existingClaim: myAppData
    subPath:
      - path: .
        mountPath: /my_media
      - path: Series
        mountPath: /series
      - path: Downloads
        mountPath: /downloads

Helm templates

Some fields in the common library values.yaml allow the use of Helm templates for their values. This is often indicated by a remark similar to Helm template enabled in the field description.

This feature allows you to set the value of that key to the output of the given Helm template.

Example:

Given the following values.yaml

image:
  repository: k8s.gcr.io/git-sync/git-sync
  tag: v3.6.2

additionalContainers:
  subcleaner:
    name: subcleaner
    image: |-
      {{ printf "%s:%s" .Values.image.repository (default .Chart.AppVersion .Values.image.tag) | quote }}
    args:
      - --repo=https://github.com/KBlixt/subcleaner.git
      - --branch=master
      - --depth=1
      - --root=/add-ons/subcleaner

This would render as follows:

image:
  repository: k8s.gcr.io/git-sync/git-sync
  tag: v3.6.2

additionalContainers:
  subcleaner:
    name: subcleaner
    image: k8s.gcr.io/git-sync/git-sync:v3.6.2
    args:
      - --repo=https://github.com/KBlixt/subcleaner.git
      - --branch=master
      - --depth=1
      - --root=/add-ons/subcleaner

App Template

Background

Since Helm library charts cannot be installed directly I have created a companion chart for the common library.

Usage

In order to use this template chart, you would deploy it as you would any other Helm chart. By setting the desired values, the common library chart will render the desired resources.

Be sure to check out the common library docs and its values.yaml for more information about the available configuration options.

Examples

This is an example values.yaml file that would deploy the vaultwarden application. For more deployment examples, check out the examples folder.

image:
  # -- image repository
  repository: vaultwarden/server
  # -- image pull policy
  pullPolicy: IfNotPresent
  # -- image tag
  # this example is not automatically updated, so be sure to use the latest image
  tag: 1.25.2

strategy:
  type: Recreate

# -- environment variables.
# See [image docs](https://github.com/dani-garcia/vaultwarden/blob/main/.env.template) for more details.
env:
  # -- Config dir
  DATA_FOLDER: "config"

# -- Configures service settings for the chart.
service:
  main:
    ports:
      http:
        port: 80
      websocket:
        enabled: true
        port: 3012

ingress:
  # -- Enable and configure ingress settings for the chart under this key.
  main:
    enabled: false
    hosts:
      - host: chart-example.local
        paths:
          - path: /
            pathType: Prefix
            service:
              port: http
          - path: /notifications/hub/negotiate
            pathType: Prefix
            service:
              port: http
          - path: /notifications/hub
            pathType: Prefix
            service:
              port: websocket

# -- Configure persistence settings for the chart under this key.
persistence:
  config:
    enabled: true
    type: pvc
    accessMode: ReadWriteOnce
    size: 1Gi
    mountPath: /config

Source code

The source code for the app template chart can be found here.