add erpnext 3.0.0 chart

main
Pratik 2021-04-06 10:44:42 +05:30
parent 59ca8ee171
commit 5849df3b6d
25 changed files with 1402 additions and 0 deletions

22
erpnext/.helmignore Normal file
View File

@ -0,0 +1,22 @@
# 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
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

7
erpnext/Chart.yaml Normal file
View File

@ -0,0 +1,7 @@
apiVersion: v2
appVersion: v13.0.0
description: Kubernetes Helm Chart for the lastest stable ERPNext branch
icon: https://raw.githubusercontent.com/frappe/design/master/logos/logo-2018/erpnext-logo-blue.svg
name: erpnext
type: application
version: 3.0.0

112
erpnext/README.md Normal file
View File

@ -0,0 +1,112 @@
# Frappe / ERPNext
[Frappe](https://frappe.io)/[ERPNext](https://erpnext.com) world's best 100% open source ERP.
ERPNext is a full-featured business management solution that helps SMEs to record all their business transactions in a single system. With ERPNext, SMEs can make informed, fact-based, timely decisions to remain ahead in the competition. It serves as the backbone of a business adding strength, transparency, and control to your growing enterprise.
## TL;DR;
```bash
$ helm repo add frappe https://helm.erpnext.com
$ helm install frappe-bench-0001 --namespace erpnext frappe/erpnext \
--set mariadbHost=mariadb.mariadb.svc.cluster.local \
--set persistence.worker.storageClass=rook-cephfs \
--set persistence.logs.storageClass=rook-cephfs
```
## Introduction
This chart bootstraps a [Frappe/ERPNext](https://github.com/frappe/frappe_docker) deployment on a [Kubernetes](http://kubernetes.io) cluster using the [Helm](https://helm.sh) package manager.
## Prerequisites
- Kubernetes 1.15+
- Helm 3.0+
- PV provisioner support in the underlying infrastructure
- Mariadb host available for access
## Installing the Chart
To install the chart with the release name `frappe-bench-0001`:
```bash
$ helm install frappe-bench-0001 --namespace erpnext frappe/erpnext \
--set mariadbHost=mariadb.mariadb.svc.cluster.local \
--set persistence.worker.storageClass=rook-cephfs \
--set persistence.logs.storageClass=rook-cephfs
```
The command deploys ERPNext on the Kubernetes cluster in the default configuration. The [Parameters](#parameters) section lists the parameters that can be configured during installation.
> **Tip**: List all releases using `helm list`
## Uninstalling the Chart
To uninstall/delete the `frappe-bench-0001` deployment:
```bash
$ helm --namespace erpnext delete frappe-bench-0001
```
The command removes all the Kubernetes components associated with the chart and deletes the release.
## Parameters
The following table lists the configurable parameters of the ERPNext chart and their default values.
| Parameter | Description | Default |
|----------------------------------|--------------------------------------------------------------|---------------------------------|
| `replicaCount` | Replica Count for App Deployments | `1` |
| `nginxImage.repository` | Frappe/ERPNext Nginx Docker image registry | `frappe/erpnext-nginx` |
| `nginxImage.tag` | Frappe/ERPNext Nginx Docker image tag | Latest Stable Release |
| `nginxImage.pullPolicy` | Frappe/ERPNext Nginx Docker image pullPolicy | `IfNotPresent` |
| `pythonImage.repository` | Frappe/ERPNext Python Docker image registry | `frappe/erpnext-worker` |
| `pythonImage.tag` | Frappe/ERPNext Python Docker image tag | Latest Stable Release |
| `pythonImage.pullPolicy` | Frappe/ERPNext Python Docker image pullPolicy | `IfNotPresent` |
| `socketIOImage.repository` | Frappe/ERPNext SocketIO Docker image registry | `frappe/frappe-socketio` |
| `socketIOImage.tag` | Frappe/ERPNext SocketIO Docker image tag | Latest Stable Release |
| `socketIOImage.pullPolicy` | Frappe/ERPNext SocketIO Docker image pullPolicy | `IfNotPresent` |
| `redis.image.repository` | Redis Docker image registry | `bitnami/redis` |
| `redis.image.tag` | Redis Docker image tag | Latest Stable Release |
| `redis.image.pullPolicy` | Redis Docker image pullPolicy | `IfNotPresent` |
| `redis.extraEnv` | Redis Extra Environment Variables | `ALLOW_EMPTY_PASSWORD=true` |
| `frappePyPort` | Frappe/ERPNext Python Gunicorn Worker Port | `8000` |
| `socketIOPort` | Frappe/ERPNext SocketIO Port | `9000` |
| `upstreamRealIPAddress` | Trusted address (or ip range) of upstream proxy servers | `127.0.0.1` |
| `upstreamRealIPRecursive` | Recursive look for upstream proxy server for real IP if `on` | `off` |
| `upstreamRealIPHeader` | Header name sent by your upstream proxy server | `X-Forwarded-For` |
| `mariadbHost` | MariaDB Host to connect (Required) | `nil` |
| `redisQueueHost` | Queue Redis Host to connect (Optional) | `nil` |
| `redisCacheHost` | Cache Redis Host to connect (Optional) | `nil` |
| `redisSocketIOHost` | Socket IO Redis Host to connect (Optional) | `nil` |
| `migrateJob.enable` | Run migrate sites Job after helm install / upgrade | `false` |
| `migrateJob.backup` | Backup before migrate sites Job | `true` |
| `persistence.worker.enable` | Creates PVC with helm release name | `true` |
| `persistence.worker.size` | Creates PVC with size | `8Gi` |
| `persistence.worker.storageClass`| StorageClass with RWX, Required if PVC is created | `nil` |
| `persistence.logs.enable` | Creates PVC for logs volume with helm release name | `true` |
| `persistence.logs.size` | Creates PVC for logs volume with size | `8Gi` |
| `persistence.logs.storageClass` | StorageClass with RWX, Required if PVC is created | `nil` |
| `volumePermissions.enabled` | Enable init container that changes volume permissions in the data directory (for cases where the default k8s `runAsUser` and `fsUser` values do not work) | `false`
The above parameters map to the env variables defined in [frappe_docker](http://github.com/frappe/frappe_docker). For more information please refer to the [frappe_docker](http://github.com/frappe/frappe_docker) images documentation.
Specify each parameter using the `--set key=value[,key=value]` argument to `helm install`. For example,
```bash
$ helm install frappe-bench-0001 --namespace erpnext frappe/erpnext \
--set mariadbHost=mariadb.mariadb.svc.cluster.local \
--set persistence.worker.storageClass=rook-cephfs \
--set persistence.logs.storageClass=rook-cephfs
--set migrateJob.enable=true
```
The above command sets the MariaDB host to `mariadb.mariadb.svc.cluster.local`. Additionally it creates a PVC named with mentioned storageClass `rook-cephfs` and creates a migration job.
Alternatively, a YAML file that specifies the values for the parameters can be provided while installing the chart. For example,
```bash
$ helm install frappe-bench-0001 -f values.yaml erpnext
```

View File

@ -0,0 +1,10 @@
Frappe/ERPNext Release deployed
Release Name: {{ include "erpnext.fullname" . }}
Wait for the pods to start.
To create sites and other resources, refer:
https://helm.erpnext.com/kubernetes-resources
Frequently Asked Questions:
https://helm.erpnext.com/faq

View File

@ -0,0 +1,98 @@
{{/* vim: set filetype=mustache: */}}
{{/*
Expand the name of the chart.
*/}}
{{- define "erpnext.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 "erpnext.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 "erpnext.chart" -}}
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Common labels
*/}}
{{- define "erpnext.labels" -}}
helm.sh/chart: {{ include "erpnext.chart" . }}
{{ include "erpnext.selectorLabels" . }}
{{- if .Chart.AppVersion }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
{{- end }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end -}}
{{/*
Selector labels
*/}}
{{- define "erpnext.selectorLabels" -}}
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end -}}
{{/*
Create the name of the service account to use
*/}}
{{- define "erpnext.serviceAccountName" -}}
{{- if .Values.serviceAccount.create -}}
{{ default (include "erpnext.fullname" .) .Values.serviceAccount.name }}
{{- else -}}
{{ default "default" .Values.serviceAccount.name }}
{{- end -}}
{{- end -}}
{{/*
Create redis host name
*/}}
{{- define "redis.fullname" -}}
{{- printf "%s-%s" .Release.Name "redis" | trunc 63 | trimSuffix "-" -}}
{{- end -}}
{{/*
Gets the mariadb host name
*/}}
{{- define "erpnext.mariadbHost" -}}
{{ .Values.mariadbHost }}
{{- end -}}
{{/*
Gets the redis socketio host name
*/}}
{{- define "erpnext.redisSocketIOHost" -}}
{{ .Values.redisSocketIOHost }}
{{- end -}}
{{/*
Gets the redis queue host name
*/}}
{{- define "erpnext.redisQueueHost" -}}
{{ .Values.redisQueueHost }}
{{- end -}}
{{/*
Gets the redis cache host name
*/}}
{{- define "erpnext.redisCacheHost" -}}
{{ .Values.redisCacheHost }}
{{- end -}}

