Helm charts for Appsmith fat container (#7343)

This commit is contained in:
geekup-legodevops 2021-10-02 13:16:07 +07:00 committed by GitHub
parent cb4d059e5f
commit ae26d2c611
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 1122 additions and 0 deletions

23
deploy/helm/.helmignore Normal file
View File

@ -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
deploy/helm/Chart.lock Normal file
View File

@ -0,0 +1,6 @@
dependencies:
- name: common
repository: https://charts.bitnami.com/bitnami
version: 0.3.1
digest: sha256:a6d6b7927942884d4abd2291b1561b6c86db71aedeb08b33ccd5a4228a776257
generated: "2021-09-09T10:54:25.247689+07:00"

20
deploy/helm/Chart.yaml Normal file
View File

@ -0,0 +1,20 @@
annotations:
category: Application
apiVersion: v2
appVersion: "1.16.0"
name: appsmith
type: application
dependencies:
# This dependency is used to render common declaration (tplvalues.render, storage.class, labels.standard)
# in Deployment, PVC, Service, ServiceAccount and TLS-Secret template
- name: common
version: 0.3.1
repository: https://charts.bitnami.com/bitnami
description: Appsmith is an open source framework to build admin panels, CRUD apps and workflows. Build everything you need, 10x faster.
maintainer:
- email: tech@appsmith.com
name: Appsmith
sources:
- https://github.com/appsmithorg/appsmith
- https://www.appsmith.com/
version: 1.3.0

167
deploy/helm/README.md Normal file
View File

@ -0,0 +1,167 @@
# Appsmith
Appsmith is a JS-based internal tool development platform. Internal tools take a lot of time to build even though they involve the same UI components, data integrations, and user access management. Developers love Appsmith because it saves them hundreds of hours.
Build interactive web apps by using UI components like a table, form components, button, charts, rich text editor, map, tabs, modal, and many more.
API Support: CURL importer for REST APIs Database Support: PostgreSQL, MongoDB, MySQL, Redshift, Elastic Search, DynamoDB, Redis, & MSFT SQL Server.
## TL;DR
---
```
helm repo add appsmith https://appsmithorg.github.io/appsmith
helm repo update
helm install appsmith/appsmith --generate-name
```
## Introduction
---
This chart bootstrap an [Appsmith](https://github.com/appsmithorg/appsmith) deployment on a [Kubernetes](kubernetes.io) cluster using [Helm](https://helm.sh) package manager.
## Prerequisites
---
* Install Helm package manager: [https://helm.sh/docs/intro/install/](https://helm.sh/docs/intro/install/)
* Ensure `kubectl` is installed and configured to connect to your cluster
* Install kubeclt: [kubernetes.io/vi/docs/tasks/tools/install-kubectl/](https://kubernetes.io/vi/docs/tasks/tools/install-kubectl/)
* Minikube: [Setup Kubectl](https://minikube.sigs.k8s.io/docs/handbook/kubectl/)
* Google Cloud Kubernetes: [Configuring cluster access for kubectl](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl)
* Aws EKS: [Create a kubeconfig for Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html)
* Microk8s: [Working with kubectl](https://microk8s.io/docs/working-with-kubectl)
* Ensure you have a default storage class running on your cluster. Please follow one of below guideline to enable your default storage class in case of no existing one
* Minikube: [Enable addon default-storageclass](https://kubernetes.io/docs/tutorials/hello-minikube/#enable-addons)
* Google Cloud Kubernetes: [Setting up default storage class on GKE](https://cloud.google.com/anthos/clusters/docs/on-prem/1.3/how-to/default-storage-class)
* AWS EKS: [Create default storage class](https://docs.aws.amazon.com/eks/latest/userguide/storage-classes.html)
* Microk8s: [Enable storage](https://microk8s.io/docs/command-reference#heading--microk8s-enable)
* Kubernetes NGINX Ingress Controller should be enable on your cluster by default. Please make sure that you install the right version for your cluster
* Minikube: [Set up Ingress on Minikube with the NGINX Ingress Controller](https://kubernetes.io/docs/tasks/access-application-cluster/ingress-minikube/)
* Google Cloud Kubernetes: [Ingress with NGINX controller on Google Kubernetes Engine](https://kubernetes.github.io/ingress-nginx/deploy/)
* AWS EKS: [Install NGINX Controller for AWS EKS](https://kubernetes.github.io/ingress-nginx/deploy/#network-load-balancer-nlb)
* Microk8s: [Add on: Ingress](https://microk8s.io/docs/addon-ingress)
## Installing the Chart
---
To install the chart with the release `appsmith`
```
helm install appsmith/appsmith --generate-name
```
The command deploys Appsmith application on Kubernetes cluster in the default configuration. The [Parameters](https://github.com/appsmithorg/appsmith/tree/release/deploy/helm#paramters) section lists the parameters that can be configured during installation.
## Uninstalling the Chart
---
To uninstall the `appsmith` release:
```
helm list
NAME NAMESPACE REVISION UPDATED STATUS CHART APP VERSION
appsmith-1631069261 default 1 2021-09-09 11:24:40.152766 +0700 +07 deployed appsmith-1.3.0 1.16.0
helm uninstall appsmith-1631069261
```
The command uninstalls the release and removes all Kubernetes resources associated with the chart
## Parameters
### Global parameters
| Name | Description | Value |
| -------------------------- | ---------------------------------------------------------- | ------- |
| `global.namespaceOverride` | Override the namespace for resource deployed by the chart | `""` |
| `global.storageClass` | Global StorageClass for Persistent Volume(s) | `""` |
### Common parameters
| Name | Description | Value |
| ------------------- | ------------------------------------------------- | ------------- |
| `fullnameOverride` | String to fully override `appsmith.name` template | `""` |
| `containerName` | Specify container's name running in the pods | `"appsmith"` |
| `commonLabels` | Labels to add to all deployed objects | `{}` |
| `commonAnnotations` | Annotations to add to all deployed objects | `{}` |
### Appsmith Image parameters
| Name | Description | Value |
| ------------------- | --------------------------- | --------------------------- |
| `image.registry` | Appsmith image registry | `index.docker.io` |
| `image.repository` | Appsmith image repository | `appsmith/appsmith-editor` |
| `image.tag` | Appsmith image tag | `latest` |
| `image.pullPolicy` | Appsmith image pull policy | `IfNotPresent` |
### Appsmith deployment parameters
| Name | Description | Value |
| --------------------------- | --------------------------------------------------- | --------------- |
| `strategyType` | Appsmith deployment strategy type | `RollingUpdate` |
| `schedulerName` | Alternate scheduler | `""` |
| `podAnnotations` | Annotations for Appsmith pods | `{}` |
| `podSecurityContext` | Appsmith pods security context | `{}` |
| `securityContext` | Set security context | `{}` |
| `resources.limit` | The resources limits for the Appsmith container | `{}` |
| `resources.requests` | The requested resources for the Appsmith container | `{}` |
| `nodeSelector` | Node labels for pod assignment | `{}` |
| `tolerations` | Tolerations for pod assignment | `[]` |
| `affinity` | Affinity fod pod assignment | `{}` |
### Appsmith service account parameters
| Name | Description | Value |
| ----------------------------- | ----------------------------------------------------------------------------------------------------------- | ------- |
| `serviceAccount.create` | Enable creation of `ServiceAccount` for Appsmith pods | `true` |
| `serviceAccount.name` | Name of the created `ServiceAccount` . If not set, a name is generated using the appsmith.fullname template | `""` |
| `serviceAccount.annotations` | Additional service account annotations | `{}` |
### Traffic Exposure Parameters
| Name | Description | Value |
| ----------------------------------- | --------------------------------------------------------------------------------------- | ----------- |
| `service.type` | Appsmith service type | `ClusterIP` |
| `service.port` | Appsmith service port | `80` |
| `service.portName` | Appsmith service port name | `appsmith` |
| `service.clusterIP` | Appsmith service Cluster | `""` |
| `service.loadBalancerIP` | Appsmith service Load Balancer IP | `""` |
| `service.loadBalancerSourceRanges` | Appsmith service Load Balancer sources | `[]` |
| `service.annotations` | Additional custom annotations for Appsmith service | `{}` |
| `ingress.enabled` | Enable ingress record generation for Appsmith | `false` |
| `ingress.hosts` | An array of hosts to be covered with the ingress record | `[]` |
| `ingress.tls` | Enable TLS configuration for the hosts defined at `ingress.hosts` parameter | `false` |
| `ingress.secrets` | Custom TLS certificates as secrets | `[]` |
| `ingress.certManager` | Enable ingress to use TLS certificates provided by Cert Manager | `false` |
| `ingress.certManagerTls` | Specify TLS secret resources created by Cert Manager | `[]` |
### Persistence parameters
| Name | Description | Value |
| ----------------------------------- | --------------------------------------------------------------------- | ------------------- |
| `persistence.enabled` | Enable persistence using Persistent Volume Claims | `true` |
| `persistence.storageClass` | Persistent Volume storage class | `""` |
| `persistence.localStorage` | Enable persistent volume using local storage | `false` |
| `persistence.storagePath` | Local storage path | `/tmp/hostpath_pv` |
| `persistence.localCluster` | Local running cluster to provide storage space | `[minikube]` |
| `persistence.accessModes` | Persistent Volume access modes | `[ReadWriteOnce]` |
| `persistence.size` | Persistent Volume size | `10Gi` |
| `storageClass.enabled` | Enable Storage Class configuration | `false` |
| `storageClass.defaultClass` | Create default Storage Class | `false` |
| `storageClass.bindingMode` | Binding mode for Persistent Volume Claims using Storage Class | `Immediate` |
| `storageClass.allowVolumeExpansion` | Allow expansion of Persistent Volume Claims using Storage Class | `true` |
| `storageClass.reclaimPolicy` | Configure the retention of the dynamically created Persistent Volume | `Delete` |
| `storageClass.provisioner` | Storage Class provisioner | `""` |
| `storageClass.annotations` | Additional storage class annotations | `{}` |
| `storageClass.mountOptions` | Mount options used by Persistent Volumes | `{}` |
| `storageClass.parameters` | Storage Class parameters | `{}` |
### Auto update chart's image
| Name | Description | Value |
| ----------------------- | --------------------------------------------- | ------------- |
| `autoupdate.enabled` | Enable auto update Helm chart's image | `true` |
| `autoupdate.scheduler` | Schedule time to run cron job to update image | `"0 * * * *"` |
Specify each parameter using `--set key=value[,key=value]` argument to helm install. For example:
```
helm install appsmith \
--set persistence.storageClass=appsmith-pv \
deploy/helm
```
The above command deploys Appsmith application and configure application to use storage class name `appsmith-pv`
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```
helm install -f values.yaml appsmith/appsmith --generate-name
```
*Tip: You can use the default [values.yaml](https://github.com/appsmithorg/appsmith/blob/release/deploy/helm/values.yaml)*
## Troubleshooting
If at any time you encounter an error during the installation process, reach out to support@appsmith.com or join our Discord Server
If you know the error and would like to reinstall Appsmith, simply delete the installation folder and the templates folder and execute the script again

View File

@ -0,0 +1,94 @@
## Introduction
- Deploying Appsmith application on a Kubernetes cluster is easier with [Appsmith's Helm chart](). However, it is best practice to secure your web application with TLS certificates.
- This guide will show you how to secure HTTP traffic with TLS and SSL certificates using [Cert Manager](https://cert-manager.io/).
## Prerequisites
- You should have a Kubernetes cluster running with [Helm v3.x](https://helm.sh/docs/intro/install/) installed.
- Ensure `kubectl` is installed and configured to connect to your cluster:
- Install kubeclt: [kubernetes.io/vi/docs/tasks/tools/install-kubectl/](https://kubernetes.io/vi/docs/tasks/tools/install-kubectl/)
- Google Cloud Kubernetes: [Configuring cluster access for kubectl](https://cloud.google.com/kubernetes-engine/docs/how-to/cluster-access-for-kubectl)
* Aws EKS: [Create a kubeconfig for Amazon EKS](https://docs.aws.amazon.com/eks/latest/userguide/create-kubeconfig.html)
## Secure traffic with TLS and Let's Encrypt SSL certificates
The Appsmith Helm chart comes with built-in support for Ingress routes and certificate management through [cert-manager](https://github.com/jetstack/cert-manager). This makes it easy to configure TLS support using certificates from a variety of certificate providers, including [Let's Encrypt](https://letsencrypt.org/).
The steps below explain how to use Ingress routes and cert-manager to configure TLS for your Appsmith deployment using a free Let's Encrypt certificate:
- Begin by installing the NGINX Ingress controller with Helm:
```shell
helm repo add ingress-nginx https://kubernetes.github.io/ingress-nginx
helm repo update
helm install ingress-nginx ingress-nginx/ingress-nginx
```
- Obtain the LoadBalancer IP address using the command below. Note this IP address as you will use it to configure DNS in a later step.
```
kubectl get svc ingress-nginx-controller -o jsonpath="{.status.loadBalancer.ingress[0].hostname}"
```
*Tip: It may take some time for the load balancer IP address to be assigned, so you may need to wait a few minutes before the command above returns any output.*
- Browse to the IP address and confirm that you see the default NGINX welcome page. This indicates that the NGINX Ingress controller is working.
- Configure the DNS for your domain name by adding an A record pointing to the public IP address obtained in the previous steps.
- Add the cert-manager repository, create a namespace and create CRDs:
```
helm repo add jetstack https://charts.jetstack.io
kubectl create namespace cert-manager
kubectl apply --validate=false -f https://github.com/jetstack/cert-manager/releases/download/v1.5.3/cert-manager.crds.yaml
```
*Tip: When executing these commands on Google Kubernetes Engine (GKE), you may encounter permission errors. [Refer to the official cert-manager documentation for notes on how to elevate your permissions](https://docs.cert-manager.io/en/latest/getting-started/install/kubernetes.html).*
- Create a ClusterIssuer resource for Let's Encrypt certificates. Create a file named letsencrypt-prod.yaml with the following content. Replace the EMAIL-ADDRESS placeholder with a valid email address.
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: letsencrypt-prod
spec:
acme:
email: EMAIL-ADDRESS
server: https://acme-v02.api.letsencrypt.org/directory
privateKeySecretRef:
name: letsencrypt-prod
solvers:
- http01:
ingress:
class: nginx
```
- Apply the changes to the cluster:
```
kubectl apply -f letsencrypt-prod.yaml
```
- Install cert-manager with Helm and configure Let's Encrypt as the default Certificate Authority (CA):
```
helm install cert-manager --namespace cert-manager jetstack/cert-manager --version v1.5.3
```
- Install Appsmith using Helm chart with additional parameters to integrate with Ingress and cert-manager. Replace the DOMAIN placeholder with your domain name:
```
helm install appsmith/appsmith --generate-name \
--set service.type=ClusterIP \
--set ingress.enabled=true \
--set ingress.tls=true \
--set ingress.certManager=true \
--set ingress.annotations."kubernetes\.io/ingress\.class"=nginx \
--set ingress.annotations."cert-manager\.io/cluster-issuer"=letsencrypt-prod \
--set ingress.hosts[0].host=DOMAIN \
--set ingress.hosts[0].paths[0].path=/ \
--set ingress.hosts[0].paths[0].pathType=ImplementationSpecific \
--set ingress.certManagerTls[0].hosts[0]=DOMAIN \
--set ingress.certManagerTls[0].secretName=letsencrypt-prod
```
After the deployment completes, visit the domain in your browser and you should see the Appsmith site over a secure TLS connection with a valid Let's Encrypt certificate.
<p>
<img src="./images/helm-ssl-config.png">
</p>
## Useful links
To learn more about the topics discussed in this guide, use the links below:
- [Appsmith Helm chart](https://github.com/appsmithorg/appsmith/blob/release/deploy/helm/README.md)
- [Get Started with Kubernetes](https://kubernetes.io/docs/setup/)
- [Kubernetes Ingress](https://kubernetes.io/docs/concepts/services-networking/ingress/)
- [NGINX Ingress Controller documentation](https://github.com/kubernetes/ingress/tree/master/controllers/nginx)
- [Annotations supported by various Ingress controllers](https://github.com/kubernetes/ingress/blob/master/docs/annotations.md)

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 194 KiB

View File

@ -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 "appsmith.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 "appsmith.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "appsmith.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 "appsmith.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 }}

View File

@ -0,0 +1,84 @@
{{/*
Expand the name of the chart.
*/}}
{{- define "appsmith.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 "appsmith.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 "appsmith.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
{{- end }}
{{/*
Common labels
*/}}
{{- define "appsmith.labels" -}}
appsmith.sh/chart: {{ include "appsmith.chart" . }}
{{ include "appsmith.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}
{{/*
Selector labels
*/}}
{{- define "appsmith.selectorLabels" -}}
app.kubernetes.io/name: {{ include "appsmith.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}
{{/*
Create the name of the service account to use
*/}}
{{- define "appsmith.serviceAccountName" -}}
{{- if .Values.serviceAccount.create }}
{{- default (include "appsmith.fullname" .) .Values.serviceAccount.name }}
{{- else }}
{{- default "default" .Values.serviceAccount.name }}
{{- end }}
{{- end }}
{{/*
Allow the release namespace to be overridden for multi-namespace deployments in combined charts.
*/}}
{{- define "appsmith.namespace" -}}
{{- if .Values.global -}}
{{- if .Values.global.namespaceOverride }}
{{- .Values.global.namespaceOverride -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end -}}
{{- else -}}
{{- .Release.Namespace -}}
{{- end }}
{{- end -}}
{{/*
Return the appropriate apiVersion for the object
*/}}
{{- define "apiVersion" -}}
{{- default "storage.k8s.io/v1" .Values.apiVersion -}}
{{- end -}}

View File

@ -0,0 +1,79 @@
{{- if and .Values.autoupdate.enabled (ne .Values.autoupdate.scheduler "") }}
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: imago
namespace: {{ include "appsmith.namespace" . }}
spec:
schedule: {{ .Values.autoupdate.scheduler | quote }}
concurrencyPolicy: Forbid
jobTemplate:
spec:
template:
metadata:
labels:
k8s-app: imago
spec:
restartPolicy: Never
serviceAccount: imago
serviceAccountName: imago
containers:
- name: imago
image: philpep/imago
imagePullPolicy: Always
args: ["--update"]
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: imago
namespace: {{ include "appsmith.namespace" . }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: imago
rules:
- apiGroups:
- ""
- apps
resources:
- pods
- replicasets
- statefulsets
verbs:
- list
- apiGroups:
- ""
- batch
resources:
- cronjobs
verbs:
- get
- list
- update
- apiGroups:
- ""
- apps
resources:
- daemonsets
- deployments
- statefulsets
verbs:
- get
- list
- update
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: imago
roleRef:
kind: ClusterRole
name: imago
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: imago
namespace: {{ include "appsmith.namespace" . }}
{{- end }}

View File

@ -0,0 +1,108 @@
apiVersion: apps/v1
kind: {{ if .Values.useStatefulSet }}StatefulSet{{- else }}Deployment{{- end }}
metadata:
name: {{ include "appsmith.fullname" . }}
namespace: {{ include "appsmith.namespace" . }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
spec:
{{- if not .Values.autoscaling.enabled }}
replicas: 1
{{- end }}
{{- if .Values.useStatefulSet }}
serviceName: {{ include "appsmith.fullname" . }}
updateStrategy:
{{- else }}
strategy:
{{- end }}
type: {{ .Values.strategyType }}
{{- if or (and (not .Values.useStatefulSet) (eq "Recreate" .Values.strategyType)) (and .Values.useStatefulSet (eq "OnDelete" .Values.strategyType)) }}
rollingUpdate: null
{{- end }}
selector:
matchLabels:
{{- include "appsmith.selectorLabels" . | nindent 6 }}
template:
metadata:
{{- with .Values.podAnnotations }}
annotations:
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "appsmith.selectorLabels" . | nindent 8 }}
spec:
{{- if .Values.schedulerName }}
schedulerName: {{ .Values.schedulerName | quote }}
{{- end }}
serviceAccountName: {{ template "appsmith.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- with .Values.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
containers:
- name: {{ .Values.containerName }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
imagePullPolicy: {{ .Values.image.pullPolicy }}
ports:
- name: http
containerPort: 80
protocol: TCP
- name: https
containerPort: 443
protocol: TCP
- name: supervisord
containerPort: 9001
protocol: TCP
livenessProbe:
httpGet:
path: /
port: http
readinessProbe:
httpGet:
path: /
port: http
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumeMounts:
- name: data
mountPath: /appsmith-stacks
volumes:
{{- if not .Values.persistence.enabled }}
- name: data
emptyDir: {}
{{- else if not .Values.useStatefulSet }}
- name: data
persistentVolumeClaim:
claimName: {{ template "appsmith.fullname" . }}
{{- else }}
volumeClaimTemplates:
- metadata:
name: data
{{- if .Values.persistence.annotations }}
annotations: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.annotations "context" $) | nindent 10 }}
{{- end }}
spec:
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{- if .Values.persistence.volumeClaimTemplates.selector }}
selector: {{- include "common.tplvalues.render" (dict "value" .Values.persistence.volumeClaimTemplates.selector "context" $) | nindent 10 }}
{{- end }}
{{ include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }}
{{- end }}

View File

@ -0,0 +1,69 @@
{{- if .Values.ingress.enabled -}}
{{- $fullName := include "appsmith.fullname" . -}}
{{- $svcPort := .Values.service.port -}}
{{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }}
{{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }}
{{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}}
{{- end }}
{{- end }}
{{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1
{{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}}
apiVersion: networking.k8s.io/v1beta1
{{- else -}}
apiVersion: extensions/v1beta1
{{- end }}
kind: Ingress
metadata:
name: {{ $fullName }}
namespace: {{ include "appsmith.namespace" . }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
{{- with .Values.ingress.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- if .Values.ingress.certManager }}
kubernetes.io/tls-acme: "true"
{{- end }}
spec:
{{- if .Values.ingress.tls }}
tls:
{{- range .Values.ingress.secrets }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- range .Values.ingress.certManagerTls }}
- hosts:
{{- range .hosts }}
- {{ . | quote }}
{{- end }}
secretName: {{ .secretName }}
{{- end }}
{{- end }}
rules:
{{- range .Values.ingress.hosts }}
- host: {{ .host | quote }}
http:
paths:
{{- range .paths }}
- path: {{ .path }}
{{- if and .pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }}
pathType: {{ .pathType }}
{{- end }}
backend:
{{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }}
service:
name: {{ $fullName }}
port:
number: {{ $svcPort }}
{{- else }}
serviceName: {{ $fullName }}
servicePort: {{ $svcPort }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: {{ include "appsmith.namespace" . }}

View File

@ -0,0 +1,27 @@
{{- if and .Values.persistence.enabled .Values.persistence.localStorage }}
apiVersion: v1
kind: PersistentVolume
metadata:
name: {{ include "appsmith.fullname" . }}
namespace: {{ include "appsmith.namespace" . }}
spec:
capacity:
storage: {{ .Values.persistence.size | quote }}
volumeMode: Filesystem # Mount volume into Pod as a directory.
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
persistentVolumeReclaimPolicy: Delete
storageClassName: {{ .Values.persistence.storageClass | quote }}
local:
path: {{ .Values.persistence.storagePath }} # Path to the directory this PV refers to.
nodeAffinity: # nodeAffinity is required when using local volumes.
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
{{- toYaml .Values.persistence.localCluster | nindent 12 }}
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if and .Values.persistence.enabled ( not .Values.useStatefulSet) }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "appsmith.fullname" . }}
namespace: {{ include "appsmith.namespace" . }}
spec:
accessModes:
{{- range .Values.persistence.accessModes }}
- {{ . | quote }}
{{- end }}
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
{{ include "common.storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }}
{{- end }}

View File

@ -0,0 +1,35 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "appsmith.fullname" . }}
namespace: {{ include "appsmith.namespace" . }}
labels:
{{- include "appsmith.labels" . | nindent 4 }}
{{- if or .Values.service.annotations .Values.commonAnnotations }}
annotations:
{{- if .Values.service.annotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.service.annotations "context" $) | nindent 4 }}
{{- end }}
{{- if .Values.commonAnnotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
{{- end }}
spec:
type: {{ .Values.service.type }}
{{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }}
clusterIP: {{ .Values.service.clusterIP }}
{{- end }}
{{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerIP }}
loadBalancerIP: {{ .Values.service.loadBalancerIP }}
{{- end }}
ports:
- name: {{ .Values.service.portName }}
port: {{ .Values.service.port }}
targetPort: http
{{- if and (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) .Values.service.nodePort }}
nodePort: {{ .Values.service.nodePort }}
{{- else if eq .Values.service.type "ClusterIP" }}
nodePort: null
{{- end }}
selector:
{{- include "appsmith.selectorLabels" . | nindent 4 }}

View File

@ -0,0 +1,19 @@
{{- if .Values.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "appsmith.serviceAccountName" . }}
namespace: {{ include "appsmith.namespace" . }}
labels: {{- include "appsmith.labels" . | nindent 4 }}
{{- if or .Values.serviceAccount.annotations .Values.commonAnnotations }}
annotations:
{{- if .Values.serviceAccount.annotations }}
{{ toYaml .Values.serviceAccount.annotations | nindent 4 }}
{{- end }}
{{- if .Values.commonAnnotations }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
{{- end }}
secrets:
- name: {{ template "appsmith.fullname" . }}
{{- end }}

View File

@ -0,0 +1,39 @@
{{- if and .Values.storageClass.enabled .Values.persistence.localStorage }}
apiVersion: {{ template "apiVersion" }}
kind: StorageClass
metadata:
name: {{ .Values.persistence.storageClass }}
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
---
{{- else if .Values.storageClass.enabled }}
apiVersion: {{ template "apiVersion" }}
kind: StorageClass
metadata:
name: {{ .Values.persistence.storageClass }}
{{- if or .Values.storageClass.annotations .Values.storageClass.defaultClass }}
annotations:
{{- end }}
{{- if .Values.storageClass.annotations }}
{{ toYaml .Values.storageClass.annotations | indent 4}}
{{- end }}
{{- if .Values.storageClass.defaultClass }}
storageclass.kubernetes.io/is-default-class: "true"
{{- end }}
volumeBindingMode: {{ .Values.storageClass.bindingMode }}
provisioner: {{ .Values.storageClass.provisioner }}
allowVolumeExpansion: {{ .Values.storageClass.allowVolumeExpansion }}
reclaimPolicy: {{ .Values.storageClass.reclaimPolicy }}
{{- if .Values.storageClass.parameters }}
parameters:
{{- range $key, $value := .Values.storageClass.parameters }}
{{ $key }}: {{ $value }}
{{- end }}
{{- end }}
{{- if .Values.storageClass.mountOptions }}
mountOptions:
{{- range .Values.storageClass.mountOptions }}
- {{ . }}
{{- end }}
{{- end }}
{{- end }}

View File

@ -0,0 +1,50 @@
{{- if .Values.ingress.enabled }}
{{- if .Values.ingress.secrets }}
{{- range .Values.ingress.secrets }}
{{- if .certificate }}
{{- if .key }}
apiVersion: v1
kind: Secret
metadata:
name: {{ printf "%s-tls" .host }}
namespace: {{ include "appsmith.namespace" $ }}
labels: {{- include "common.labels.standard" $ | nindent 4 }}
{{- if $.Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" $.Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
{{- if $.Values.commonAnnotations }}
annotations: {{- include "common.tplvalues.render" ( dict "value" $.Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
type: kubernetes.io/tls
data:
tls.crt: {{ .certificate | b64enc }}
tls.key: {{ .key | b64enc }}
---
{{- end }}
{{- end }}
{{- if and .Values.ingress.tls (not .Values.ingress.certManager) }}
{{- range .Values.ingress.hosts }}
{{- $ca := genCA "appsmith-ca" 365 }}
{{- $cert := genSignedCert .host nil (list .host) 365 $ca }}
apiVersion: v1
kind: Secret
metadata:
name: {{ printf "%s-tls" .host }}
namespace: {{ include "appsmith.namespace" $ }}
labels: {{- include "common.labels.standard" $ | nindent 4 }}
{{- if $.Values.commonLabels }}
{{- include "common.tplvalues.render" ( dict "value" .Values.commonLabels "context" $ ) | nindent 4 }}
{{- end }}
{{- if $.Values.commonAnnotations }}
annotations: {{- include "common.tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }}
{{- end }}
type: kubernetes.io/tls
data:
tls.crt: {{ $cert.Cert | b64enc | quote }}
tls.key: {{ $cert.Key | b64enc | quote }}
ca.crt: {{ $ca.Cert | b64enc | quote }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}

260
deploy/helm/values.yaml Normal file
View File

@ -0,0 +1,260 @@
## @section Global parameters
## Global Docker image parameters
## Please, note that this will override the image parameters, including dependencies, configured to use the global value
## Current available global Docker image parameters: imageRegistry, imagePullSecrets and storageClass
##
## @param global.imageRegistry Global Docker image registry
## @param global.imagePullSecrets Global Docker registry secret names as an array
## @param global.storageClass Global StorageClass for Persistent Volume(s)
## @param global.namespaceOverride Override the namespace for resource deployed by the chart, but can itself be overridden by the local namespaceOverride
##
global:
storageClass: ""
namespaceOverride: "appsmith"
## @param fullnameOverride String to fully override appsmith.fullname template
##
fullnameOverride: ""
## @param containerName specify running container name in a pod
##
containerName: "appsmith"
## @param commonLabels Labels to add to all deployed objects
##
commonLabels: {}
## @param commonAnnotations Common annotations to add to all Appsmith resources (sub-charts are not considered). Evaluated as a template
##
commonAnnotations: {}
## @param useStatefulSet Set to true to use a StatefulSet instead of a Deployment
##
useStatefulSet: true
## @param schedulerName Name of the scheduler (other than default) to dispatch pods
## ref: https://kubernetes.io/docs/tasks/administer-cluster/configure-multiple-schedulers/
##
schedulerName: ""
## @param strategyType StrategyType for Appsmith&reg; statefulset
## It can be set to RollingUpdate or Recreate by default.
##
strategyType: RollingUpdate
## Image
##
image:
registry: index.docker.io
repository: appsmith/appsmith-editor
pullPolicy: Always
# Overrides the image tag whose default is the chart appVersion.
tag: "latest"
## ServiceAccount
## ref: https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/
##
serviceAccount:
## @param serviceAccount.create Enable creation of ServiceAccount for Appsmith; pods
##
create: true
## @param serviceAccount.name Name of the created serviceAccount
## If not set and create is true, a name is generated using the appsmith.fullname template
##
name: ""
## @param serviceAccount.annotations Additional Service Account annotations
##
annotations: {}
podAnnotations: {}
podSecurityContext: {}
# fsGroup: 2000
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
## @param service.type Kubernetes Service type
##
type: ClusterIP
## @param service.port; service port
##
port: 80
## @param service.portName Appsmith; service port name
##
portName: appsmith
## @param service.clusterIP Appsmith; service cluster IP
## e.g:
## clusterIP: None
##
clusterIP: ""
## @param service.loadBalancerIP loadBalancerIP for Appsmith&reg; Service
## ref: https://kubernetes.io/docs/concepts/services-networking/service/#loadbalancer
##
loadBalancerIP: ""
## @param service.loadBalancerSourceRanges Address(es) that are allowed when service is LoadBalancer
## ref: https://kubernetes.io/docs/tasks/access-application-cluster/configure-cloud-provider-firewall/#restrict-access-for-loadbalancer-service
##
loadBalancerSourceRanges: []
## @param service.annotations Provide any additional annotations that may be required
##
annotations: {}
ingress:
## @param ingress.enabled Enable ingress record generation for Ghost
##
enabled: false
## @param ingress.annotations Additional custom annotations for the ingress record
## NOTE: If `ingress.certManager=true`, annotation `kubernetes.io/tls-acme: "true"` will automatically be added
##
annotations: {}
# kubernetes.io/ingress.class: nginx
# cert-manager.io/cluster-issuer: "letsencrypt-prod"
# nginx.ingress.kubernetes.io/ssl-redirect: "true"
# nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
hosts: []
# - host: appsmith-domain.me
# paths:
# - path: /
# pathType: ImplementationSpecific
## @param ingress.tls Enable TLS configuration for the host defined at `ingress.hosts` parameter
## You can:
## - Use the `ingress.secrets` parameter to create this TLS secret
## - Relay on cert-manager to create it by setting `ingress.certManager=true`
## - Relay on Helm to create self-signed certificates by setting `ingress.selfSigned=true`
##
tls: false
## @param ingress.secrets Custom TLS certificates as secrets
## NOTE: 'key' and 'certificate' are expected in PEM format
## NOTE: 'name' should line up with a 'secretName' set further up
## If it is not set and you're using cert-manager, this is unneeded, as it will create a secret for you with valid certificates
## If it is not set and you're NOT using cert-manager either, self-signed certificates will be created valid for 365 days
## It is also possible to create and manage the certificates outside of this helm chart
## Please see README.md for more information
## e.g:
## secrets:
## - host: chart-example.local
## key: |-
## -----BEGIN RSA PRIVATE KEY-----
## ...
## -----END RSA PRIVATE KEY-----
## certificate: |-
## -----BEGIN CERTIFICATE-----
## ...
## -----END CERTIFICATE-----
##
secrets: []
## @param ingress.certManager Enable ingress to use TLS certificates provided by Cert Manager
##
certManager: false
## @param ingress.certManagerTls Specify the TLS secret created by Cert Manager
## e.g:
## certManagerTls:
## - hosts:
## - appsmith-domain.me
## secretName: appsmith-tls
certManagerTls: []
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
limits: {}
requests: {}
autoscaling:
enabled: false
minReplicas: 1
maxReplicas: 100
targetCPUUtilizationPercentage: 80
# targetMemoryUtilizationPercentage: 80
nodeSelector: {}
tolerations: []
affinity: {}
persistence:
## @param persistence.enabled - Enable data persistence using PVC
##
enabled: true
## @param persistence.storageClass PVC Storage Class
##
storageClass: ""
## @param persistence.localStorage - Use local storage for PVC
##
localStorage: false
## @param persistence.storagePath - local storage path
##
storagePath: /tmp/hostpath_pv
## @param persistence.localCluster
##
localCluster:
- minikube
## @param persistence.accessModes PV Access Mode
##
accessModes:
- ReadWriteOnce
## @param persistence.size PVC Storage Request
##
size: 10Gi
## Fine tuning for volumeClaimTemplates
##
volumeClaimTemplates:
## @param persistence.volumeClaimTemplates.selector A label query over volumes to consider for binding (e.g. when using local volumes)
## A label query over volumes to consider for binding (e.g. when using local volumes)
## See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#labelselector-v1-meta for more details
##
selector: {}
## @param persistence.volumeClaimTemplates.requests Custom PVC requests attributes
## Sometime cloud providers use additional requests attributes to provision custom storage instance
## See https://cloud.ibm.com/docs/containers?topic=containers-file_storage#file_dynamic_statefulset
##
requests: {}
## @param persistence.volumeClaimTemplates.dataSource Add dataSource to the VolumeClaimTemplate
##
dataSource: {}
# tags:
# install-ingress-nginx: true
storageClass:
## @param storageClass.enabled - Enable config storage class
##
enabled: false
## @param storageClass.bindingMode - the binding mode for PVCs using this storage class
##
bindingMode: Immediate
## @param storageClass.defaultClass - boolean to set annotation designating this object as the default storage class
##
defaultClass: false
## @param storageClass.allowVolumeExpansion - allow expansion of PVCs using this storage class
##
allowVolumeExpansion: true
## @param storageClass.reclaimPolicy - configures the retention of the PV when dynamically created using this class
##
reclaimPolicy: Delete
## @param storageClass.provisioner - storage class parameters used for volumes created with this storage class
##
provisioner: ""
## @param storageClass.annotations - annotations in yaml map format to be added to the object
##
annotations: {}
## @param storageClass.mountOptions - options used by volumes created by this storage class
##
mountOptions: {}
## @param storageClass.parameters - storage class parameters used for volumes created with this storage class
##
parameters: {}
autoupdate:
## @param autoupdate.enabled - Enable config autoupdate
##
enabled: true
## @param autoupdate.scheduler - Schedule cron job to check & update Helm image
##
scheduler: "0 * * * *"