diff --git a/.gitignore b/.gitignore index 2e0fba0..caa9b93 100644 --- a/.gitignore +++ b/.gitignore @@ -33,3 +33,5 @@ data *.iml *.env *.tgz + +values.yaml diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..a7387da --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +deployment/helm/meli-chart/**/*.yaml \ No newline at end of file diff --git a/deployment/helm/meli-chart/Chart.yaml b/deployment/helm/meli-chart/Chart.yaml new file mode 100644 index 0000000..1c833e7 --- /dev/null +++ b/deployment/helm/meli-chart/Chart.yaml @@ -0,0 +1,14 @@ +apiVersion: v2 +name: meli +description: A server for deploying static web sites + +# This is a chart for an application +type: application + +# The version of this chart is automatically filled in by rsci. It will +# be a semantic version compatible with (https://semver.org/) +version: 1.0.0-beta.24 + +# Our application version will mirror the chart version except we will +# leave off the semantic version if it is a work in progress. +appVersion: 1.0.0-beta.24 diff --git a/deployment/helm/meli-chart/templates/NOTES.txt b/deployment/helm/meli-chart/templates/NOTES.txt new file mode 100644 index 0000000..105c348 --- /dev/null +++ b/deployment/helm/meli-chart/templates/NOTES.txt @@ -0,0 +1,17 @@ +This will configure the Meli admin server to run at: + +https://{{ .Values.ingress.domain }} + +It will also direct `cert-manager` to issue certificates for: + +https://*.{{ .Values.ingress.domain }} +{{ range $index, $site := .Values.ingress.sites }} +https://*.{{ $site }}.{{ $.Values.ingress.domain }} +{{ end }} + +The Meli deployment will pick up any additional environment variables +from the secret `deployment-env`. This is where you should put any +"secrets" like authentication client secrets, passwords, etc. You are +also free to put any other less confidential information in there as well. +But, at a minimum, it is where you should put authentication related +configuration variables like `MELI_PASSWORD`, or `MELI_GITLAB_*`. diff --git a/deployment/helm/meli-chart/templates/_helpers.tpl b/deployment/helm/meli-chart/templates/_helpers.tpl new file mode 100644 index 0000000..b6d7df1 --- /dev/null +++ b/deployment/helm/meli-chart/templates/_helpers.tpl @@ -0,0 +1,63 @@ + +{{/* +Expand the name of the chart. +*/}} +{{- define "helper.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 "helper.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 "helper.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "helper.labels" -}} +helm.sh/chart: {{ include "helper.chart" . }} +{{ include "helper.selectorLabels" . }} +{{- if .Chart.AppVersion }} +app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} +{{- end }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "helper.selectorLabels" -}} +app.kubernetes.io/name: {{ include "helper.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "helper.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "helper.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} diff --git a/deployment/helm/meli-chart/templates/deployment.yaml b/deployment/helm/meli-chart/templates/deployment.yaml new file mode 100644 index 0000000..653033b --- /dev/null +++ b/deployment/helm/meli-chart/templates/deployment.yaml @@ -0,0 +1,118 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: meli-app + labels: + {{- include "helper.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "helper.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "helper.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + containers: + - name: meli + image: "{{ .Values.image }}:{{ .Values.tag}}" + envFrom: + - secretRef: + name: deployment-env + env: + - name: MELI_URL + value: {{ printf "https://%s" .Values.ingress.domain | quote }} + - name: MELI_USER + value: {{ .Values.user | quote }} + - name: MELI_HTTPS_AUTO + value: "false" + - name: MELI_MONGO_HOST + value: {{ .Values.mongo.host | quote }} + - name: MELI_MONGO_PORT + value: {{ .Values.mongo.port | quote }} + - name: MELI_MAX_ORGS + value: {{ .Values.maxorgs | quote }} + - name: MELI_MONGO_USER + value: {{ .Values.mongo.user | quote }} + - name: MELI_MONGO_DB + value: {{ .Values.mongo.db | quote }} + imagePullPolicy: {{ .Values.pullPolicy }} + ports: + - name: http + containerPort: 80 + protocol: TCP + - name: https + containerPort: 443 + protocol: TCP + - name: api + containerPort: 3001 + protocol: TCP + - name: admin + containerPort: 2019 + protocol: TCP + # In Work - Docker File needs to be updated + #securityContext: + # runAsUser: 1001 + volumes: null + resources: + requests: + cpu: 200m + memory: 256Mi + #limits: + # cpu500m + volumeMounts: + - name: data + mountPath: /data + subPath: data + - name: config + mountPath: /config + subPath: config + - name: sites + mountPath: /sites + subPath: sites + livenessProbe: + httpGet: + path: / + port: http + scheme: HTTP + httpHeaders: + - name: Host + value: {{ .Values.ingress.domain }} + initialDelaySeconds: 60 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + httpGet: + path: / + port: http + scheme: HTTP + httpHeaders: + - name: Host + value: {{ .Values.ingress.domain }} + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + volumes: + - name: data + persistentVolumeClaim: + claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-data + - name: config + persistentVolumeClaim: + claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-config + - name: sites + persistentVolumeClaim: + claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-sites + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + #securityContext: + # fsGroup: 1001 diff --git a/deployment/helm/meli-chart/templates/ingress.yaml b/deployment/helm/meli-chart/templates/ingress.yaml new file mode 100644 index 0000000..f32f035 --- /dev/null +++ b/deployment/helm/meli-chart/templates/ingress.yaml @@ -0,0 +1,68 @@ +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: ingress + labels: + run: meli-svc + annotations: + cert-manager.io/cluster-issuer: {{ .Values.ingress.certificateIssuer | quote }} + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/connection-proxy-header: "keep-alive" + # This is useful if we every want to map hosts outside the domain to the meli server + # nginx.ingress.kubernetes.io/upstream-vhost: {{ printf "%s" .Values.ingress.domain | quote }} + nginx.ingress.kubernetes.io/send-timeout: "36000" + nginx.ingress.kubernetes.io/proxy-connect-timeout: "36000" + nginx.ingress.kubernetes.io/proxy-read-timeout: "36000" + # This value should match the value in the deployment + nginx.ingress.kubernetes.io/proxy-body-size: "100m" +spec: + ingressClassName: nginx + + # NB - The order of these rules MATTERS + rules: + # First, check if this is the bare domain. If so, it will + # be interpreted by Meli as a request for the admin pages + - host: {{ .Values.ingress.domain | quote }} + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: meli-svc + port: + number: 80 + # Now check the wildcard matches. Ultimately, they get routed + # the same, but the host pattern is different. + - host: "*.{{ .Values.ingress.domain }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: meli-svc + port: + number: 80 + # Now check the wildcard matches. Ultimately, they get routed + # the same, but the host pattern is different. + {{- range $index, $site := .Values.ingress.sites }} + - host: "*.{{ $site }}.{{ $.Values.ingress.domain }}" + http: + paths: + - path: / + pathType: Prefix + backend: + service: + name: meli-svc + port: + number: 80 + {{- end }} + tls: + - hosts: + - {{ .Values.ingress.domain | quote }} + - "*.{{ .Values.ingress.domain }}" + {{- range $index, $site := .Values.ingress.sites }} + - "*.{{ $site }}.{{ $.Values.ingress.domain }}" + {{- end }} + secretName: {{ .Values.ingress.tlsSecret }} diff --git a/deployment/helm/meli-chart/templates/mongo-deployment.yaml b/deployment/helm/meli-chart/templates/mongo-deployment.yaml new file mode 100644 index 0000000..76aa268 --- /dev/null +++ b/deployment/helm/meli-chart/templates/mongo-deployment.yaml @@ -0,0 +1,97 @@ +{{- if .Values.mongo.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: mongo + labels: + {{- include "helper.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + app.kubernetes.io/name: {{ include "helper.name" . }}-mongo + app.kubernetes.io/instance: {{ .Release.Name }} + template: + metadata: + labels: + app.kubernetes.io/name: {{ include "helper.name" . }}-mongo + app.kubernetes.io/instance: {{ .Release.Name }} + spec: + containers: + - image: bitnami/mongodb + imagePullPolicy: IfNotPresent + name: mongo + securityContext: + runAsUser: 1001 + runAsNonRoot: true + ports: + - name: mongo-port + containerPort: {{ .Values.mongo.port }} + protocol: TCP + env: + - name: MONGODB_USERNAME + value: {{ .Values.mongo.user | quote }} + - name: MONGODB_PASSWORD + valueFrom: + secretKeyRef: + name: deployment-env + key: MELI_MONGO_PASSWORD + - name: MONGODB_DATABASE + value: {{ .Values.mongo.db | quote }} + - name: MONGODB_ROOT_PASSWORD + valueFrom: + secretKeyRef: + name: deployment-env + key: MELI_ROOT_MONGO_PASSWORD + - name: BITNAMI_DEBUG + value: "false" + resources: + requests: + cpu: {{ .Values.resources.mongo.cpu }} + memory: {{ .Values.resources.mongo.memory }} + #limits: + # cpu500m + volumeMounts: + - name: data-db + mountPath: /bitnami/mongodb + subPath: mongodb + livenessProbe: + exec: + command: + - mongo + - '--disableImplicitSessions' + - '--eval' + - db.adminCommand('ping') + initialDelaySeconds: 30 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + readinessProbe: + exec: + command: + - bash + - '-ec' + - > + mongo --disableImplicitSessions $TLS_OPTIONS --eval + 'db.hello().isWritablePrimary || db.hello().secondary' | grep + -q 'true' + initialDelaySeconds: 5 + timeoutSeconds: 5 + periodSeconds: 10 + successThreshold: 1 + failureThreshold: 6 + terminationMessagePath: /dev/termination-log + terminationMessagePolicy: File + restartPolicy: Always + terminationGracePeriodSeconds: 30 + dnsPolicy: ClusterFirst + serviceAccountName: default + serviceAccount: default + securityContext: + fsGroup: 1001 + volumes: + - name: data-db + persistentVolumeClaim: + claimName: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-data-db +{{ end }} \ No newline at end of file diff --git a/deployment/helm/meli-chart/templates/mongo-service.yaml b/deployment/helm/meli-chart/templates/mongo-service.yaml new file mode 100644 index 0000000..2711c81 --- /dev/null +++ b/deployment/helm/meli-chart/templates/mongo-service.yaml @@ -0,0 +1,19 @@ +{{- if .Values.mongo.enabled }} +kind: Service +apiVersion: v1 +metadata: + name: mongo + labels: + app.kubernetes.io/name: {{ include "helper.name" . }}-mongo + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + ports: + - name: mongo-svc-port + protocol: TCP + port: {{ .Values.mongo.port }} + targetPort: mongo-port + selector: + app.kubernetes.io/name: {{ include "helper.name" . }}-mongo + app.kubernetes.io/instance: {{ .Release.Name }} + type: ClusterIP +{{ end }} \ No newline at end of file diff --git a/deployment/helm/meli-chart/templates/pvcs.yaml b/deployment/helm/meli-chart/templates/pvcs.yaml new file mode 100644 index 0000000..6bfece3 --- /dev/null +++ b/deployment/helm/meli-chart/templates/pvcs.yaml @@ -0,0 +1,55 @@ +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-data + labels: + {{- include "helper.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.resources.storage.data }} + #storageClassName: {} +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-config + labels: + {{- include "helper.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.resources.storage.config }} + #storageClassName: {} +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-sites + labels: + {{- include "helper.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.resources.storage.sites }} + #storageClassName: {} +--- +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ .Values.pvcPrefix }}-{{ .Release.Name }}-data-db + labels: + {{- include "helper.labels" . | nindent 4 }} +spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: {{ .Values.resources.storage.db }} + #storageClassName: {} diff --git a/deployment/helm/meli-chart/templates/service.yaml b/deployment/helm/meli-chart/templates/service.yaml new file mode 100644 index 0000000..7405096 --- /dev/null +++ b/deployment/helm/meli-chart/templates/service.yaml @@ -0,0 +1,29 @@ +kind: Service +apiVersion: v1 +metadata: + name: meli-svc + labels: + app.kubernetes.io/name: {{ include "helper.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} +spec: + ports: + - name: http + protocol: TCP + port: 80 + targetPort: http + - name: https + protocol: TCP + port: 443 + targetPort: https + - name: admin + protocol: TCP + port: 2019 + targetPort: admin + - name: api + protocol: TCP + port: 3001 + targetPort: api + selector: + app.kubernetes.io/name: {{ include "helper.name" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + type: ClusterIP