View File

@ -0,0 +1,166 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-erpnext
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-backend
app.kubernetes.io/instance: {{ .Release.Name }}-backend
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-backend
app.kubernetes.io/instance: {{ .Release.Name }}-backend
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ include "erpnext.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
{{- if and .Values.volumePermissions.enabled .Values.persistence.enabled }}
initContainers:
- name: frappe-bench-ownership
image: quay.io/libpod/alpine:3.2
imagePullPolicy: {{ .Values.nginxImage.pullPolicy }}
command: ['sh', '-c']
args: ['chown -R 1000:1000 /home/frappe/frappe-bench']
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
capabilities:
add: ["CAP_CHOWN"]
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
{{- end }}
containers:
- name: {{ .Chart.Name }}-assets
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.nginxImage.repository }}:{{ .Values.nginxImage.tag }}"
volumeMounts:
- name: assets-cache
mountPath: /assets
- name: sites-dir
mountPath: /var/www/html/sites
imagePullPolicy: {{ .Values.nginxImage.pullPolicy }}
env:
- name: "FRAPPE_PY"
value: "0.0.0.0"
- name: "FRAPPE_PY_PORT"
value: {{ .Values.frappePyPort | quote }}
- name: "FRAPPE_SOCKETIO"
value: {{ template "erpnext.fullname" . }}-socketio
- name: "SOCKETIO_PORT"
value: {{ .Values.socketIOPort | quote }}
{{- if .Values.upstreamRealIPAddress }}
- name: "UPSTREAM_REAL_IP_ADDRESS"
value: "{{ .Values.upstreamRealIPAddress }}"
{{- end }}
{{- if .Values.upstreamRealIPRecursive }}
- name: "UPSTREAM_REAL_IP_RECURSIVE"
value: {{ .Values.upstreamRealIPRecursive }}
{{- end }}
{{- if .Values.upstreamRealIPHeader }}
- name: "UPSTREAM_REAL_IP_HEADER"
value: {{ .Values.upstreamRealIPHeader }}
{{- end }}
ports:
- name: http
containerPort: 80
protocol: TCP
resources:
{{- toYaml .Values.resources | nindent 12 }}
- name: {{ .Chart.Name }}-python
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
volumeMounts:
- name: assets-cache
mountPath: /home/frappe/frappe-bench/sites/assets
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
env:
- name: "MARIADB_HOST"
value: {{ required "A valid .Values.mariadbHost entry required!" (include "erpnext.mariadbHost" .) }}
- name: "REDIS_QUEUE"
{{- if eq (include "erpnext.redisQueueHost" .) "" }}
value: {{ include "erpnext.fullname" . }}-redis-queue:{{ .Values.redisQueueService.port }}
{{- else }}
value: {{ include "erpnext.redisQueueHost" . }}
{{- end }}
- name: "REDIS_CACHE"
{{- if eq (include "erpnext.redisCacheHost" .) "" }}
value: {{ include "erpnext.fullname" . }}-redis-cache:{{ .Values.redisCacheService.port }}
{{- else }}
value: {{ include "erpnext.redisCacheHost" . }}
{{- end }}
- name: "REDIS_SOCKETIO"
{{- if eq (include "erpnext.redisSocketIOHost" .) "" }}
value: {{ include "erpnext.fullname" . }}-redis-socketio:{{ .Values.redisSocketIOService.port }}
{{- else }}
value: {{ include "erpnext.redisSocketIOHost" . }}
{{- end }}
- name: "SOCKETIO_PORT"
value: {{ .Values.socketIOPort | quote }}
livenessProbe:
tcpSocket:
port: {{ .Values.frappePyPort }}
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: {{ .Values.frappePyPort }}
initialDelaySeconds: 5
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: assets-cache
emptyDir: {}
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- 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 }}

