Browse Source

feat: add kubernetes chart

Signed-off-by: Bruno Bernard <contact.brunobernard@gmail.com>
pull/122/head
Bruno Bernard 7 months ago
parent
commit
1dcf1c98a7
  1. 28
      .github/workflows/build-kubernetes-chart.yaml
  2. 23
      charts/textbee/.helmignore
  3. 8
      charts/textbee/Chart.yaml
  4. 44
      charts/textbee/templates/NOTES.txt
  5. 52
      charts/textbee/templates/_helpers.tpl
  6. 131
      charts/textbee/templates/deployment.yaml
  7. 32
      charts/textbee/templates/hpa.yaml
  8. 88
      charts/textbee/templates/ingress.yaml
  9. 41
      charts/textbee/templates/service.yaml
  10. 142
      charts/textbee/values.yaml

28
.github/workflows/build-kubernetes-chart.yaml

@ -0,0 +1,28 @@
name: Release Charts
on:
push:
permissions: write-all
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Configure Git
run: |
git config user.name "$GITHUB_ACTOR"
git config user.email "$GITHUB_ACTOR@users.noreply.github.com"
- name: Run chart-releaser
id: cr
uses: helm/chart-releaser-action@v1.5.0
env:
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
with:
charts_dir: ./charts

23
charts/textbee/.helmignore

@ -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/

8
charts/textbee/Chart.yaml

@ -0,0 +1,8 @@
apiVersion: v2
name: textbee
description: A Helm chart to deploy TextBee.
type: application
version: 0.1.0
appVersion: "v2.6.2"

44
charts/textbee/templates/NOTES.txt

@ -0,0 +1,44 @@
Text Bee is ready !
Don't forget to create a secret
apiVersion: v1
kind: Secret
metadata:
name: textbee-api-secrets
type: Opaque
stringData:
MONGO_URI: mongodb://adminUser:adminPassword@textbee-db:27017/textbee?authSource=admin
JWT_SECRET: supersecret
JWT_EXPIRATION: 60d
FIREBASE_PROJECT_ID:
FIREBASE_PRIVATE_KEY_ID:
FIREBASE_PRIVATE_KEY:
FIREBASE_CLIENT_EMAIL:
FIREBASE_CLIENT_ID:
FIREBASE_CLIENT_C509_CERT_URL:
MAIL_HOST:
MAIL_PORT:
MAIL_USER:
MAIL_PASS:
MAIL_FROM:
MAIL_REPLY_TO:
apiVersion: v1
kind: Secret
metadata:
name: textbee-web-secrets
type: Opaque
stringData:
AUTH_SECRET= # https://generate-secret.vercel.app/32
NEXT_PUBLIC_SITE_URL: http://localhost:80
NEXT_PUBLIC_GOOGLE_CLIENT_ID:
NEXT_PUBLIC_TAWKTO_EMBED_URL:
DATABASE_URL: mongodb://adminUser:adminPassword@textbee-db:27017/textbee?authSource=admin
MAIL_HOST:
MAIL_PORT:
MAIL_USER:
MAIL_PASS:
MAIL_FROM:
ADMIN_EMAIL:

52
charts/textbee/templates/_helpers.tpl

