Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,8 @@ result
# All .env files
.env
.env.yaml
# Helm dev values with passwords
helm-chart/values.dev.yaml
helm-chart/charts/
## ============================================================================

23 changes: 23 additions & 0 deletions helm-chart/.helmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/
9 changes: 9 additions & 0 deletions helm-chart/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
dependencies:
- name: postgresql
repository: https://charts.bitnami.com/bitnami
version: 18.8.6
- name: keycloak
repository: https://repo.helmforge.dev
version: 3.0.7
digest: sha256:15cdc5bf9f1d24c4f3beb12f85675fa57c050e4f1662d36d50e35e430eeb301a
generated: "2026-08-07T09:27:51.820259829+02:00"
18 changes: 18 additions & 0 deletions helm-chart/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v2
name: hackagon
description: A Helm chart for Hackagon on Kubernetes

type: application

version: 0.1.0
appVersion: "1.0.0"

dependencies:
- name: postgresql
version: 18.x
repository: https://charts.bitnami.com/bitnami
condition: postgresql.enabled
- name: keycloak
version: 3.x
repository: https://repo.helmforge.dev
condition: keycloak.enabled
19 changes: 19 additions & 0 deletions helm-chart/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Hackagon has been deployed!

Frontend: https://{{ .Values.baseDomain }}
Keycloak: https://auth.{{ .Values.baseDomain }}

To get the generated frontend OIDC secrets, run:

kubectl get secret {{ include "hackagon.fullname" . }}-frontend-secrets \
-n {{ .Release.Namespace }} -o jsonpath='{.data.secrets\.yaml}' | base64 -d

Passwords are set in your values files. Retrieve them with:

# Platform (hackagon) user password
kubectl get secret {{ include "hackagon.fullname" . }}-postgresql \
-n {{ .Release.Namespace }} -o jsonpath='{.data.postgres-password}' | base64 -d

Check the status of your release:

helm status {{ .Release.Name }} -n {{ .Release.Namespace }}
130 changes: 130 additions & 0 deletions helm-chart/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "hackagon.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 "hackagon.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 "hackagon.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Common labels
*/}}
{{- define "hackagon.labels" -}}
helm.sh/chart: {{ include "hackagon.chart" . }}
{{ include "hackagon.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{/*
Selector labels
*/}}
{{- define "hackagon.selectorLabels" -}}
app.kubernetes.io/name: {{ include "hackagon.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

{{/*
Create the name of the service account to use
*/}}
{{- define "hackagon.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "hackagon.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}

{{/*
Base domain with substitution
*/}}
{{- define "hackagon.baseDomain" -}}
{{- .Values.baseDomain | replace "{baseDomain}" .Values.baseDomain }}
{{- end }}

{{/*
Frontend host with substitution
*/}}
{{- define "hackagon.frontendHost" -}}
{{- printf "app.%s" (include "hackagon.baseDomain" .) | replace "{baseDomain}" .Values.baseDomain }}
{{- end }}

{{/*
Keycloak host with substitution
*/}}
{{- define "hackagon.keycloakHost" -}}
{{- printf "auth.%s" (include "hackagon.baseDomain" .) | replace "{baseDomain}" .Values.baseDomain }}
{{- end }}

{{/*
Frontend service name
*/}}
{{- define "hackagon.frontendServiceName" -}}
{{- printf "%s-frontend" (include "hackagon.fullname" .) }}
{{- end }}

{{/*
Backend service name
*/}}
{{- define "hackagon.backendServiceName" -}}
{{- printf "%s-backend" (include "hackagon.fullname" .) }}
{{- end }}

{{/*
Generate a random alphanumeric string of given length
Usage: include "hackagon.randAlphaNum" (dict "length" 32)
*/}}
{{- define "hackagon.randAlphaNum" -}}
{{- randAlphaNum .length | lower }}
{{- end }}

{{/*
Keycloak service name (bitnami chart names it <release>-keycloak)
*/}}
{{- define "hackagon.keycloakServiceName" -}}
{{- printf "%s-keycloak" .Release.Name }}
{{- end }}

{{/*
PostgreSQL service name (bitnami chart names it <release>-postgresql)
*/}}
{{- define "hackagon.postgresqlServiceName" -}}
{{- printf "%s-postgresql" .Release.Name }}
{{- end }}

{{/*
Get password: use provided value or generate one
*/}}
{{- define "hackagon.getPassword" -}}
{{- if .value }}
{{- .value | b64enc }}
{{- else }}
{{- include "hackagon.randAlphaNum" .length | b64enc }}
{{- end }}
{{- end }}
26 changes: 26 additions & 0 deletions helm-chart/templates/backend-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "hackagon.fullname" . }}-backend-config
namespace: {{ .Release.Namespace }}
labels:
{{- include "hackagon.labels" . | nindent 4 }}
data:
config.yaml: |
server:
port: {{ .Values.backend.config.server.port | quote }}
adminemail: {{ .Values.backend.config.server.adminemail | replace "{baseDomain}" .Values.baseDomain | quote }}
adminkeycloakid: {{ .Values.backend.config.server.adminkeycloakid | quote }}
database:
driver: {{ .Values.backend.config.database.driver | quote }}
host: {{ include "hackagon.postgresqlServiceName" . | quote }}
port: {{ .Values.backend.config.database.port }}
dbname: {{ .Values.backend.config.database.dbname | quote }}
user: {{ .Values.backend.config.database.user | quote }}
password: {{ .Values.backend.config.database.postgresPassword | required "postgresql.auth.postgresPassword is required" | quote }}
oidc:
jwksurl: {{ .Values.backend.config.oidc.jwksurl | replace "{baseDomain}" .Values.baseDomain | quote }}
issuerurl: {{ .Values.backend.config.oidc.issuerurl | replace "{baseDomain}" .Values.baseDomain | quote }}
algorithm: {{ .Values.backend.config.oidc.algorithm | quote }}
logging:
level: {{ .Values.backend.config.logging.level | quote }}
55 changes: 55 additions & 0 deletions helm-chart/templates/backend-deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "hackagon.fullname" . }}-backend
namespace: {{ .Release.Namespace }}
labels:
{{- include "hackagon.labels" . | nindent 4 }}
app.kubernetes.io/component: backend
spec:
replicas: {{ .Values.backend.replicaCount }}
selector:
matchLabels:
{{- include "hackagon.selectorLabels" . | nindent 6 }}
app.kubernetes.io/component: backend
template:
metadata:
{{- with .Values.backend.annotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "hackagon.selectorLabels" . | nindent 8 }}
app.kubernetes.io/component: backend
spec:
containers:
- name: backend
image: "{{ .Values.backend.image.repository }}:{{ .Values.backend.image.tag }}"
imagePullPolicy: {{ .Values.backend.image.pullPolicy }}
args:
- "--config-dir=/etc/hackagon/"
ports:
- name: grpc
containerPort: 3000
protocol: TCP
resources:
{{- toYaml .Values.backend.resources | nindent 12 }}
volumeMounts:
- name: config
mountPath: /etc/hackagon/config.yaml
subPath: config.yaml
readOnly: true
livenessProbe:
grpc:
port: 3000
initialDelaySeconds: 10
periodSeconds: 15
readinessProbe:
grpc:
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
volumes:
- name: config
configMap:
name: {{ include "hackagon.fullname" . }}-backend-config
18 changes: 18 additions & 0 deletions helm-chart/templates/backend-service.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "hackagon.fullname" . }}-backend
namespace: {{ .Release.Namespace }}
labels:
{{- include "hackagon.labels" . | nindent 4 }}
app.kubernetes.io/component: backend
spec:
type: {{ .Values.backend.service.type }}
ports:
- port: {{ .Values.backend.service.port }}
targetPort: grpc
protocol: TCP
name: grpc
selector:
{{- include "hackagon.selectorLabels" . | nindent 4 }}
app.kubernetes.io/component: backend
20 changes: 20 additions & 0 deletions helm-chart/templates/frontend-configmap.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: {{ include "hackagon.fullname" . }}-frontend-config
namespace: {{ .Release.Namespace }}
labels:
{{- include "hackagon.labels" . | nindent 4 }}
data:
config.yaml: |
log:
forceDevLog: {{ .Values.frontend.config.log.forceDevLog }}
backend:
hostname: {{ .Values.frontend.config.backend.hostname | quote }}
port: {{ .Values.frontend.config.backend.port }}
cookies:
useSecure: {{ .Values.frontend.config.cookies.useSecure }}
oidc:
clientId: {{ .Values.frontend.config.oidc.clientId | quote }}
issuer: {{ .Values.frontend.config.oidc.issuer | replace "{baseDomain}" .Values.baseDomain | quote }}
audience: {{ .Values.frontend.config.oidc.audience | quote }}
Loading
Loading