View File

@ -0,0 +1,51 @@
{{- if eq (include "erpnext.redisCacheHost" .) ""}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-redis-cache
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-cache
app.kubernetes.io/instance: {{ .Release.Name }}-redis-cache
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-cache
app.kubernetes.io/instance: {{ .Release.Name }}-redis-cache
spec:
serviceAccountName: {{ include "erpnext.serviceAccountName" . }}-redis
containers:
- name: master
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
imagePullPolicy: {{ .Values.redis.image.pullPolicy }}
command: ["redis-server"]
args:
- "--bind 0.0.0.0"
- "--maxmemory 292mb"
- "--maxmemory-policy allkeys-lru"
- "--appendonly no"
- "--save \"\""
resources: {}
{{- if .Values.redis.extraEnv }}
env:
{{- if .Values.redis.extraEnv }}
{{- toYaml .Values.redis.extraEnv | nindent 12 }}
{{- end }}
{{- end }}
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
{{- end }}

View File

@ -0,0 +1,46 @@
{{- if eq (include "erpnext.redisQueueHost" .) ""}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-redis-queue
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-queue
app.kubernetes.io/instance: {{ .Release.Name }}-redis-queue
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-queue
app.kubernetes.io/instance: {{ .Release.Name }}-redis-queue
spec:
serviceAccountName: {{ include "erpnext.serviceAccountName" . }}-redis
containers:
- name: master
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
imagePullPolicy: {{ .Values.redis.image.pullPolicy }}
command: ["redis-server"]
args: ["--bind 0.0.0.0"]
resources:
{{- if .Values.redis.extraEnv }}
env:
{{- if .Values.redis.extraEnv }}
{{- toYaml .Values.redis.extraEnv | nindent 12 }}
{{- end }}
{{- end }}
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
{{- end }}

View File

@ -0,0 +1,46 @@
{{- if eq (include "erpnext.redisSocketIOHost" .) ""}}
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-redis-socketio
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-socketio
app.kubernetes.io/instance: {{ .Release.Name }}-redis-socketio
replicas: 1
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-socketio
app.kubernetes.io/instance: {{ .Release.Name }}-redis-socketio
spec:
serviceAccountName: {{ include "erpnext.serviceAccountName" . }}-redis
containers:
- name: master
image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}"
imagePullPolicy: {{ .Values.redis.image.pullPolicy }}
command: ["redis-server"]
args: ["--bind 0.0.0.0"]
resources:
{{- if .Values.redis.extraEnv }}
env:
{{- if .Values.redis.extraEnv }}
{{- toYaml .Values.redis.extraEnv | nindent 12 }}
{{- end }}
{{- end }}
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
{{- end }}

View File

@ -0,0 +1,96 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-scheduler
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
replicas: 1
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "erpnext.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
args: ["schedule"]
livenessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- 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 }}

