diff --git a/helm-repo/index.yaml b/helm-repo/index.yaml index 78c38df..4ea550d 100644 --- a/helm-repo/index.yaml +++ b/helm-repo/index.yaml @@ -1,9 +1,29 @@ apiVersion: v1 entries: + phase: + - apiVersion: v2 + created: "2024-08-15T17:20:48.04662344+05:30" + description: A Helm chart for deploying the Phase Secrets Manager + digest: 35fb1622a8b3d83e461f8d83c957e90d1afd5c6a69049e92da7594a8af302461 + home: https://github.com/phasehq/kubernetes-secrets-operator + icon: https://phase.dev/apple-touch-icon.png + keywords: + - phase + - deployment + maintainers: + - email: nimish@phase.dev + name: Nimish + name: phase + sources: + - https://github.com/phasehq/console + type: application + urls: + - phase-0.1.0.tgz + version: 0.1.0 phase-kubernetes-operator: - apiVersion: v2 appVersion: 1.2.1 - created: "2024-07-29T18:55:33.848979547+05:30" + created: "2024-08-15T17:20:48.047188122+05:30" description: A Helm chart for deploying the Phase Kubernetes Operator digest: dc708b49b17107c0bf6efd354777f2ddaf4e080c18f7ab0541968338dfe808c5 home: https://github.com/phasehq/kubernetes-secrets-operator @@ -21,6 +41,6 @@ entries: - https://github.com/phasehq/kubernetes-secrets-operator type: application urls: - - https://helm.phase.dev/phase-kubernetes-operator-1.2.1.tgz + - phase-kubernetes-operator-1.2.1.tgz version: 1.2.1 -generated: "2024-07-29T18:55:33.848176069+05:30" +generated: "2024-08-15T17:20:48.045460903+05:30" diff --git a/helm-repo/phase-0.1.0.tgz b/helm-repo/phase-0.1.0.tgz new file mode 100644 index 0000000..08528d2 Binary files /dev/null and b/helm-repo/phase-0.1.0.tgz differ diff --git a/phase-k8s.yaml b/phase-k8s.yaml new file mode 100644 index 0000000..31c9195 --- /dev/null +++ b/phase-k8s.yaml @@ -0,0 +1,338 @@ +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: phase-config +data: + HOST: "localhost" + HTTP_PROTOCOL: "http://" # Need to change to https after TLS + SSO_PROVIDERS: "google,github,gitlab" + DATABASE_HOST: "phase-postgres" + DATABASE_PORT: "5432" + DATABASE_NAME: "postgres-db-name" + DATABASE_USER: "postgres-user" + REDIS_HOST: "phase-redis" + REDIS_PORT: "6379" + NEXT_TELEMETRY_DISABLED: "1" + +--- +apiVersion: v1 +kind: Secret +metadata: + name: phase-secrets +type: Opaque +stringData: + NEXTAUTH_SECRET: "82031b3760ac58352bb2d48fd9f32e9f72a0614343b669038139f18652ed1447" + SECRET_KEY: "92d44efc4f9a4c0556cc67d2d033d3217829c263d5ab7d1954cf4b5bfd533e58" + SERVER_SECRET: "9e760539415af07b22249b5878593bd4deb9b8961c7dd0570117549f2f32a2" + DATABASE_PASSWORD: "a765b221799be364c53c8a32acccf5dd90d5fc832607bdd14fccaaaa0062adfd" + GOOGLE_CLIENT_ID: + GOOGLE_CLIENT_SECRET: + GITHUB_CLIENT_ID: + GITHUB_CLIENT_SECRET: + GITLAB_CLIENT_ID: + GITLAB_CLIENT_SECRET: + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phase-frontend +spec: + replicas: 1 + selector: + matchLabels: + app: phase-frontend + template: + metadata: + labels: + app: phase-frontend + spec: + containers: + - name: frontend + image: phasehq/frontend:bae2759 + ports: + - containerPort: 3000 + envFrom: + - configMapRef: + name: phase-config + - secretRef: + name: phase-secrets + env: + - name: NEXTAUTH_URL + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: BACKEND_API_BASE + value: "$(HTTP_PROTOCOL)$(HOST)/service" + - name: NEXT_PUBLIC_BACKEND_API_BASE + value: "$(HTTP_PROTOCOL)$(HOST)/service" + - name: NEXT_PUBLIC_NEXTAUTH_PROVIDERS + value: "$(SSO_PROVIDERS)" + # readinessProbe: + # httpGet: + # path: /api/health + # port: 3000 + # initialDelaySeconds: 10 + # periodSeconds: 5 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phase-backend +spec: + replicas: 1 + selector: + matchLabels: + app: phase-backend + template: + metadata: + labels: + app: phase-backend + spec: + initContainers: + - name: wait-for-postgres + image: busybox:1.28 + command: ['sh', '-c', 'until nc -z phase-postgres 5432; do echo waiting for postgres; sleep 2; done;'] + containers: + - name: backend + image: phasehq/backend:latest + envFrom: + - configMapRef: + name: phase-config + - secretRef: + name: phase-secrets + env: + - name: OAUTH_REDIRECT_URI + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: ALLOWED_HOSTS + value: "$(HOST),phase-backend" + - name: ALLOWED_ORIGINS + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: SESSION_COOKIE_DOMAIN + value: "$(HOST)" + # readinessProbe: + # httpGet: + # path: /health + # port: 8000 + # httpHeaders: + # - name: Host + # value: "phase-backend" + # initialDelaySeconds: 10 + # periodSeconds: 5 + # timeoutSeconds: 5 + # livenessProbe: + # httpGet: + # path: /health + # port: 8000 + # httpHeaders: + # - name: Host + # value: "phase-backend" + # initialDelaySeconds: 15 + # periodSeconds: 20 + # timeoutSeconds: 5 + # lifecycle: + # postStart: + # exec: + # command: ["/bin/sh", "-c", "python manage.py migrate"] + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phase-worker +spec: + replicas: 1 + selector: + matchLabels: + app: phase-worker + template: + metadata: + labels: + app: phase-worker + spec: + initContainers: + # Wait for Postgresql to boot up before starting worker + - name: wait-for-postgres + image: busybox + command: ['sh', '-c', 'until nc -z $DATABASE_HOST $DATABASE_PORT; do echo waiting for postgres; sleep 2; done;'] + envFrom: + - configMapRef: + name: phase-config + # Wait for Redis to boot up before starting worker + - name: wait-for-redis + image: busybox + command: ['sh', '-c', 'until nc -z $REDIS_HOST $REDIS_PORT; do echo waiting for redis; sleep 2; done;'] + envFrom: + - configMapRef: + name: phase-config + containers: + - name: worker + image: phasehq/backend:latest + command: ["python", "manage.py", "rqworker", "default"] + envFrom: + - configMapRef: + name: phase-config + - secretRef: + name: phase-secrets + env: + - name: ALLOWED_HOSTS + value: "$(HOST),phase-worker" + - name: ALLOWED_ORIGINS + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: SESSION_COOKIE_DOMAIN + value: "$(HOST)" + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phase-postgres +spec: + replicas: 1 + selector: + matchLabels: + app: phase-postgres + template: + metadata: + labels: + app: phase-postgres + spec: + containers: + - name: postgres + image: postgres:15.4-alpine3.17 + envFrom: + - configMapRef: + name: phase-config + - secretRef: + name: phase-secrets + env: + - name: POSTGRES_DB + valueFrom: + configMapKeyRef: + name: phase-config + key: DATABASE_NAME + - name: POSTGRES_USER + valueFrom: + configMapKeyRef: + name: phase-config + key: DATABASE_USER + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: phase-secrets + key: DATABASE_PASSWORD + volumeMounts: + - name: postgres-storage + mountPath: /var/lib/postgresql/data + volumes: + - name: postgres-storage + emptyDir: {} + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: phase-redis +spec: + replicas: 1 + selector: + matchLabels: + app: phase-redis + template: + metadata: + labels: + app: phase-redis + spec: + containers: + - name: redis + image: redis:alpine3.19 + readinessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: 5 + periodSeconds: 5 + +--- +apiVersion: v1 +kind: Service +metadata: + name: phase-frontend +spec: + selector: + app: phase-frontend + ports: + - protocol: TCP + port: 3000 + targetPort: 3000 + +--- +apiVersion: v1 +kind: Service +metadata: + name: phase-backend +spec: + selector: + app: phase-backend + ports: + - protocol: TCP + port: 8000 + targetPort: 8000 + +--- +apiVersion: v1 +kind: Service +metadata: + name: phase-postgres +spec: + selector: + app: phase-postgres + ports: + - protocol: TCP + port: 5432 + targetPort: 5432 + +--- +apiVersion: v1 +kind: Service +metadata: + name: phase-redis +spec: + selector: + app: phase-redis + ports: + - protocol: TCP + port: 6379 + targetPort: 6379 + +--- +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: phase-ingress + annotations: + nginx.ingress.kubernetes.io/ssl-redirect: "false" +spec: + rules: + - http: + paths: + - path: /service + pathType: Prefix + backend: + service: + name: phase-backend + port: + number: 8000 + - path: /kms + pathType: Prefix + backend: + service: + name: phase-backend + port: + number: 8000 + - path: / + pathType: Prefix + backend: + service: + name: phase-frontend + port: + number: 3000 \ No newline at end of file diff --git a/phase/Chart.yaml b/phase/Chart.yaml new file mode 100644 index 0000000..ded60c4 --- /dev/null +++ b/phase/Chart.yaml @@ -0,0 +1,15 @@ +apiVersion: v2 +name: phase +icon: https://phase.dev/apple-touch-icon.png +description: A Helm chart for deploying the Phase Secrets Manager +type: application +version: 0.1.0 +keywords: + - phase + - deployment +home: https://github.com/phasehq/kubernetes-secrets-operator +sources: + - https://github.com/phasehq/console +maintainers: + - name: Nimish + email: nimish@phase.dev diff --git a/phase/templates/NOTES.txt b/phase/templates/NOTES.txt new file mode 100644 index 0000000..94b8275 --- /dev/null +++ b/phase/templates/NOTES.txt @@ -0,0 +1,42 @@ +{{- define "phase.asciiArt" -}} +⠀⠀⠀⠀⠀⠀⠀⠀⠀⢠⠔⠋⣳⣖⠚⣲⢖⠙⠳⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⡴⠉⢀⡼⠃⢘⣞⠁⠙⡆⠀⠘⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⢀⡜⠁⢠⠞⠀⢠⠞⠸⡆⠀⠹⡄⠀⠹⡄⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⢀⠞⠀⢠⠏⠀⣠⠏⠀⠀⢳⠀⠀⢳⠀⠀⢧⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⢠⠎⠀⣠⠏⠀⣰⠃⠀⠀⠀⠈⣇⠀⠘⡇⠀⠘⡆⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⢠⠏⠀⣰⠇⠀⣰⠃⠀⠀⠀⠀⠀⢺⡀⠀⢹⠀⠀⢽⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⢠⠏⠀⣰⠃⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⣇⠀⠈⣇⠀⠘⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⢠⠏⠀⢰⠃⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⠀⢸⡀⠀⢹⡀⠀⢹⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⢠⠏⠀⢰⠃⠀⣰⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣇⠀⠈⣇⠀⠈⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀ +⠛⠒⠚⠛⠒⠓⠚⠒⠒⠓⠒⠓⠚⠒⠓⠚⠒⠓⢻⡒⠒⢻⡒⠒⢻⡒⠒⠒⠒⠒⠒⠒⠒⠒⠒⠒⣲⠒⠒⣲⠒⠒⡲⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢧⠀⠀⢧⠀⠈⣇⠀⠀⠀⠀⠀⠀⠀⠀⢠⠇⠀⣰⠃⠀⣰⠃⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠘⡆⠀⠘⡆⠀⠸⡄⠀⠀⠀⠀⠀⠀⣠⠇⠀⣰⠃⠀⣴⠃⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠹⡄⠀⠹⡄⠀⠹⡄⠀⠀⠀⠀⡴⠃⢀⡼⠁⢀⡼⠁⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣆⠀⠙⣆⠀⠹⣄⠀⣠⠎⠁⣠⠞⠀⡤⠏⠀⠀⠀⠀⠀⠀⠀⠀ +⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠳⢤⣈⣳⣤⣼⣹⢥⣰⣋⡥⡴⠊⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀ +{{- end -}} + +{{- define "phase.installationMessage" -}} +{{ include "phase.asciiArt" . }} +Thank you for installing {{ .Chart.Name }}! + +To learn more about the deployment, try: + - `helm status {{ .Release.Name }}` + - `helm get all {{ .Release.Name }}` + +🙋 Need help?: https://slack.phase.dev +💻 Bug reports / feature requests: https://github.com/phasehq/console + +{{- if .Values.ingress.enabled }} +You can access the application at: +{{- range .Values.ingress.hosts }} + - http{{ if $.Values.ingress.tls }}s{{ end }}://{{ .host }} +{{- end }} +{{- else }} +To access the application, you need to set up your own ingress or use port-forwarding: + - kubectl port-forward svc/{{ .Release.Name }}-frontend 3000:3000 +Then access the application at: http://localhost:3000 +{{- end }} +{{- end -}} + +{{ include "phase.installationMessage" . }} \ No newline at end of file diff --git a/phase/templates/_helpers.tpl b/phase/templates/_helpers.tpl new file mode 100644 index 0000000..3a2aa74 --- /dev/null +++ b/phase/templates/_helpers.tpl @@ -0,0 +1,59 @@ +{{/* +Expand the name of the chart. +*/}} +{{- define "phase.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 "phase.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 "phase.chart" -}} +{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} +{{- end }} + +{{/* +Common labels +*/}} +{{- define "phase.labels" -}} +helm.sh/chart: {{ include "phase.chart" . }} +{{ include "phase.selectorLabels" . }} +app.kubernetes.io/managed-by: {{ .Release.Service }} +{{- end }} + +{{/* +Selector labels +*/}} +{{- define "phase.selectorLabels" -}} +app.kubernetes.io/name: {{ include "phase.name" . }} +app.kubernetes.io/instance: {{ .Release.Name }} +{{- end }} + +{{/* +Create the name of the service account to use +*/}} +{{- define "phase.serviceAccountName" -}} +{{- if .Values.serviceAccount.create }} +{{- default (include "phase.fullname" .) .Values.serviceAccount.name }} +{{- else }} +{{- default "default" .Values.serviceAccount.name }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/phase/templates/configmap.yaml b/phase/templates/configmap.yaml new file mode 100644 index 0000000..1407134 --- /dev/null +++ b/phase/templates/configmap.yaml @@ -0,0 +1,17 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "phase.fullname" . }}-config + labels: + {{- include "phase.labels" . | nindent 4 }} +data: + HOST: {{ .Values.global.host | quote }} + HTTP_PROTOCOL: {{ .Values.global.httpProtocol | quote }} + SSO_PROVIDERS: {{ .Values.sso.providers | quote }} + DATABASE_HOST: {{ tpl .Values.database.host . | quote }} + DATABASE_PORT: {{ .Values.database.port | quote }} + DATABASE_NAME: {{ .Values.database.name | quote }} + DATABASE_USER: {{ .Values.database.user | quote }} + REDIS_HOST: {{ tpl .Values.redis.host . | quote }} + REDIS_PORT: {{ .Values.redis.port | quote }} + NEXT_TELEMETRY_DISABLED: {{ default "1" | quote }} \ No newline at end of file diff --git a/phase/templates/deployment-backend.yaml b/phase/templates/deployment-backend.yaml new file mode 100644 index 0000000..8db9797 --- /dev/null +++ b/phase/templates/deployment-backend.yaml @@ -0,0 +1,62 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "phase.fullname" . }}-backend + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.app.backend.replicaCount }} + selector: + matchLabels: + {{- include "phase.selectorLabels" . | nindent 6 }} + app: backend + template: + metadata: + labels: + {{- include "phase.selectorLabels" . | nindent 8 }} + app: backend + spec: + containers: + - name: backend + image: "{{ .Values.global.images.backend.repository }}:{{ .Values.global.version }}" + imagePullPolicy: {{ .Values.app.backend.image.pullPolicy }} + envFrom: + - configMapRef: + name: {{ include "phase.fullname" . }}-config + - secretRef: + name: {{ include "phase.fullname" . }}-secrets + env: + - name: OAUTH_REDIRECT_URI + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: ALLOWED_HOSTS + value: "$(HOST),{{ include "phase.fullname" . }}-backend" + - name: ALLOWED_ORIGINS + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: SESSION_COOKIE_DOMAIN + value: "$(HOST)" + {{- if .Values.app.backend.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: 493c5048-99f9-4eac-ad0d-98c3740b491f/health + port: 8000 + httpHeaders: + - name: Host + value: "{{ include "phase.fullname" . }}-backend" + initialDelaySeconds: {{ .Values.app.backend.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.app.backend.readinessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.app.backend.readinessProbe.timeoutSeconds }} + {{- end }} + {{- if .Values.app.backend.livenessProbe.enabled }} + livenessProbe: + httpGet: + path: 493c5048-99f9-4eac-ad0d-98c3740b491f/health + port: 8000 + httpHeaders: + - name: Host + value: "{{ include "phase.fullname" . }}-backend" + initialDelaySeconds: {{ .Values.app.backend.livenessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.app.backend.livenessProbe.periodSeconds }} + timeoutSeconds: {{ .Values.app.backend.livenessProbe.timeoutSeconds }} + {{- end }} + resources: + {{- toYaml .Values.app.backend.resources | nindent 12 }} \ No newline at end of file diff --git a/phase/templates/deployment-frontend.yaml b/phase/templates/deployment-frontend.yaml new file mode 100644 index 0000000..7807b10 --- /dev/null +++ b/phase/templates/deployment-frontend.yaml @@ -0,0 +1,48 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "phase.fullname" . }}-frontend + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.app.frontend.replicaCount }} + selector: + matchLabels: + {{- include "phase.selectorLabels" . | nindent 6 }} + app: frontend + template: + metadata: + labels: + {{- include "phase.selectorLabels" . | nindent 8 }} + app: frontend + spec: + containers: + - name: frontend + image: "{{ .Values.global.images.frontend.repository }}:{{ .Values.global.version }}" + imagePullPolicy: {{ .Values.app.frontend.image.pullPolicy }} + ports: + - containerPort: 3000 + envFrom: + - configMapRef: + name: {{ include "phase.fullname" . }}-config + - secretRef: + name: {{ include "phase.fullname" . }}-secrets + env: + - name: NEXTAUTH_URL + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: BACKEND_API_BASE + value: "http://{{ include "phase.fullname" . }}-backend:{{ .Values.app.backend.service.port }}" + - name: NEXT_PUBLIC_BACKEND_API_BASE + value: "$(HTTP_PROTOCOL)$(HOST)/service" + - name: NEXT_PUBLIC_NEXTAUTH_PROVIDERS + value: "$(SSO_PROVIDERS)" + {{- if .Values.app.frontend.readinessProbe.enabled }} + readinessProbe: + httpGet: + path: api/health + port: 3000 + initialDelaySeconds: {{ .Values.app.frontend.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.app.frontend.readinessProbe.periodSeconds }} + {{- end }} + resources: + {{- toYaml .Values.app.frontend.resources | nindent 12 }} \ No newline at end of file diff --git a/phase/templates/deployment-postgres.yaml b/phase/templates/deployment-postgres.yaml new file mode 100644 index 0000000..f1afc99 --- /dev/null +++ b/phase/templates/deployment-postgres.yaml @@ -0,0 +1,101 @@ +{{- if not .Values.global.external.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "phase.fullname" . }}-postgres + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "phase.selectorLabels" . | nindent 6 }} + app: postgres + template: + metadata: + labels: + {{- include "phase.selectorLabels" . | nindent 8 }} + app: postgres + spec: + securityContext: + fsGroup: 999 + containers: + - name: postgres + image: "{{ .Values.database.image.repository }}:{{ .Values.database.image.tag }}" + imagePullPolicy: {{ .Values.database.image.pullPolicy }} + securityContext: + runAsUser: 999 + runAsGroup: 999 + envFrom: + - configMapRef: + name: {{ include "phase.fullname" . }}-config + - secretRef: + name: {{ include "phase.fullname" . }}-secrets + env: + - name: POSTGRES_DB + value: {{ .Values.database.name | quote }} + - name: POSTGRES_USER + value: {{ .Values.database.user | quote }} + - name: POSTGRES_PASSWORD + valueFrom: + secretKeyRef: + name: {{ include "phase.fullname" . }}-secrets + key: DATABASE_PASSWORD + - name: PGDATA + value: /var/lib/postgresql/data/pgdata + ports: + - name: postgres + containerPort: 5432 + volumeMounts: + - name: postgres-storage + mountPath: /var/lib/postgresql/data + resources: + {{- toYaml .Values.database.resources | nindent 12 }} + livenessProbe: + exec: + command: + - /bin/sh + - -c + - exec pg_isready -U $POSTGRES_USER -d $POSTGRES_DB + initialDelaySeconds: 30 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + readinessProbe: + exec: + command: + - /bin/sh + - -c + - exec pg_isready -U $POSTGRES_USER -d $POSTGRES_DB + initialDelaySeconds: 5 + periodSeconds: 10 + timeoutSeconds: 5 + failureThreshold: 6 + volumes: + - name: postgres-storage + {{- if .Values.database.persistence.enabled }} + persistentVolumeClaim: + claimName: {{ include "phase.fullname" . }}-postgres-pvc + {{- else }} + emptyDir: {} + {{- end }} + +--- +{{- if and (not .Values.global.external.enabled) .Values.database.persistence.enabled }} +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: {{ include "phase.fullname" . }}-postgres-pvc + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + accessModes: + - {{ .Values.database.persistence.accessMode }} + resources: + requests: + storage: {{ .Values.database.persistence.size }} + {{- if .Values.database.persistence.storageClass }} + storageClassName: {{ .Values.database.persistence.storageClass }} + {{- end }} +{{- end }} +{{- end }} \ No newline at end of file diff --git a/phase/templates/deployment-redis.yaml b/phase/templates/deployment-redis.yaml new file mode 100644 index 0000000..3d539f7 --- /dev/null +++ b/phase/templates/deployment-redis.yaml @@ -0,0 +1,33 @@ +{{- if not .Values.global.external.enabled }} +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "phase.fullname" . }}-redis + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + replicas: 1 + selector: + matchLabels: + {{- include "phase.selectorLabels" . | nindent 6 }} + app: redis + template: + metadata: + labels: + {{- include "phase.selectorLabels" . | nindent 8 }} + app: redis + spec: + containers: + - name: redis + image: "{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}" + imagePullPolicy: {{ .Values.redis.image.pullPolicy }} + ports: + - containerPort: 6379 + readinessProbe: + tcpSocket: + port: 6379 + initialDelaySeconds: {{ .Values.redis.readinessProbe.initialDelaySeconds }} + periodSeconds: {{ .Values.redis.readinessProbe.periodSeconds }} + resources: + {{- toYaml .Values.redis.resources | nindent 12 }} +{{- end }} \ No newline at end of file diff --git a/phase/templates/deployment-worker.yaml b/phase/templates/deployment-worker.yaml new file mode 100644 index 0000000..bf81d76 --- /dev/null +++ b/phase/templates/deployment-worker.yaml @@ -0,0 +1,37 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "phase.fullname" . }}-worker + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + replicas: {{ .Values.app.worker.replicaCount }} + selector: + matchLabels: + {{- include "phase.selectorLabels" . | nindent 6 }} + app: worker + template: + metadata: + labels: + {{- include "phase.selectorLabels" . | nindent 8 }} + app: worker + spec: + containers: + - name: worker + image: "{{ .Values.global.images.backend.repository }}:{{ .Values.global.version }}" + imagePullPolicy: {{ .Values.app.worker.image.pullPolicy }} + command: ["python", "manage.py", "rqworker", "default"] + envFrom: + - configMapRef: + name: {{ include "phase.fullname" . }}-config + - secretRef: + name: {{ include "phase.fullname" . }}-secrets + env: + - name: ALLOWED_HOSTS + value: "$(HOST),{{ include "phase.fullname" . }}-worker" + - name: ALLOWED_ORIGINS + value: "$(HTTP_PROTOCOL)$(HOST)" + - name: SESSION_COOKIE_DOMAIN + value: "$(HOST)" + resources: + {{- toYaml .Values.app.worker.resources | nindent 12 }} \ No newline at end of file diff --git a/phase/templates/ingress.yaml b/phase/templates/ingress.yaml new file mode 100644 index 0000000..c458203 --- /dev/null +++ b/phase/templates/ingress.yaml @@ -0,0 +1,55 @@ +{{- if .Values.ingress.enabled -}} +apiVersion: networking.k8s.io/v1 +kind: Ingress +metadata: + name: {{ include "phase.fullname" . }} + labels: + {{- include "phase.labels" . | nindent 4 }} + annotations: + kubernetes.io/ingress.class: {{ .Values.ingress.className | default "nginx" }} + {{- if .Values.certManager.enabled }} + cert-manager.io/cluster-issuer: {{ .Values.certManager.issuerName }} + {{- end }} + nginx.ingress.kubernetes.io/ssl-redirect: "false" + nginx.ingress.kubernetes.io/proxy-connect-timeout: "30" + nginx.ingress.kubernetes.io/proxy-send-timeout: "30" + nginx.ingress.kubernetes.io/proxy-read-timeout: "30" + nginx.ingress.kubernetes.io/proxy-body-size: "64m" + nginx.ingress.kubernetes.io/proxy-buffer-size: "64k" + nginx.ingress.kubernetes.io/proxy-buffers-number: "8" + nginx.ingress.kubernetes.io/proxy-busy-buffers-size: "128k" + nginx.ingress.kubernetes.io/use-regex: "true" + nginx.ingress.kubernetes.io/rewrite-target: /$2 +spec: + {{- if .Values.ingress.className }} + ingressClassName: {{ .Values.ingress.className }} + {{- end }} + rules: + - host: {{ .Values.ingress.host | default .Values.global.host | quote }} + http: + paths: + - path: /service(/|$)(.*) + pathType: Prefix + backend: + service: + name: {{ include "phase.fullname" $ }}-backend + port: + number: 8000 + - path: /()(.*) + pathType: Prefix + backend: + service: + name: {{ include "phase.fullname" $ }}-frontend + port: + number: 3000 + {{- if or .Values.ingress.tls .Values.certManager.enabled }} + tls: + - hosts: + - {{ .Values.ingress.host | default .Values.global.host | quote }} + {{- if .Values.certManager.enabled }} + secretName: {{ include "phase.fullname" . }}-tls + {{- else }} + secretName: {{ .Values.ingress.tlsSecretName }} + {{- end }} + {{- end }} +{{- end }} \ No newline at end of file diff --git a/phase/templates/secret.yaml b/phase/templates/secret.yaml new file mode 100644 index 0000000..3588bd6 --- /dev/null +++ b/phase/templates/secret.yaml @@ -0,0 +1,16 @@ +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "phase.fullname" . }}-secrets +type: Opaque +stringData: + NEXTAUTH_SECRET: {{ .Values.secrets.nextauthSecret | quote }} + SECRET_KEY: {{ .Values.secrets.secretKey | quote }} + SERVER_SECRET: {{ .Values.secrets.serverSecret | quote }} + DATABASE_PASSWORD: {{ .Values.secrets.databasePassword | quote }} + GOOGLE_CLIENT_ID: {{ .Values.secrets.googleClientId | quote }} + GOOGLE_CLIENT_SECRET: {{ .Values.secrets.googleClientSecret | quote }} + GITHUB_CLIENT_ID: {{ .Values.secrets.githubClientId | quote }} + GITHUB_CLIENT_SECRET: {{ .Values.secrets.githubClientSecret | quote }} + GITLAB_CLIENT_ID: {{ .Values.secrets.gitlabClientId | quote }} + GITLAB_CLIENT_SECRET: {{ .Values.secrets.gitlabClientSecret | quote }} \ No newline at end of file diff --git a/phase/templates/service-backend.yaml b/phase/templates/service-backend.yaml new file mode 100644 index 0000000..612ae9d --- /dev/null +++ b/phase/templates/service-backend.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "phase.fullname" . }}-backend + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + type: {{ .Values.app.backend.service.type }} + ports: + - port: {{ .Values.app.backend.service.port }} + targetPort: 8000 + protocol: TCP + selector: + {{- include "phase.selectorLabels" . | nindent 4 }} + app: backend \ No newline at end of file diff --git a/phase/templates/service-frontend.yaml b/phase/templates/service-frontend.yaml new file mode 100644 index 0000000..64d86d4 --- /dev/null +++ b/phase/templates/service-frontend.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "phase.fullname" . }}-frontend + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + type: {{ .Values.app.frontend.service.type }} + ports: + - port: {{ .Values.app.frontend.service.port }} + targetPort: 3000 + protocol: TCP + selector: + {{- include "phase.selectorLabels" . | nindent 4 }} + app: frontend \ No newline at end of file diff --git a/phase/templates/service-postgres.yaml b/phase/templates/service-postgres.yaml new file mode 100644 index 0000000..2451890 --- /dev/null +++ b/phase/templates/service-postgres.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "phase.fullname" . }}-postgres + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.database.service.port }} + targetPort: 5432 + protocol: TCP + selector: + {{- include "phase.selectorLabels" . | nindent 4 }} + app: postgres \ No newline at end of file diff --git a/phase/templates/service-redis.yaml b/phase/templates/service-redis.yaml new file mode 100644 index 0000000..990cbe6 --- /dev/null +++ b/phase/templates/service-redis.yaml @@ -0,0 +1,15 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "phase.fullname" . }}-redis + labels: + {{- include "phase.labels" . | nindent 4 }} +spec: + type: ClusterIP + ports: + - port: {{ .Values.redis.service.port }} + targetPort: 6379 + protocol: TCP + selector: + {{- include "phase.selectorLabels" . | nindent 4 }} + app: redis \ No newline at end of file diff --git a/phase/values.yaml b/phase/values.yaml new file mode 100644 index 0000000..7d1a2cb --- /dev/null +++ b/phase/values.yaml @@ -0,0 +1,149 @@ +# Global settings +global: + host: "localhost" + httpProtocol: "https://" + version: latest + images: + frontend: + repository: phasehq/frontend + backend: + repository: phasehq/backend + external: + enabled: false # Set to true to use external managed services + +sso: + providers: "google,github,gitlab" + +# Secrets (DO NOT use these in production, generate your own secure values) +secrets: + nextauthSecret: "efd7e1e87edd416bc8ee28e7ee1d961ab7f4a4724ea4249d36f07c92616a322d" + secretKey: "ee728b91f92b48841a847fad61549f9f0b384f172b74bdcc859c1aadbfb633bd" + serverSecret: "896d2d2462ebd12683cee44d7808939217da961d1f15e69c977ae250f23a65c9" + databasePassword: "f5cc076c4788bba216567380247b394d71a2fa0c8970052005a824bad340c6be" + googleClientId: "" + googleClientSecret: "" + githubClientId: "" + githubClientSecret: "" + gitlabClientId: "" + gitlabClientSecret: "" + +# Ingress settings +ingress: + enabled: true + className: "nginx" + # host: "your-domain.com" + tls: [] + +# Cert manager settings +certManager: + enabled: false + issuerName: "" + issuerKind: "" + +app: + frontend: + image: + pullPolicy: IfNotPresent + replicaCount: 1 + service: + type: ClusterIP + port: 3000 + readinessProbe: + enabled: true + initialDelaySeconds: 10 + periodSeconds: 5 + resources: + requests: + cpu: 500m + memory: 1Gi + + backend: + image: + pullPolicy: IfNotPresent + replicaCount: 1 + service: + type: ClusterIP + port: 8000 + readinessProbe: + enabled: true + initialDelaySeconds: 10 + periodSeconds: 5 + timeoutSeconds: 5 + livenessProbe: + enabled: true + initialDelaySeconds: 15 + periodSeconds: 20 + timeoutSeconds: 5 + resources: + requests: + cpu: 500m + memory: 1Gi + + worker: + image: + pullPolicy: IfNotPresent + replicaCount: 1 + resources: + requests: + cpu: 250m + memory: 512Mi + +database: + external: false + host: "{{ .Release.Name }}-postgres" + port: "5432" + name: "postgres-db-name" + user: "postgres-user" + image: + repository: postgres + tag: 15.4-alpine3.17 + pullPolicy: IfNotPresent + service: + port: 5432 + persistence: + enabled: true + size: 50Gi + storageClass: "" + accessMode: ReadWriteOnce + resources: + requests: + cpu: 500m + memory: 1Gi + +# Redis settings +redis: + external: false + host: "{{ .Release.Name }}-redis" + port: "6379" + image: + repository: redis + tag: alpine3.19 + pullPolicy: IfNotPresent + service: + port: 6379 + readinessProbe: + initialDelaySeconds: 5 + periodSeconds: 5 + resources: + requests: + cpu: 100m + memory: 256Mi + + +# Autoscaling settings +autoscaling: + frontend: + enabled: false + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 80 + backend: + enabled: false + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 80 + worker: + enabled: false + minReplicas: 1 + maxReplicas: 10 + targetCPUUtilizationPercentage: 80 \ No newline at end of file