Add Helm chart
pipeline / build-and-push-images (push) Successful in 1m46s
pipeline / lint-and-publish-chart (push) Failing after 14s

This commit is contained in:
2026-05-11 23:02:28 +02:00
parent 259ad574d1
commit 3c057fcc0a
11 changed files with 446 additions and 0 deletions
+39
View File
@@ -29,3 +29,42 @@ jobs:
tags: |
git.vhaudiquet.fr/vhaudiquet/vhaudiquet.fr:latest
git.vhaudiquet.fr/vhaudiquet/vhaudiquet.fr:${{ github.sha }}
lint-and-publish-chart:
runs-on: ubuntu-latest
needs: build-and-push-images
steps:
- name: Checkout repository
uses: https://gitea.com/actions/checkout@v4
with:
fetch-depth: 0
- name: Install Helm
uses: azure/setup-helm@v5
- name: Update Chart version and appVersion
run: |
# Get base chart version from Chart.yaml
BASE_VERSION=$(grep '^version:' chart/Chart.yaml | awk '{print $2}')
# Use timestamp for ordered versions (e.g., 0.1.0-20240511.130400)
TIMESTAMP=$(date -u +"%Y%m%d.%H%M%S")
CHART_VERSION="${BASE_VERSION}-${TIMESTAMP}"
# Update both version and appVersion
sed -i "s/^version:.*/version: \"${CHART_VERSION}\"/" chart/Chart.yaml
sed -i "s/^appVersion:.*/appVersion: \"${{ github.sha }}\"/" chart/Chart.yaml
echo "chart_version=${CHART_VERSION}" >> $GITHUB_ENV
- name: Lint Helm chart
run: helm lint chart/
- name: Package Helm chart
run: helm package chart/
- name: Push Helm chart to Gitea registry
run: |
curl --user ${{ github.actor }}:${{ secrets.PACKAGES_TOKEN }} \
-X POST \
--upload-file vhaudiquet-fr-*.tgz \
https://git.vhaudiquet.fr/api/packages/${{ github.actor }}/helm/api/charts
+28
View File
@@ -0,0 +1,28 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
# Plans directory
plans/
+14
View File
@@ -0,0 +1,14 @@
apiVersion: v2
name: vhaudiquet-fr
description: A Helm chart for deploying vhaudiquet.fr personal website
# A chart can be either an 'application' or a 'library' chart.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates.
version: 0.1.0
# The appVersion is automatically updated by CI to the git commit SHA.
# Do not manually update this value - it will be overwritten during the build process.
appVersion: ""
+29
View File
@@ -0,0 +1,29 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "vhaudiquet-fr.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "vhaudiquet-fr.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "vhaudiquet-fr.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "vhaudiquet-fr.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}
{{- if .Values.nfs.enabled }}
2. NFS Storage Configuration:
The chart has created an NFS-based PersistentVolume and PersistentVolumeClaim.
Make sure your NFS server ({{ .Values.nfs.server }}) is accessible from the cluster
and the export path ({{ .Values.nfs.path }}) exists.
{{- end }}
+62
View File
@@ -0,0 +1,62 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "vhaudiquet-fr.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Create a default fully qualified app name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
If release name contains chart name it will be used as a full name.
*/}}
{{- define "vhaudiquet-fr.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.nameOverride }}
{{- if contains $name .Release.Name }}
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}
{{- end }}
{{/*
Create chart name and version as used by the chart label.
*/}}
{{- define "vhaudiquet-fr.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "vhaudiquet-fr.labels" -}}
helm.sh/chart: {{ include "vhaudiquet-fr.chart" . }}
{{ include "vhaudiquet-fr.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "vhaudiquet-fr.selectorLabels" -}}
app.kubernetes.io/name: {{ include "vhaudiquet-fr.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "vhaudiquet-fr.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "vhaudiquet-fr.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
+79
View File
@@ -0,0 +1,79 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "vhaudiquet-fr.fullname" . }}
labels:
{{- include "vhaudiquet-fr.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
{{- include "vhaudiquet-fr.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "vhaudiquet-fr.selectorLabels" . | nindent 8 }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "vhaudiquet-fr.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
{{- range $key, $value := .Values.env }}
- name: {{ $key }}
value: {{ $value | quote }}
{{- end }}
ports:
- name: http
containerPort: 80
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 10
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: http
initialDelaySeconds: 5
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 12 }}
{{- if .Values.nfs.enabled }}
volumeMounts:
- name: public-files
mountPath: {{ .Values.nfs.mountPath }}
{{- end }}
{{- if .Values.nfs.enabled }}
volumes:
- name: public-files
persistentVolumeClaim:
claimName: {{ include "vhaudiquet-fr.fullname" . }}-public
{{- end }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
+41
View File
@@ -0,0 +1,41 @@
{{- if .Values.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "vhaudiquet-fr.fullname" . }}
labels:
{{- include "vhaudiquet-fr.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- if .Values.ingress.className }}
ingressClassName: {{ .Values.ingress.className }}
{{- end }}
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
pathType: {{ .pathType }}
backend:
service:
name: {{ include "vhaudiquet-fr.fullname" $ }}
port:
number: {{ $.Values.service.port }}
{{- end }}
{{- end }}
{{- end }}
+18
View File
@@ -0,0 +1,18 @@
{{- if .Values.nfs.enabled -}}
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ include "vhaudiquet-fr.fullname" . }}-public
labels:
{{- include "vhaudiquet-fr.labels" . | nindent 4 }}
spec:
capacity:
storage: {{ .Values.nfs.storageSize }}
accessModes:
- ReadOnlyMany
persistentVolumeReclaimPolicy: Retain
storageClassName: {{ .Values.nfs.storageClassName | default (printf "%s-nfs" (include "vhaudiquet-fr.fullname" .)) }}
nfs:
server: {{ .Values.nfs.server | required "nfs.server is required when nfs.enabled is true" }}
path: {{ .Values.nfs.path }}
{{- end }}
@@ -0,0 +1,15 @@
{{- if .Values.nfs.enabled -}}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "vhaudiquet-fr.fullname" . }}-public
labels:
{{- include "vhaudiquet-fr.labels" . | nindent 4 }}
spec:
accessModes:
- ReadOnlyMany
storageClassName: {{ .Values.nfs.storageClassName | default (printf "%s-nfs" (include "vhaudiquet-fr.fullname" .)) }}
resources:
requests:
storage: {{ .Values.nfs.storageSize }}
{{- end }}
+15
View File
@@ -0,0 +1,15 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "vhaudiquet-fr.fullname" . }}
labels:
{{- include "vhaudiquet-fr.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "vhaudiquet-fr.selectorLabels" . | nindent 4 }}
+106
View File
@@ -0,0 +1,106 @@
# Default values for vhaudiquet-fr.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
# Number of replicas
replicaCount: 1
# Container image configuration
image:
repository: git.vhaudiquet.fr/vhaudiquet/vhaudiquet.fr
pullPolicy: IfNotPresent
# The image tag defaults to the chart appVersion (which is set to git SHA by CI).
# Override this only if you need a specific version.
tag: ""
# Image pull secrets for private registries
imagePullSecrets: []
# Override the name of the chart
nameOverride: ""
fullnameOverride: ""
# Service account configuration
serviceAccount:
# Specifies whether a service account should be created
create: true
# Annotations to add to the service account
annotations: {}
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
name: ""
# Pod annotations
podAnnotations: {}
# Pod security context
podSecurityContext: {}
# fsGroup: 2000
# Container security context
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
# Service configuration
service:
type: ClusterIP
port: 80
# Ingress configuration
ingress:
enabled: true
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: vhaudiquet.fr
paths:
- path: /
pathType: Prefix
tls: []
# - secretName: vhaudiquet-fr-tls
# hosts:
# - vhaudiquet.fr
# Resource limits and requests
resources: {}
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# Node selector
nodeSelector: {}
# Tolerations
tolerations: []
# Affinity
affinity: {}
# Environment variables
env:
NGINX_HOST: vhaudiquet.fr
NGINX_PORT: "80"
# NFS Storage configuration for public files
nfs:
enabled: true
# NFS server IP address - REQUIRED when enabled
server: ""
# NFS export path
path: /mnt/main_storage/public
# Mount path inside the container
mountPath: /usr/share/nginx/html/public
# Storage size for PVC
storageSize: 10Gi
# Storage class name (leave empty for default)
storageClassName: ""