View File

@ -0,0 +1,89 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-socketio
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-socketio
app.kubernetes.io/instance: {{ .Release.Name }}-socketio
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-socketio
app.kubernetes.io/instance: {{ .Release.Name }}-socketio
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "erpnext.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.socketIOImage.repository }}:{{ .Values.socketIOImage.tag }}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
imagePullPolicy: {{ .Values.socketIOImage.pullPolicy }}
ports:
- name: http
containerPort: 9000
protocol: TCP
livenessProbe:
tcpSocket:
port: {{ .Values.socketIOPort }}
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: {{ .Values.socketIOPort }}
initialDelaySeconds: 5
periodSeconds: 10
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- 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 }}

View File

@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-worker-d
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "erpnext.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
args: ["worker"]
env:
- name: "WORKER_TYPE"
value: "default"
livenessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- 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 }}

View File

@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-worker-l
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "erpnext.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
args: ["worker"]
env:
- name: "WORKER_TYPE"
value: "long"
livenessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- 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 }}

View File

@ -0,0 +1,99 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-worker-s
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
replicas: {{ .Values.replicaCount }}
selector:
matchLabels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
template:
metadata:
labels:
app.kubernetes.io/name: {{ include "erpnext.name" . }}
app.kubernetes.io/instance: {{ .Release.Name }}
spec:
{{- with .Values.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
serviceAccountName: {{ template "erpnext.serviceAccountName" . }}
securityContext:
{{- toYaml .Values.podSecurityContext | nindent 8 }}
containers:
- name: {{ .Chart.Name }}
securityContext:
{{- toYaml .Values.securityContext | nindent 12 }}
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: logs
mountPath: /home/frappe/frappe-bench/logs
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
args: ["worker"]
env:
- name: "WORKER_TYPE"
value: "short"
livenessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "healthcheck.sh"
{{- if and .Values.postgresHost .Values.postgresPort }}
- "-p"
- "{{ .Values.postgresHost }}:{{ .Values.postgresPort }}"
{{- end }}
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- 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 }}

