feat: kubernetes installation

helm chart for erpnext
job resources to create, backup, migrate sites
This commit is contained in:
Revant Nandgaonkar 2020-03-07 22:32:57 +05:30
parent 7a38666a84
commit 2162c63a48
34 changed files with 1161 additions and 2 deletions

View file

@ -196,7 +196,7 @@ docker exec -it \
-e "DB_ROOT_USER=$DB_ROOT_USER" \
-e "MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD" \
-e "ADMIN_PASSWORD=$ADMIN_PASSWORD" \
-e "INSTALL_APPS='erpnext'" \
-e "INSTALL_APPS=erpnext" \
<project-name>_erpnext-python_1 docker-entrypoint.sh new
```
@ -206,7 +206,7 @@ Environment Variables needed:
- `DB_ROOT_USER`: MariaDB Root user. The user that can create databases.
- `MYSQL_ROOT_PASSWORD`: In case of mariadb docker container use the one set in `MYSQL_ROOT_PASSWORD` in previous steps. In case of managed database use appropriate password.
- `ADMIN_PASSWORD`: set the administrator password for new site.
- `INSTALL_APPS='erpnext'`: available only in erpnext-worker and erpnext containers (or other containers with custom apps). Installs ERPNext (and/or the specified apps, comma-delinieated) on this new site.
- `INSTALL_APPS=erpnext`: available only in erpnext-worker and erpnext containers (or other containers with custom apps). Installs ERPNext (and/or the specified apps, comma-delinieated) on this new site.
- `FORCE=1`: is optional variable which force installs the same site.
#### Backup Sites

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/

View file

@ -0,0 +1,21 @@
apiVersion: v2
name: erpnext
description: A Helm chart for Kubernetes
# A chart can be either an 'application' or a 'library' chart.
#
# Application charts are a collection of templates that can be packaged into versioned archives
# to be deployed.
#
# Library charts provide useful utilities or functions for the chart developer. They're included as
# a dependency of application charts to inject those utilities and functions into the rendering
# pipeline. Library charts do not define any templates and therefore cannot be deployed.
type: application
# This is the chart version. This version number should be incremented each time you make changes
# to the chart and its templates, including the app version.
version: 0.1.0
# This is the version number of the application being deployed. This version number should be
# incremented each time you make changes to the application.
appVersion: 1.16.0

View file

@ -0,0 +1,3 @@
1. Get the application URL by running these commands:
ERPNext Bench deployed

View file

@ -0,0 +1,70 @@
{{/* 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 -}}

View file

@ -0,0 +1,107 @@
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 }}
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_PYERPNEXT_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 }}
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
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
env:
{{ if .Values.runAsRoot }}
- name: "RUN_AS_ROOT"
value: "1"
{{ end }}
- name: "MARIADB_HOST"
value: {{ .Values.mariadbHost }}
- name: "REDIS_QUEUE"
value: {{ include "erpnext.fullname" . }}-redis-queue:{{ .Values.redisQueueService.port }}
- name: "REDIS_CACHE"
value: {{ include "erpnext.fullname" . }}-redis-cache:{{ .Values.redisCacheService.port }}
- name: "REDIS_SOCKETIO"
value: {{ include "erpnext.fullname" . }}-redis-socketio:{{ .Values.redisSocketIOService.port }}
- 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
persistentVolumeClaim:
claimName: {{ template "erpnext.fullname" . }}
readOnly: false
{{- 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,40 @@
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:
containers:
- name: master
image: redis:5-alpine
command: ["redis-server"]
args:
- "--maxmemory 292mb"
- "--maxmemory-policy allkeys-lru"
- "--appendonly no"
- "--save \"\""
resources: {}
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10

View file

@ -0,0 +1,34 @@
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:
containers:
- name: master
image: redis:5-alpine
resources:
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10

View file

@ -0,0 +1,34 @@
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:
containers:
- name: master
image: redis:5-alpine
resources:
ports:
- containerPort: 6379
livenessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
tcpSocket:
port: 6379
initialDelaySeconds: 5
periodSeconds: 10

View file

@ -0,0 +1,74 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "erpnext.fullname" . }}-scheduler
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
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
command: ["docker-entrypoint.sh"]
args: ["schedule"]
{{ if .Values.runAsRoot }}
env:
- name: "RUN_AS_ROOT"
value: "1"
{{ end }}
livenessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: {{ template "erpnext.fullname" . }}
readOnly: false
{{- 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,67 @@
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
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
persistentVolumeClaim:
claimName: {{ template "erpnext.fullname" . }}
readOnly: false
{{- 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,76 @@
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
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
command: ["docker-entrypoint.sh"]
args: ["worker"]
env:
{{ if .Values.runAsRoot }}
- name: "RUN_AS_ROOT"
value: "1"
{{ end }}
- name: "WORKER_TYPE"
value: "default"
livenessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: {{ template "erpnext.fullname" . }}
readOnly: false
{{- 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,76 @@
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
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
command: ["docker-entrypoint.sh"]
args: ["worker"]
env:
- name: "WORKER_TYPE"
value: "long"
{{ if .Values.runAsRoot }}
- name: "RUN_AS_ROOT"
value: "1"
{{ end }}
livenessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: {{ template "erpnext.fullname" . }}
readOnly: false
{{- 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,76 @@
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
imagePullPolicy: {{ .Values.pythonImage.pullPolicy }}
command: ["docker-entrypoint.sh"]
args: ["worker"]
env:
- name: "WORKER_TYPE"
value: "short"
{{ if .Values.runAsRoot }}
- name: "RUN_AS_ROOT"
value: "1"
{{ end }}
livenessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
readinessProbe:
exec:
command:
- "docker-entrypoint.sh"
- "doctor"
initialDelaySeconds: 15
periodSeconds: 5
resources:
{{- toYaml .Values.resources | nindent 12 }}
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: {{ template "erpnext.fullname" . }}
readOnly: false
{{- 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,18 @@
{{- if and .Values.persistence.enabled (not .Values.persistence.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:
- ReadWriteMany
resources:
requests:
storage: {{ .Values.persistence.size | quote }}
storageClassName: {{ .Values.persistence.storageClass }}
{{- end }}

View file

@ -0,0 +1,14 @@
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

View file

@ -0,0 +1,14 @@
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

View file

@ -0,0 +1,14 @@
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

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,8 @@
{{- if .Values.serviceAccount.create -}}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "erpnext.serviceAccountName" . }}
labels:
{{ include "erpnext.labels" . | nindent 4 }}
{{- 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

View file

@ -0,0 +1,99 @@
# 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: edge
pullPolicy: Always
pythonImage:
repository: frappe/erpnext-worker
tag: edge
pullPolicy: Always
socketIOImage:
repository: frappe/frappe-socketio
tag: edge
pullPolicy: Always
# Asset Image Env Variables
frappePyPort: "8000"
socketIOPort: "9000"
# Python Image Env Variables
mariadbHost: "mariadb.mariadb.svc.cluster.local"
imagePullSecrets: []
nameOverride: ""
fullnameOverride: ""
# Run workers, scheduler and web as root
runAsRoot: false
serviceAccount:
# Specifies whether a service account should be created
create: true
# The name of the service account to use.
# If not set and create is true, a name is generated using the fullname template
# name:
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:
enabled: true
# existingClaim: ""
size: 10Gi
# storageClass: "csi-s3"
# storageClass: "standard"
storageClass: "nfs"
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
nodeSelector: {}
tolerations: []
affinity: {}

View file

@ -0,0 +1 @@
*.yaml

View file

@ -0,0 +1,30 @@
apiVersion: batch/v1
kind: Job
metadata:
name: backup-site-${SITE_NAME}-${TIMESTAMP}
spec:
backoffLimit: 1
template:
spec:
securityContext:
supplementalGroups: [1000]
containers:
- name: erpnext
image: castlecraft/erpnext-python:${VERSION}
command: ["docker-entrypoint.sh"]
args: ["backup"]
imagePullPolicy: Always
env:
- name: "WITH_FILES"
value: "1"
- name: "SITES"
value: "${SITE_NAME}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
restartPolicy: Never
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: ${SITES_PVC}
readOnly: false

View file

@ -0,0 +1,23 @@
#!/bin/bash
set -e
if [[ -z "$SITE_NAME" ]]; then
echo "SITE_NAME is not set"
exit 1
fi
if [[ -z "$SITES_PVC" ]]; then
echo "SITES_PVC is not set"
exit 1
fi
if [[ -z "$VERSION" ]]; then
echo "VERSION is not set"
exit 1
fi
export TIMESTAMP=$(date +%s)
envsubst '${TIMESTAMP}
${SITE_NAME}
${VERSION}
${SITES_PVC}' \
< ./backupsitejob.yaml.template > backupsitejob-$SITE_NAME-$TIMESTAMP.yaml

View file

@ -0,0 +1,10 @@
#!/bin/bash
set -e
if [[ -z "$BASE64_PASSWORD" ]]; then
echo "BASE64_PASSWORD is not set"
exit 1
fi
envsubst '${BASE64_PASSWORD}' \
< ./mariadbrootpasswordsecret.yaml.template > ./mariadbrootpasswordsecret.yaml

View file

@ -0,0 +1,23 @@
#!/bin/bash
set -e
if [[ -z "$SITE_NAME" ]]; then
echo "SITE_NAME is not set"
exit 1
fi
if [[ -z "$SITES_PVC" ]]; then
echo "SITES_PVC is not set"
exit 1
fi
if [[ -z "$VERSION" ]]; then
echo "VERSION is not set"
exit 1
fi
export TIMESTAMP=$(date +%s)
envsubst '${TIMESTAMP}
${SITE_NAME}
${VERSION}
${SITES_PVC}' \
< ./migratesitejob.yaml.template > migratesitejob-$SITE_NAME-$TIMESTAMP.yaml

View file

@ -0,0 +1,25 @@
#!/bin/bash
set -e
if [[ -z "$INGRESS_NAME" ]]; then
echo "INGRESS_NAME is not set"
exit 1
fi
if [[ -z "$ERPNEXT_SERVICE" ]]; then
echo "ERPNEXT_SERVICE is not set"
exit 1
fi
if [[ -z "$SITE_NAME" ]]; then
echo "SITE_NAME is not set"
exit 1
fi
if [[ -z "$TLS_SECRET_NAME" ]]; then
echo "TLS_SECRET_NAME is not set"
exit 1
fi
envsubst '${INGRESS_NAME}
${ERPNEXT_SERVICE}
${SITE_NAME}
${TLS_SECRET_NAME}' \
< ./newsiteingress.yaml.template > newsiteingress_$SITE_NAME.yaml

View file

@ -0,0 +1,33 @@
#!/bin/bash
set -e
if [[ -z "$SITE_NAME" ]]; then
echo "SITE_NAME is not set"
exit 1
fi
if [[ -z "$DB_ROOT_USER" ]]; then
echo "DB_ROOT_USER is not set"
exit 1
fi
if [[ -z "$ADMIN_PASSWORD" ]]; then
echo "ADMIN_PASSWORD is not set"
exit 1
fi
if [[ -z "$SITES_PVC" ]]; then
echo "SITES_PVC is not set"
exit 1
fi
if [[ -z "$VERSION" ]]; then
echo "VERSION is not set"
exit 1
fi
export TIMESTAMP=$(date +%s)
envsubst '${SITE_NAME}
${DB_ROOT_USER}
${ADMIN_PASSWORD}
${SITES_PVC}
${SITE_NAME}
${VERSION}' \
< ./newsitejob.yaml.template > newsitejob-$SITE_NAME-$TIMESTAMP.yaml

View file

@ -0,0 +1,7 @@
apiVersion: v1
data:
password: ${BASE64_PASSWORD}
kind: Secret
metadata:
name: mariadb-root-password
type: Opaque

View file

@ -0,0 +1,28 @@
apiVersion: batch/v1
kind: Job
metadata:
name: migrate-site-${SITE_NAME}-${TIMESTAMP}
spec:
backoffLimit: 1
template:
spec:
securityContext:
supplementalGroups: [1000]
containers:
- name: erpnext
image: castlecraft/erpnext-python:${VERSION}
command: ["docker-entrypoint.sh"]
args: ["migrate"]
imagePullPolicy: Always
env:
- name: "SITES"
value: "${SITE_NAME}"
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
restartPolicy: Never
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: ${SITES_PVC}
readOnly: false

View file

@ -0,0 +1,26 @@
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
name: ${INGRESS_NAME}
# Optional Labels
labels:
app.kubernetes.io/instance: ${ERPNEXT_SERVICE}
annotations:
# required for cert-manager letsencrypt
cert-manager.io/cluster-issuer: letsencrypt-prod
# other annotations as needed, e.g timestamp
kubernetes.io/ingress.class: nginx
kubernetes.io/tls-acme: "true"
spec:
rules:
- host: ${SITE_NAME}
http:
paths:
- backend:
serviceName: ${ERPNEXT_SERVICE}
servicePort: 80
path: /
tls:
- hosts:
- ${SITE_NAME}
secretName: ${TLS_SECRET_NAME}

View file

@ -0,0 +1,39 @@
apiVersion: batch/v1
kind: Job
metadata:
name: create-new-site-${SITE_NAME}
spec:
backoffLimit: 1
template:
spec:
securityContext:
supplementalGroups: [1000]
containers:
- name: erpnext
image: castlecraft/erpnext-python:${VERSION}
command: ["docker-entrypoint.sh"]
args: ["new"]
imagePullPolicy: Always
volumeMounts:
- name: sites-dir
mountPath: /home/frappe/frappe-bench/sites
env:
- name: "SITE_NAME"
value: ${SITE_NAME}
- name: "DB_ROOT_USER"
value: ${DB_ROOT_USER}
- name: "DB_ROOT_PASSWORD"
valueFrom:
secretKeyRef:
key: password
name: mariadb-root-password
- name: "ADMIN_PASSWORD"
value: ${ADMIN_PASSWORD}
- name: "INSTALL_APPS"
value: "erpnext"
restartPolicy: Never
volumes:
- name: sites-dir
persistentVolumeClaim:
claimName: ${SITES_PVC}
readOnly: false