Skip to content

Commit

Permalink
feat(chart): add initial version of the helm chart (#383)
Browse files Browse the repository at this point in the history
Signed-off-by: Jakob Steiner <[email protected]>
  • Loading branch information
kosmoz authored Jan 29, 2025
1 parent c225ef9 commit 78f9d58
Show file tree
Hide file tree
Showing 17 changed files with 652 additions and 1 deletion.
1 change: 1 addition & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
node_modules
internal/frontend/dist
deploy
45 changes: 45 additions & 0 deletions .github/workflows/build-chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
name: Build helm chart

on:
push:
branches:
- 'main'
paths:
- deploy/charts/**
tags:
- '*'
pull_request:
workflow_dispatch:
inputs:
publish:
description: 'Publish the helm chart to ghcr.io'
type: boolean
default: false

jobs:
build-chart:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- name: Setup helm
uses: azure/setup-helm@fe7b79cd5ee1e45176fcad797de68ecaf3ca4814 # v4.2.0
- name: Build helm chart
run: |
helm dependency build deploy/charts/distr
helm lint deploy/charts/distr
helm package deploy/charts/distr
- name: Login to GitHub Container Registry (tag or manual only)
if: ${{ startsWith(github.ref, 'refs/tags/') || inputs.publish }}
uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Push helm chart to ghcr.io (tag or manual only)
if: ${{ startsWith(github.ref, 'refs/tags/') || inputs.publish }}
run: |
for chart in distr-*.tgz; do
helm push "$chart" oci://ghcr.io/glasskube/charts
done
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,5 @@ Thumbs.db

# Sentry Config File
.sentryclirc

*.tgz
1 change: 1 addition & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
*.json
**/dist/*
CHANGELOG.md
deploy/charts/*/templates/*
23 changes: 23 additions & 0 deletions deploy/charts/distr/.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/
6 changes: 6 additions & 0 deletions deploy/charts/distr/Chart.lock
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies:
- name: postgresql
repository: oci://registry-1.docker.io/bitnamicharts
version: 16.4.5
digest: sha256:d85386cb7c57975ddb0d54ce5349329603210c1260b832b692b43020a4a259cc
generated: "2025-01-29T14:39:38.851254282+01:00"
24 changes: 24 additions & 0 deletions deploy/charts/distr/Chart.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
apiVersion: v2
name: distr
description: The easiest way to distribute enterprise software
keywords:
- distr
- web
- application
- enterprise
- software
- distribution
maintainers:
- name: Glasskube, Inc.
url: https://github.com/glasskube
icon: https://github.com/glasskube/distr/raw/refs/heads/main/frontend/ui/public/distr-logo.svg
home: https://distr.sh/docs/
type: application
version: '0.13.2'
appVersion: '0.13.2'
dependencies:
# https://github.com/bitnami/charts/blob/main/bitnami/postgresql
- name: postgresql
repository: oci://registry-1.docker.io/bitnamicharts
version: 16.x.x
condition: postgresql.enabled
22 changes: 22 additions & 0 deletions deploy/charts/distr/templates/NOTES.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
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 "distr.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 its status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "distr.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "distr.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 "distr.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 }}
120 changes: 120 additions & 0 deletions deploy/charts/distr/templates/_helpers.tpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "distr.name" -}}
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
{{- end }}

{{/*
Create a default fully qualified postgresql name.
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
*/}}
{{- define "distr.postgresql.fullname" -}}
{{- include "common.names.dependency.fullname" (dict "chartName" "postgresql" "chartValues" .Values.postgresql "context" $) -}}
{{- 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 "distr.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 "distr.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}

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

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

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

{{/*
Return the PostgreSQL connection URI
*/}}
{{- define "distr.databaseUri" -}}
{{- printf "postgresql://%s:$(DATABASE_PASSWORD)@%s:%s/%s?sslmode=prefer" .Values.postgresql.auth.username (include "distr.databaseHost" .) (include "distr.databasePort" .) .Values.postgresql.auth.database -}}
{{- end -}}

{{/*
Return the PostgreSQL Hostname
*/}}
{{- define "distr.databaseHost" -}}
{{- if .Values.postgresql.enabled }}
{{- if eq .Values.postgresql.architecture "replication" }}
{{- printf "%s-%s" (include "distr.postgresql.fullname" .) "primary" | trunc 63 | trimSuffix "-" -}}
{{- else -}}
{{- print (include "distr.postgresql.fullname" .) -}}
{{- end -}}
{{- else -}}
{{- print .Values.externalDatabase.host -}}
{{- end -}}
{{- end -}}

{{/*
Return the PostgreSQL Port
*/}}
{{- define "distr.databasePort" -}}
{{- if .Values.postgresql.enabled }}
{{- print .Values.postgresql.primary.service.ports.postgresql -}}
{{- else -}}
{{- printf "%d" (.Values.externalDatabase.port | int ) -}}
{{- end -}}
{{- end -}}

{{/*
Return the PostgreSQL Secret Name
*/}}
{{- define "distr.databaseSecretName" -}}
{{- if .Values.postgresql.enabled }}
{{- if .Values.postgresql.auth.existingSecret -}}
{{- print .Values.postgresql.auth.existingSecret -}}
{{- else -}}
{{- print (include "distr.postgresql.fullname" .) -}}
{{- end -}}
{{- else if .Values.externalDatabase.existingSecret -}}
{{- print .Values.externalDatabase.existingSecret -}}
{{- else -}}
{{- printf "%s-%s" (include "distr.fullname" .) "externaldb" -}}
{{- end -}}
{{- end -}}
104 changes: 104 additions & 0 deletions deploy/charts/distr/templates/deployment.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "distr.fullname" . }}
labels:
{{- include "distr.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: {{ .Values.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "distr.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "distr.labels" . | nindent 8 }}
{{- with .Values.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "distr.serviceAccountName" . }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: hub
{{- with .Values.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.service.port }}
protocol: TCP
{{- with .Values.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.readinessProbe }}
readinessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.volumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.hub.envFrom }}
envFrom:
{{- toYaml . | nindent 12 }}
{{- end }}
env:
{{- if .Values.postgresql.enabled }}
- name: DATABASE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "distr.databaseSecretName" . }}
key: password
{{- end}}
- name: DATABASE_URL
{{- if .Values.postgresql.enabled }}
value: {{ include "distr.databaseUri" . }}
{{- else if .Values.externalDatabase.uri }}
value: {{ .Values.externalDatabase.uri }}
{{- else }}
valueFrom:
secretKeyRef:
name: {{ include "distr.databaseSecretName" . }}
key: {{ .Values.externalDatabase.existingSecretUriKey }}
{{- end }}
{{- with .Values.hub.env }}
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.volumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- 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 }}
32 changes: 32 additions & 0 deletions deploy/charts/distr/templates/hpa.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
{{- if .Values.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "distr.fullname" . }}
labels:
{{- include "distr.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "distr.fullname" . }}
minReplicas: {{ .Values.autoscaling.minReplicas }}
maxReplicas: {{ .Values.autoscaling.maxReplicas }}
metrics:
{{- if .Values.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}
Loading

0 comments on commit 78f9d58

Please sign in to comment.