View File

@ -0,0 +1,91 @@
{{- if .Values.migrateJob.enable }}
apiVersion: batch/v1
kind: Job
metadata:
name: migrate-sites-{{ template "erpnext.fullname" . }}-{{ date "20060102150405" .Release.Now }}
spec:
backoffLimit: 1
template:
spec:
serviceAccountName: {{ template "erpnext.serviceAccountName" $ }}
securityContext:
{{- toYaml $.Values.podSecurityContext | nindent 8 }}
initContainers:
- name: set-maintenance-mode
image: stedolan/jq
imagePullPolicy: IfNotPresent
command: ["/bin/bash", "-c"]
securityContext:
runAsUser: 1000 # same as erpnext user
runAsGroup: 1000
args:
- cp /data/common_site_config.json /data/temp.json;
jq -r '.maintenance_mode=1 | .pause_scheduler=1' /data/temp.json > /data/common_site_config.json;
volumeMounts:
- name: sites-dir
mountPath: "/data"
- name: populate-assets
image: "{{ .Values.nginxImage.repository }}:{{ .Values.nginxImage.tag }}"
command: ["/bin/bash", "-c"]
args:
- "rsync -a --delete /var/www/html/assets/frappe /assets"
volumeMounts:
- name: assets-cache
mountPath: /assets
{{- if .Values.migrateJob.backup }}
- name: backup
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
args: ["backup"]
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
securityContext:
{{- toYaml $.Values.securityContext | nindent 12 }}
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
{{- end }}
containers:
- name: migrate
image: "{{ .Values.pythonImage.repository }}:{{ .Values.pythonImage.tag }}"
args: ["migrate"]
env:
- name: "MAINTENANCE_MODE"
value: "1"
securityContext:
{{- toYaml $.Values.securityContext | nindent 12 }}
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
- name: assets-cache
mountPath: /home/frappe/frappe-bench/sites/assets
- name: logs
mountPath: /home/frappe/frappe-bench/logs
restartPolicy: Never
volumes:
- name: assets-cache
emptyDir: {}
- name: sites-dir
{{- if .Values.persistence.worker.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.worker.existingClaim }}
claimName: {{ .Values.persistence.worker.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
- name: logs
{{- if .Values.persistence.logs.enabled }}
persistentVolumeClaim:
{{- if .Values.persistence.logs.existingClaim }}
claimName: {{ .Values.persistence.logs.existingClaim }}
{{- else }}
claimName: {{ template "erpnext.fullname" . }}-logs
{{- end }}
readOnly: false
{{- else }}
emptyDir: {}
{{- end }}
{{- end }}

View File

@ -0,0 +1,18 @@
{{- if and .Values.persistence.worker.enabled (not .Values.persistence.worker.existingClaim) }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
labels:
app: {{ template "erpnext.name" . }}
chart: {{ template "erpnext.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "erpnext.fullname" . }}
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.persistence.worker.size | quote }}
storageClassName: {{ required "A valid .Values.persistence.worker.storageClass entry required!" .Values.persistence.worker.storageClass }}
{{- end }}

View File

@ -0,0 +1,18 @@
{{- if and .Values.persistence.logs.enabled (not .Values.persistence.logs.existingClaim) }}
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
labels:
app: {{ template "erpnext.name" . }}
chart: {{ template "erpnext.chart" . }}
heritage: {{ .Release.Service }}
release: {{ .Release.Name }}
name: {{ template "erpnext.fullname" . }}-logs
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: {{ .Values.persistence.logs.size | quote }}
storageClassName: {{ required "A valid .Values.persistence.logs.storageClass entry required!" .Values.persistence.logs.storageClass }}
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if eq (include "erpnext.redisCacheHost" .) ""}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "erpnext.fullname" . }}-redis-cache
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
type: {{ .Values.redisCacheService.type }}
ports:
- port: {{ .Values.redisCacheService.port }}
targetPort: 6379
selector:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-cache
app.kubernetes.io/instance: {{ .Release.Name }}-redis-cache
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if eq (include "erpnext.redisQueueHost" .) ""}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "erpnext.fullname" . }}-redis-queue
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
type: {{ .Values.redisQueueService.type }}
ports:
- port: {{ .Values.redisQueueService.port }}
targetPort: 6379
selector:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-queue
app.kubernetes.io/instance: {{ .Release.Name }}-redis-queue
{{- end }}

