Add Argo CD Helm chart release
Test, publish birthday app and chart / publish-image (push) Successful in 5s
Test, publish birthday app and chart / validate (push) Successful in 4s
Test, publish birthday app and chart / publish-chart (push) Successful in 4s

This commit is contained in:
2026-10-19 08:43:31 +02:00
parent bfac12a5bb
commit 68d31e9692
15 changed files with 511 additions and 165 deletions
-137
View File
@@ -1,137 +0,0 @@
name: Publish and deploy birthday invitation
on:
push:
env:
IMAGE: registry.brunner.ninja/feedc0de/30-birthday
KUBERNETES_API: https://host.containers.internal:6443
KUBERNETES_TLS_SERVER_NAME: 192.168.0.2
jobs:
test:
name: Check JavaScript
runs-on: linux_amd64
steps:
- name: Check out source
uses: actions/checkout@v4
- name: Check server and browser scripts
run: |
authfile=$(mktemp)
trap 'rm -f "$authfile"' EXIT
printf '{"auths":{}}' > "$authfile"
export REGISTRY_AUTH_FILE="$authfile"
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < server.js
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < database.js
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < public/app.js
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < public/admin.js
podman run --rm \
--volume "$PWD:/app:ro" \
--workdir /app \
docker.io/library/node:24-alpine npm test
publish:
name: Build and push
if: gitea.ref == 'refs/heads/main'
needs: test
runs-on: linux_amd64
steps:
- name: Check out source
uses: actions/checkout@v4
- name: Configure isolated registry access
env:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }}
run: |
set -euo pipefail
authfile="${RUNNER_TEMP}/quay-auth.json"
printf '{"auths":{}}' > "$authfile"
chmod 0600 "$authfile"
printf '%s' "$QUAY_TOKEN" | podman login registry.brunner.ninja \
--authfile "$authfile" --username "$QUAY_USERNAME" --password-stdin
echo "REGISTRY_AUTH_FILE=$authfile" >> "$GITHUB_ENV"
- name: Build image
env:
COMMIT_SHA: ${{ gitea.sha }}
run: |
podman build \
--label "org.opencontainers.image.revision=${COMMIT_SHA}" \
--label "org.opencontainers.image.source=https://code.brunner.ninja/feedc0de/30-birthday" \
--tag "${IMAGE}:${COMMIT_SHA}" \
.
- name: Push commit tag
env:
COMMIT_SHA: ${{ gitea.sha }}
run: podman push "${IMAGE}:${COMMIT_SHA}"
- name: Push latest tag
if: gitea.ref == 'refs/heads/main'
env:
COMMIT_SHA: ${{ gitea.sha }}
run: |
podman tag "${IMAGE}:${COMMIT_SHA}" "${IMAGE}:latest"
podman push "${IMAGE}:latest"
- name: Remove registry credentials
if: always()
run: rm -f "${RUNNER_TEMP}/quay-auth.json"
deploy:
name: Deploy to Kubernetes
if: gitea.ref == 'refs/heads/main'
needs: publish
runs-on: ubuntu-latest
steps:
- name: Install kubectl
env:
KUBECTL_VERSION: v1.36.4
run: |
curl --fail --silent --show-error --location \
--output "${RUNNER_TEMP}/kubectl" \
"https://dl.k8s.io/release/${KUBECTL_VERSION}/bin/linux/amd64/kubectl"
chmod 0700 "${RUNNER_TEMP}/kubectl"
- name: Configure Kubernetes access
env:
KUBE_CONFIG_BASE64: ${{ secrets.KUBE_CONFIG_BASE64 }}
run: |
test -n "${KUBE_CONFIG_BASE64}"
printf '%s' "${KUBE_CONFIG_BASE64}" | base64 --decode > "${RUNNER_TEMP}/kubeconfig"
chmod 0600 "${RUNNER_TEMP}/kubeconfig"
export KUBECONFIG="${RUNNER_TEMP}/kubeconfig"
"${RUNNER_TEMP}/kubectl" config set-cluster cluster \
--server="${KUBERNETES_API}" \
--tls-server-name="${KUBERNETES_TLS_SERVER_NAME}"
- name: Deploy commit image
env:
COMMIT_SHA: ${{ gitea.sha }}
run: |
export KUBECONFIG="${RUNNER_TEMP}/kubeconfig"
"${RUNNER_TEMP}/kubectl" --namespace default set image \
deployment/30-birthday \
"30-birthday=${IMAGE}:${COMMIT_SHA}"
for attempt in {1..60}; do
IFS='|' read -r generation observed desired updated available unavailable <<< "$(
"${RUNNER_TEMP}/kubectl" --namespace default get deployment/30-birthday \
--output=jsonpath='{.metadata.generation}|{.status.observedGeneration}|{.spec.replicas}|{.status.updatedReplicas}|{.status.availableReplicas}|{.status.unavailableReplicas}'
)"
echo "Rollout ${attempt}/60: generation ${observed}/${generation}, replicas ${updated}/${desired} updated, ${available}/${desired} available"
if [[ "${observed}" == "${generation}" \
&& "${updated}" == "${desired}" \
&& "${available}" == "${desired}" \
&& ( -z "${unavailable}" || "${unavailable}" == "0" ) ]]; then
echo "Deployment successfully rolled out"
exit 0
fi
sleep 5
done
"${RUNNER_TEMP}/kubectl" --namespace default describe deployment/30-birthday
exit 1
+149
View File
@@ -0,0 +1,149 @@
name: Test, publish birthday app and chart
on:
push:
pull_request:
env:
IMAGE: registry.brunner.ninja/feedc0de/30-birthday
jobs:
validate:
runs-on: linux_amd64
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Helm
run: |
curl --fail --silent --show-error --location \
--output "${RUNNER_TEMP}/helm.tar.gz" \
https://get.helm.sh/helm-v4.2.2-linux-amd64.tar.gz
tar -xzf "${RUNNER_TEMP}/helm.tar.gz" -C "${RUNNER_TEMP}" linux-amd64/helm
mv "${RUNNER_TEMP}/linux-amd64/helm" "${RUNNER_TEMP}/helm"
chmod 0700 "${RUNNER_TEMP}/helm"
echo "${RUNNER_TEMP}" >> "$GITHUB_PATH"
- name: Validate application and chart
run: |
set -euo pipefail
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < server.js
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < database.js
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < public/app.js
podman run --rm --interactive docker.io/library/node:24-alpine node --check - < public/admin.js
podman run --rm --volume "$PWD:/app:ro" --workdir /app \
docker.io/library/node:24-alpine npm test
chart/test.sh
publish-image:
if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main'
needs: validate
runs-on: linux_amd64
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Configure isolated registry access
env:
QUAY_USERNAME: ${{ secrets.QUAY_USERNAME }}
QUAY_TOKEN: ${{ secrets.QUAY_TOKEN }}
run: |
set -euo pipefail
authfile="${RUNNER_TEMP}/quay-auth.json"
printf '{"auths":{}}' > "$authfile"
chmod 0600 "$authfile"
printf '%s' "$QUAY_TOKEN" | podman login registry.brunner.ninja \
--authfile "$authfile" --username "$QUAY_USERNAME" --password-stdin
echo "REGISTRY_AUTH_FILE=$authfile" >> "$GITHUB_ENV"
- name: Build and push immutable image
env:
COMMIT_SHA: ${{ gitea.sha }}
run: |
set -euo pipefail
podman build \
--label "org.opencontainers.image.revision=${COMMIT_SHA}" \
--label "org.opencontainers.image.source=https://code.brunner.ninja/feedc0de/30-birthday" \
--tag "${IMAGE}:${COMMIT_SHA}" .
podman push "${IMAGE}:${COMMIT_SHA}"
podman tag "${IMAGE}:${COMMIT_SHA}" "${IMAGE}:latest"
podman push "${IMAGE}:latest"
- if: always()
run: rm -f "${RUNNER_TEMP}/quay-auth.json"
publish-chart:
if: gitea.event_name == 'push' && gitea.ref == 'refs/heads/main'
needs:
- validate
- publish-image
runs-on: linux_amd64
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Install Helm
run: |
curl --fail --silent --show-error --location \
--output "${RUNNER_TEMP}/helm.tar.gz" \
https://get.helm.sh/helm-v4.2.2-linux-amd64.tar.gz
tar -xzf "${RUNNER_TEMP}/helm.tar.gz" -C "${RUNNER_TEMP}" linux-amd64/helm
mv "${RUNNER_TEMP}/linux-amd64/helm" "${RUNNER_TEMP}/helm"
chmod 0700 "${RUNNER_TEMP}/helm"
echo "${RUNNER_TEMP}" >> "$GITHUB_PATH"
- id: chart
name: Derive chart version
env:
COMMIT_SHA: ${{ gitea.sha }}
run: |
set -euo pipefail
git fetch --tags origin main
test "$(git rev-parse origin/main)" = "$COMMIT_SHA"
description=$(git describe --tags --long --match 'v[0-9]*' --dirty)
case "$description" in *-dirty) echo 'Refusing dirty chart tree' >&2; exit 1 ;; esac
version=${description#v}
case "$version" in *-0-g*) version=${version%%-0-g*} ;; esac
echo "version=${version}" >> "$GITHUB_OUTPUT"
- name: Package and publish chart
env:
PACKAGE_USERNAME: ${{ secrets.PACKAGE_USERNAME }}
PACKAGE_TOKEN: ${{ secrets.PACKAGE_TOKEN }}
CHART_VERSION: ${{ steps.chart.outputs.version }}
COMMIT_SHA: ${{ gitea.sha }}
run: |
set -euo pipefail
test -n "$PACKAGE_USERNAME" && test -n "$PACKAGE_TOKEN"
helm lint chart
helm template 30-birthday chart --namespace default \
--set persistence.existingClaim=30-birthday-data \
--set ingress.enabled=true --set ingress.host=30.brunner.ninja >/dev/null
helm package chart --version "$CHART_VERSION" --app-version "$COMMIT_SHA" --destination "$RUNNER_TEMP"
curl --fail --silent --show-error \
--user "${PACKAGE_USERNAME}:${PACKAGE_TOKEN}" \
--request POST --upload-file "${RUNNER_TEMP}/30-birthday-${CHART_VERSION}.tgz" \
https://code.brunner.ninja/api/packages/feedc0de/helm/api/charts
- name: Promote GitOps chart version
env:
GITOPS_TOKEN: ${{ secrets.GITOPS_TOKEN }}
CHART_VERSION: ${{ steps.chart.outputs.version }}
COMMIT_SHA: ${{ gitea.sha }}
run: |
set -euo pipefail
test -n "$GITOPS_TOKEN"
test "$(git rev-parse origin/main)" = "$COMMIT_SHA"
auth=$(printf 'feedc0de:%s' "$GITOPS_TOKEN" | base64 | tr -d '\n')
git -c "http.extraheader=AUTHORIZATION: basic ${auth}" clone --depth=1 \
https://code.brunner.ninja/feedc0de/homelab-gitops.git "$RUNNER_TEMP/gitops"
unset auth
cd "$RUNNER_TEMP/gitops"
gitops_auth=$(printf 'feedc0de:%s' "$GITOPS_TOKEN" | base64 | tr -d '\n')
unset GITOPS_TOKEN
git config user.name feedc0de
git config user.email feedc0de@users.noreply.code.brunner.ninja
sed -i -E "0,/targetRevision: [^ ]+/s//targetRevision: ${CHART_VERSION}/" bootstrap/30-birthday.yaml
if git diff --quiet; then exit 0; fi
git add bootstrap/30-birthday.yaml
git commit -m "Deploy birthday invitation chart ${CHART_VERSION}"
for attempt in 1 2 3; do
if git -c "http.extraheader=AUTHORIZATION: basic ${gitops_auth}" push origin HEAD:main; then exit 0; fi
git -c "http.extraheader=AUTHORIZATION: basic ${gitops_auth}" fetch origin main
git rebase origin/main
done
exit 1
+24 -26
View File
@@ -89,36 +89,34 @@ Die Einladungsgrafik und PDF sind bewusst nicht im Git-Repository oder Container
## Kubernetes, Traefik und Authentik
Ein vollständiges Beispiel liegt in `k8s/invitation.yaml`. Es verwendet:
Das veröffentlichte Helm Chart befindet sich in `chart/`. Es owns the
Deployment, Service, probes, SQLite persistence contract, and the public/admin
Ingresses. SQLite must stay at one replica and uses a `Recreate` strategy.
- genau einen Pod (SQLite ist hier bewusst nicht horizontal skaliert)
- einen `128Mi`-`rook-ceph-block`-PVC für `/data/invites.db`
- die Domain `30.brunner.ninja`
- ausschließlich Traefiks EntryPoint `websecure`
- das bestehende `default-authentik@kubernetescrd`-Middleware nur für `/admin*` und `/api/admin/*`
- öffentliche Gast- und Asset-Routen ohne Authentik
- `Recreate`-Updates mit einer kurzen Unterbrechung, damit nur ein SQLite-Prozess den Block-PVC verwendet
For this homelab, Argo CD is the sole workload writer. Its cluster values and
existing-claim reference are in the separate
[homelab-gitops application](https://code.brunner.ninja/feedc0de/homelab-gitops/src/branch/main/apps/30-birthday).
The live `30-birthday-data` PVC is referenced as `existingClaim`; the chart
does not render or replace it. Invitation assets stay in the existing
`30-birthday-invitation` Secret, outside public Git. Authentik protects only
admin paths; guest and invitation asset routes remain public.
Zuerst das Image bauen und in die eigene Registry pushen:
For another cluster, create the invitation Secret first (the local helper
expects private assets excluded from Git), then install the chart:
```bash
docker build -t registry.brunner.ninja/feedc0de/30-birthday:latest .
docker push registry.brunner.ninja/feedc0de/30-birthday:latest
./k8s/create-invitation-secret.sh
helm repo add brunner.ninja https://brunner.ninja/charts
helm repo update brunner.ninja
helm upgrade --install 30-birthday brunner.ninja/30-birthday \
--namespace default --wait --timeout 5m
```
Die Gitea Action in `.gitea/workflows/container.yml` übernimmt Build, Push und Deployment automatisch. Sie benötigt diese Repository-Secrets:
Main-branch CI tests the app, publishes an immutable image, packages a chart
with that exact image as `appVersion`, and promotes only the chart version in
homelab-gitops. CI uses `QUAY_USERNAME`, `QUAY_TOKEN`, `PACKAGE_USERNAME`,
`PACKAGE_TOKEN`, and `GITOPS_TOKEN`; it has no Kubernetes credentials.
- `QUAY_USERNAME`: `feedc0de+birthday30`
- `QUAY_TOKEN`: Token dieses Robot-Accounts
- `KUBE_CONFIG_BASE64`: Kubeconfig des eingeschränkten `30-birthday-deployer`-ServiceAccounts
Workload und CI-Berechtigungen werden einmalig mit einem Cluster-Administrator angelegt:
```bash
./install.sh
./k8s/create-ci-kubeconfig.sh
```
Die Action baut `registry.brunner.ninja/feedc0de/30-birthday`, versieht jedes Image mit dem unveränderlichen Commit-SHA und aktualisiert auf `main` ausschließlich das bestehende `default/30-birthday`-Deployment. Ihre Kubernetes-Rolle kann keine Secrets oder anderen Deployments lesen oder verändern.
Der Cluster stellt Authentiks `/outpost.goauthentik.io/*` bereits zentral bereit. Der App-Service ist nur als `ClusterIP` erreichbar; daher kann ein externer Client Authentiks Identitätsheader nicht direkt am App-Port einschleusen.
The cluster exposes Authentik's `/outpost.goauthentik.io/*` centrally. The app
Service remains `ClusterIP`, so external clients cannot inject Authentik
identity headers through the app port.
+6
View File
@@ -0,0 +1,6 @@
apiVersion: v2
name: 30-birthday
description: Helm chart for the 30th birthday RSVP application
type: application
version: 0.1.0
appVersion: "bfac12a5bb24142c0c2f38b2a1c7bb0f5212df91"
+25
View File
@@ -0,0 +1,25 @@
# 30-birthday Helm chart
Portable Helm chart for the 30th birthday invitation and RSVP application. The
chart owns its Deployment, Service, probes and public/admin Ingresses. SQLite
requires one replica and a persistent claim. Set `persistence.existingClaim`
to adopt an existing PVC; the chart then does not render a PVC object.
Invitation PDF/JPEG assets and optional admin credentials are referenced by
existing Secret name only. Never commit their values.
The homelab keeps its desired values in
[homelab-gitops](https://code.brunner.ninja/feedc0de/homelab-gitops/src/branch/main/apps/30-birthday).
For a new cluster, create the invitation Secret and run:
```sh
helm repo add brunner.ninja https://brunner.ninja/charts
helm repo update brunner.ninja
helm upgrade --install 30-birthday brunner.ninja/30-birthday \
--namespace default --wait --timeout 5m \
--set origin=https://example.invalid \
--set ingress.enabled=true --set ingress.host=example.invalid
```
Chart tags version the Helm contract. `appVersion` is the exact immutable image
tag published by the same source CI run.
+16
View File
@@ -0,0 +1,16 @@
#!/bin/sh
set -eu
release=${RELEASE_NAME:-30-birthday}
namespace=${NAMESPACE:-default}
helm repo add brunner.ninja https://brunner.ninja/charts --force-update
helm repo update brunner.ninja
if [ -n "${VALUES_FILE:-}" ]; then
helm upgrade --install "$release" brunner.ninja/30-birthday \
--namespace "$namespace" --create-namespace \
--values "$VALUES_FILE" --wait --timeout 5m
else
helm upgrade --install "$release" brunner.ninja/30-birthday \
--namespace "$namespace" --create-namespace --wait --timeout 5m
fi
+7
View File
@@ -0,0 +1,7 @@
{{- define "birthday.name" -}}
30-birthday
{{- end -}}
{{- define "birthday.dataClaim" -}}
{{- default "30-birthday-data" .Values.persistence.existingClaim -}}
{{- end -}}
+86
View File
@@ -0,0 +1,86 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: 30-birthday
labels:
app: 30-birthday
app.kubernetes.io/name: 30-birthday
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
replicas: {{ .Values.replicaCount }}
strategy:
type: Recreate
selector:
matchLabels:
app: 30-birthday
template:
metadata:
labels:
app: 30-birthday
app.kubernetes.io/name: 30-birthday
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
automountServiceAccountToken: false
securityContext:
fsGroup: 65532
fsGroupChangePolicy: OnRootMismatch
containers:
- name: 30-birthday
image: {{ printf "%s:%s" .Values.image.repository .Chart.AppVersion | quote }}
imagePullPolicy: {{ .Values.image.pullPolicy }}
env:
- name: ORIGIN
value: {{ .Values.origin | quote }}
- name: DATABASE_FILE
value: /data/invites.db
- name: TRUST_AUTHENTIK
value: {{ .Values.trustAuthentik | quote }}
- name: INVITATION_PDF
value: {{ .Values.invitationPdf | quote }}
- name: INVITATION_IMAGE
value: {{ .Values.invitationImage | quote }}
{{- if .Values.adminKey.secretName }}
- name: ADMIN_KEY
valueFrom:
secretKeyRef:
name: {{ .Values.adminKey.secretName | quote }}
key: {{ .Values.adminKey.secretKey | quote }}
{{- end }}
ports:
- name: http
containerPort: 3000
readinessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 2
periodSeconds: 5
livenessProbe:
httpGet:
path: /health
port: http
initialDelaySeconds: 10
periodSeconds: 15
resources:
{{- toYaml .Values.resources | nindent 12 }}
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop: [ALL]
readOnlyRootFilesystem: true
runAsNonRoot: true
runAsUser: 65532
runAsGroup: 65532
volumeMounts:
- name: data
mountPath: /data
- name: invitation
mountPath: /private
readOnly: true
volumes:
- name: data
persistentVolumeClaim:
claimName: {{ include "birthday.dataClaim" . | quote }}
- name: invitation
secret:
secretName: {{ .Values.secrets.invitation | quote }}
+58
View File
@@ -0,0 +1,58 @@
{{- if .Values.ingress.enabled }}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: 30-birthday-public
annotations:
{{- toYaml .Values.ingress.annotations | nindent 4 }}
spec:
ingressClassName: {{ .Values.ingress.ingressClassName | quote }}
{{- if .Values.ingress.tlsSecretName }}
tls:
- hosts: [{{ .Values.ingress.host | quote }}]
secretName: {{ .Values.ingress.tlsSecretName | quote }}
{{- end }}
rules:
- host: {{ .Values.ingress.host | quote }}
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: 30-birthday
port:
name: http
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: 30-birthday-admin
annotations:
{{- toYaml .Values.ingress.adminAnnotations | nindent 4 }}
spec:
ingressClassName: {{ .Values.ingress.ingressClassName | quote }}
{{- if .Values.ingress.tlsSecretName }}
tls:
- hosts: [{{ .Values.ingress.host | quote }}]
secretName: {{ .Values.ingress.tlsSecretName | quote }}
{{- end }}
rules:
- host: {{ .Values.ingress.host | quote }}
http:
paths:
- path: /admin
pathType: Prefix
backend:
service:
name: 30-birthday
port:
name: http
- path: /api/admin/
pathType: Prefix
backend:
service:
name: 30-birthday
port:
name: http
{{- end }}
+18
View File
@@ -0,0 +1,18 @@
{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim) }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "birthday.dataClaim" . }}
labels:
app.kubernetes.io/name: 30-birthday
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.persistence.size }}
{{- with .Values.persistence.storageClassName }}
storageClassName: {{ . | quote }}
{{- end }}
{{- end }}
+16
View File
@@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: 30-birthday
labels:
app: 30-birthday
app.kubernetes.io/name: 30-birthday
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
selector:
app: 30-birthday
ports:
- name: http
port: 80
protocol: TCP
targetPort: http
Executable
+23
View File
@@ -0,0 +1,23 @@
#!/bin/sh
set -eu
chart_dir=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)
workdir=$(mktemp -d)
trap 'rm -rf "$workdir"' EXIT
helm lint "$chart_dir"
helm template 30-birthday "$chart_dir" --namespace default \
--set persistence.existingClaim=existing-data \
--set ingress.enabled=true --set ingress.host=test.example \
>"$workdir/rendered.yaml"
if grep -q '^kind: PersistentVolumeClaim$' "$workdir/rendered.yaml"; then
echo 'existingClaim must not render a PVC' >&2
exit 1
fi
grep -q 'claimName: "existing-data"' "$workdir/rendered.yaml"
grep -q 'name: 30-birthday-public' "$workdir/rendered.yaml"
grep -q 'name: 30-birthday-admin' "$workdir/rendered.yaml"
grep -q 'path: /api/admin/' "$workdir/rendered.yaml"
app_version=$(sed -n 's/^appVersion: *"\{0,1\}\([^" ]*\).*/\1/p' "$chart_dir/Chart.yaml")
image_repository=$(sed -n 's/^ repository: *//p' "$chart_dir/values.yaml")
grep -Fq "${image_repository}:${app_version}" "$workdir/rendered.yaml"
+36
View File
@@ -0,0 +1,36 @@
{
"$schema": "https://json-schema.org/draft-07/schema#",
"type": "object",
"properties": {
"replicaCount": {"type": "integer", "const": 1},
"image": {
"type": "object",
"required": ["repository", "pullPolicy"],
"properties": {
"repository": {"type": "string", "minLength": 1},
"pullPolicy": {"type": "string", "enum": ["Always", "IfNotPresent", "Never"]}
},
"additionalProperties": false
},
"origin": {"type": "string", "minLength": 1},
"trustAuthentik": {"type": "boolean"},
"invitationPdf": {"type": "string"},
"invitationImage": {"type": "string"},
"secrets": {"type": "object"},
"persistence": {
"type": "object",
"required": ["enabled", "existingClaim"],
"properties": {
"enabled": {"type": "boolean"},
"existingClaim": {"type": "string"},
"size": {"type": "string"},
"storageClassName": {"type": "string"}
},
"additionalProperties": true
},
"adminKey": {"type": "object"},
"ingress": {"type": "object"},
"resources": {"type": "object"}
},
"additionalProperties": true
}
+46
View File
@@ -0,0 +1,46 @@
replicaCount: 1
image:
repository: registry.brunner.ninja/feedc0de/30-birthday
pullPolicy: Always
origin: http://localhost:3000
trustAuthentik: false
invitationPdf: /private/Einladung.pdf
invitationImage: /private/einladung.jpg
secrets:
invitation: 30-birthday-invitation
persistence:
enabled: true
existingClaim: ""
size: 128Mi
storageClassName: ""
adminKey:
secretName: ""
secretKey: ADMIN_KEY
ingress:
enabled: false
host: ""
ingressClassName: traefik
tlsSecretName: ""
annotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.priority: "10"
adminAnnotations:
traefik.ingress.kubernetes.io/router.entrypoints: websecure
traefik.ingress.kubernetes.io/router.middlewares: default-authentik@kubernetescrd
traefik.ingress.kubernetes.io/router.priority: "100"
resources:
requests:
cpu: 10m
memory: 32Mi
ephemeral-storage: 32Mi
limits:
cpu: 250m
memory: 192Mi
ephemeral-storage: 128Mi
+1 -2
View File
@@ -5,5 +5,4 @@ set -euo pipefail
repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
"${repo_root}/k8s/create-invitation-secret.sh"
kubectl apply --filename="${repo_root}/k8s/ci-deployer.yaml"
kubectl apply --filename="${repo_root}/k8s/invitation.yaml"
exec "${repo_root}/chart/install.sh"