@ -0,0 +1,52 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "textbee.name" -}}
{{- default .Chart.Name .Values.api.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 "textbee.fullname" -}}
{{- if .Values.api.fullnameOverride }}
{{- .Values.api.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- $name := default .Chart.Name .Values.api.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 "textbee.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "textbee.labels" -}}
helm.sh/chart: {{ include "textbee.chart" . }}
{{ include "textbee.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "textbee.selectorLabels" -}}
app.kubernetes.io/name: {{ include "textbee.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

131
charts/textbee/templates/deployment.yaml

@ -0,0 +1,131 @@
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "textbee.fullname" .}}-api
labels:
{{- include "textbee.labels" . | nindent 4 }}
spec:
{{- if not .Values.api.autoscaling.enabled }}
replicas: {{ .Values.api.replicaCount }}
{{- end }}
selector:
matchLabels:
{{- include "textbee.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.api.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "textbee.labels" . | nindent 8 }}
{{- with .Values.api.podLabels }}
{{- toYaml . | nindent 8 }}
{{- end }}
spec:
containers:
{{- with .Values.api.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.podSecurityContext }}
securityContext:
{{- toYaml . | nindent 8 }}
{{- end }}
- name: {{ .Chart.Name }}-api
{{- with .Values.api.securityContext }}
securityContext:
{{- toYaml . | nindent 12 }}
{{- end }}
image: "{{ .Values.api.image.repository }}:{{ .Values.api.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.api.image.pullPolicy }}
ports:
- name: http
containerPort: {{ .Values.api.service.port }}
protocol: TCP
env:
- name: PORT
value: "{{ .Values.api.service.port }}"
{{- if .Values.api.redis.enabled }}
- name: REDIS_URL
value: "{{ .Values.api.redis.dsn }}"
- name: USE_SMS_QUEUE
value: "true"
{{- else }}
- name: USE_SMS_QUEUE
value: "false"
{{- end }}
{{- if .Values.web.enabled }}
- name: FRONTEND_URL
value: "http://{{ include "textbee.fullname" .}}-web:{{ .Values.web.service.port }}"
{{- end}}
envFrom:
- secretRef:
name: {{ include "textbee.fullname" .}}-api-secrets
{{- with .Values.api.livenessProbe }}
livenessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.api.readinessProbe }}
readinessProbe:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.api.resources }}
resources:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.api.volumeMounts }}
volumeMounts:
{{- toYaml . | nindent 12 }}
{{- end }}
{{- with .Values.api.volumes }}
volumes:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.api.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.api.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.api.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
---
{{- if not .Values.web.enabled -}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "textbee.fullname" .}}-web
labels:
{{- include "textbee.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app: {{ include "textbee.fullname" .}}-web
template:
metadata:
labels:
app: {{ include "textbee.fullname" .}}-web
spec:
containers:
- name: {{ include "textbee.fullname" .}}-web
image: "{{ .Values.web.image.repository }}:{{ .Values.web.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.api.image.pullPolicy }}
ports:
- containerPort: {{ .Values.web.service.port }}
env:
- name: PORT
value: "{{ .Values.web.service.port }}"
- name: NEXT_PUBLIC_API_BASE_URL
value: "http://{{ include "textbee.fullname" .}}-api:{{ .Values.web.service.port }}/api/v1"
envFrom:
- secretRef:
name: {{ include "textbee.fullname" .}}-web-secrets
{{- end }}

32
charts/textbee/templates/hpa.yaml

@ -0,0 +1,32 @@
{{- if .Values.api.autoscaling.enabled }}
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: {{ include "textbee.fullname" . }}
labels:
{{- include "textbee.labels" . | nindent 4 }}
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: {{ include "textbee.fullname" . }}
minReplicas: {{ .Values.api.autoscaling.minReplicas }}
maxReplicas: {{ .Values.api.autoscaling.maxReplicas }}
metrics:
{{- if .Values.api.autoscaling.targetCPUUtilizationPercentage }}
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: {{ .Values.api.autoscaling.targetCPUUtilizationPercentage }}
{{- end }}
{{- if .Values.api.autoscaling.targetMemoryUtilizationPercentage }}
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: {{ .Values.api.autoscaling.targetMemoryUtilizationPercentage }}
{{- end }}
{{- end }}

88
charts/textbee/templates/ingress.yaml

@ -0,0 +1,88 @@
{{- if .Values.api.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "textbee.fullname" . }}
labels:
{{- include "textbee.labels" . | nindent 4 }}
{{- with .Values.api.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.api.ingress.className }}
ingressClassName: {{ . }}
{{- end }}
{{- if .Values.api.ingress.tls }}
tls:
{{- range .Values.api.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.api.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- with .pathType }}
pathType: {{ . }}
{{- end }}
backend:
service:
name: {{ include "textbee.fullname" $ }}
port:
number: {{ $.Values.api.service.port }}
{{- end }}
{{- end }}
{{- end }}
---
{{- if .Values.web.ingress.enabled -}}
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: {{ include "textbee.fullname" . }}
labels:
{{- include "textbee.labels" . | nindent 4 }}
{{- with .Values.web.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
spec:
{{- with .Values.api.ingress.className }}
ingressClassName: {{ . }}
{{- end }}
{{- if .Values.web.ingress.tls }}
tls:
{{- range .Values.web.ingress.tls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.web.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- with .pathType }}
pathType: {{ . }}
{{- end }}
backend:
service:
name: {{ include "textbee.fullname" $ }}
port:
number: {{ $.Values.web.service.port }}
{{- end }}
{{- end }}
{{- end }}

41
charts/textbee/templates/service.yaml

@ -0,0 +1,41 @@
---
{{- if .Values.web.service.enabled -}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "textbee.fullname" . }}-web
labels:
{{- include "textbee.labels" . | nindent 4 }}
spec:
selector:
app: {{ include "textbee.fullname" . }}-web
{{- if .Values.web.service.annotations }}
annotations:
{{- toYaml .Values.web.service.annotations | nindent 4 }}
{{- end }}
ports:
- port: {{ .Values.web.service.port | default 80 }}
targetPort: {{ .Values.web.service.targetPort | default 80 }}
type: {{ .Values.web.service.type | default "ClusterIP" }}
{{- end }}
---
{{- if .Values.api.service.enabled -}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "textbee.fullname" . }}-api
labels:
{{- include "textbee.labels" . | nindent 4 }}
spec:
selector:
app: {{ include "textbee.fullname" . }}-web
{{- if .Values.api.service.annotations }}
annotations:
{{- toYaml .Values.api.service.annotations | nindent 4 }}
{{- end }}
ports:
- port: {{ .Values.api.service.port | default 80 }}
targetPort: {{ .Values.api.service.targetPort | default 80 }}
type: {{ .Values.api.service.type | default "ClusterIP" }}
{{- end }}

142
charts/textbee/values.yaml

@ -0,0 +1,142 @@
api:
replicaCount: 1
image:
repository: ghcr.io/vernu/textbee/api
# This sets the pull policy for images.
pullPolicy: IfNotPresent
# Overrides the image tag whose default is the chart appVersion.
tag: ""
# This is for the secrets for pulling an image from a private repository more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/pull-image-private-registry/
imagePullSecrets: []
# This is to override the chart name.
nameOverride: ""
fullnameOverride: ""
# Redis enabled means API SMS QUEUE is enabled.
redis:
enabled: true
dsn: ""
# This is the name of the secret that contains the environment variables for the API.
# If not set, it will default to the chart name with '-env' suffix.
envSecretName: ""
# This is for setting Kubernetes Annotations to a Pod.
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations/
podAnnotations: {}
# This is for setting Kubernetes Labels to a Pod.
# For more information checkout: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/
podLabels: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
# This is for setting up a service more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/
service:
# This sets the service type more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#publishing-services-service-types
type: ClusterIP
# This sets the ports more information can be found here: https://kubernetes.io/docs/concepts/services-networking/service/#field-spec-ports
port: 80
annotations: {}
labels: {}
# This block is for setting up the ingress for more information can be found here: https://kubernetes.io/docs/concepts/services-networking/ingress/
ingress:
enabled: false
className: ""
annotations: {}
# kubernetes.io/ingress.class: nginx
# kubernetes.io/tls-acme: "true"
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
tls: []
# - secretName: chart-example-tls
# hosts:
# - chart-example.local
resources: {}
# We usually recommend not to specify default resources and to leave this as a conscious
# choice for the user. This also increases chances charts run on environments with little
# resources, such as Minikube. If you do want to specify resources, uncomment the following
# lines, adjust them as necessary, and remove the curly braces after 'resources:'.
# limits:
# cpu: 100m
# memory: 128Mi
# requests:
# cpu: 100m
# memory: 128Mi
# This is to setup the liveness and readiness probes more information can be found here: https://kubernetes.io/docs/tasks/configure-pod-container/configure-liveness-readiness-startup-probes/
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
# This section is for setting up autoscaling more information can be found here: https://kubernetes.io/docs/concepts/workloads/autoscaling/
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 10
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
# Additional volumes on the output Deployment definition.
volumes: []
# - name: foo
# secret:
# secretName: mysecret
# optional: false
# Additional volumeMounts on the output Deployment definition.
volumeMounts: []
# - name: foo
# mountPath: "/etc/foo"
# readOnly: true
nodeSelector: {}
tolerations: []
affinity: {}
web:
enabled: false
image:
repository: ghcr.io/vernu/textbee/web
pullPolicy: IfNotPresent
tag: ""
service:
type: ClusterIP
port: 80
labels: {}
annotations: {}
ingress:
enabled: false
className: ""
annotations: {}
hosts:
- host: chart-example.local
paths:
- path: /
pathType: ImplementationSpecific
Loading…
Cancel
Save