View File

@ -0,0 +1,16 @@
{{- if eq (include "erpnext.redisSocketIOHost" .) ""}}
apiVersion: v1
kind: Service
metadata:
name: {{ include "erpnext.fullname" . }}-redis-socketio
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
type: {{ .Values.redisSocketIOService.type }}
ports:
- port: {{ .Values.redisSocketIOService.port }}
targetPort: 6379
selector:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-redis-socketio
app.kubernetes.io/instance: {{ .Release.Name }}-redis-socketio
{{- end }}

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "erpnext.fullname" . }}
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
type: {{ .Values.service.type }}
ports:
- port: {{ .Values.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-backend
app.kubernetes.io/instance: {{ .Release.Name }}-backend

View File

@ -0,0 +1,16 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "erpnext.serviceAccountName" . }}
labels:
{{ include "erpnext.labels" . | nindent 4 }}
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "erpnext.serviceAccountName" . }}-redis
labels:
{{- include "erpnext.labels" . | nindent 4 }}
app.kubernetes.io/name: erpnext-redis
{{- end -}}

View File

@ -0,0 +1,16 @@
apiVersion: v1
kind: Service
metadata:
name: {{ include "erpnext.fullname" . }}-socketio
labels:
{{- include "erpnext.labels" . | nindent 4 }}
spec:
type: {{ .Values.socketIOService.type }}
ports:
- port: {{ .Values.socketIOService.port }}
targetPort: http
protocol: TCP
name: http
selector:
app.kubernetes.io/name: {{ include "erpnext.name" . }}-socketio
app.kubernetes.io/instance: {{ .Release.Name }}-socketio

View File

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "erpnext.fullname" . }}-test-connection"
labels:
{{ include "erpnext.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test-success
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "erpnext.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

124
erpnext/values.yaml Normal file
View File

@ -0,0 +1,124 @@
# Default values for erpnext.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.
replicaCount: 1
nginxImage:
repository: frappe/erpnext-nginx
tag: v13.0.0
pullPolicy: IfNotPresent
pythonImage:
repository: frappe/erpnext-worker
tag: v13.0.0
pullPolicy: IfNotPresent
socketIOImage:
repository: frappe/frappe-socketio
tag: v13.0.0
pullPolicy: IfNotPresent
redis:
image:
repository: bitnami/redis
tag: 5.0.10-debian-10-r105
pullPolicy: IfNotPresent
extraEnv:
- name: ALLOW_EMPTY_PASSWORD
value: "yes"
# Asset Image Env Variables
frappePyPort: "8000"
socketIOPort: "9000"
# upstreamRealIPAddress: "127.0.0.1"
# upstreamRealIPRecursive: "off"
# upstreamRealIPHeader: "X-Forwarded-For"
# Python Image Env Variables
# mariadbHost: "mariadb.mariadb.svc.cluster.local"
redisQueueHost: ""
redisCacheHost: ""
redisSocketIOHost: ""
# PostgreSQL related variables
postgresHost: ""
postgresPort: ""
migrateJob:
# Set this to true to run migrate as part of helm install/upgrade
enable: false
backup: true
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
serviceAccount:
# Specifies whether a service account should be created
create: true
podSecurityContext:
supplementalGroups: [1000]
securityContext: {}
# capabilities:
# drop:
# - ALL
# readOnlyRootFilesystem: true
# runAsNonRoot: true
# runAsUser: 1000
service:
type: ClusterIP
port: 80
# Additional Services
socketIOService:
type: ClusterIP
port: 9000
redisSocketIOService:
type: ClusterIP
port: 11000
redisQueueService:
type: ClusterIP
port: 12000
redisCacheService:
type: ClusterIP
port: 13000
persistence:
worker:
enabled: true
# existingClaim: ""
size: 8Gi
# storageClass: "nfs"
logs:
enabled: true
# existingClaim: ""
size: 8Gi
# storageClass: "nfs"
volumePermissions:
enabled: no
resources: {}
# 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
nodeSelector: {}
tolerations: []
affinity: {}