├── .gitignore ├── charts ├── saleor │ ├── charts │ │ ├── redis-22.0.7.tgz │ │ └── postgresql-12.12.5.tgz │ ├── templates │ │ ├── imageSecret.yaml │ │ ├── serviceaccount.yaml │ │ ├── gcs-secret.yaml │ │ ├── tests │ │ │ └── test-connection.yaml │ │ ├── service.yaml │ │ ├── s3-secret.yaml │ │ ├── dashboard_service.yaml │ │ ├── istio_virtual_service.yaml │ │ ├── postgresql_credentials.yaml │ │ ├── istio_destination_rule.yaml │ │ ├── _gcs-env.tpl │ │ ├── _s3-env.tpl │ │ ├── saleor_secrets.yaml │ │ ├── celery-beat-deployment.yaml │ │ ├── saleor_hpa.yaml │ │ ├── ingress.yaml │ │ ├── migration_job.yaml │ │ ├── worker_deployment.yaml │ │ ├── dashboard_deployment.yaml │ │ ├── saleor_deployment.yaml │ │ └── NOTES.txt │ ├── test-values │ │ ├── minimal-values.yaml │ │ ├── minimal-test.yaml │ │ ├── redis-internal.yaml │ │ ├── redis-external.yaml │ │ ├── redis-external-tls.yaml │ │ ├── redis-sentinel.yaml │ │ ├── redis-global-url.yaml │ │ ├── external-redis-test.yaml │ │ ├── external-db-values.yaml │ │ ├── redis-test.yaml │ │ ├── custom-values.yaml │ │ ├── all-enabled-values.yaml │ │ ├── production-values.yaml │ │ └── test-values.yaml │ ├── Chart.lock │ ├── .helmignore │ ├── Chart.yaml │ ├── scripts │ │ └── generate_settings_configmap.sh │ └── docs │ │ └── gcs-storage.md ├── saleor-apps │ ├── charts │ │ └── redis-0.6.4.tgz │ ├── docs │ │ ├── images │ │ │ └── marketplaceImage.png │ │ └── marketplace.md │ ├── Chart.lock │ ├── templates │ │ ├── secret.yaml │ │ ├── marketplace-service.yaml │ │ ├── _redis-helpers.tpl │ │ ├── service.yaml │ │ ├── dynamodb-service.yaml │ │ ├── dynamodb-secret.yaml │ │ ├── _helpers.tpl │ │ ├── marketplace-ingress.yaml │ │ ├── ingress.yaml │ │ ├── marketplace-deployment.yaml │ │ ├── deployment.yaml │ │ └── dynamodb-deployment.yaml │ ├── Chart.yaml │ ├── values-example-prod.yaml │ ├── values.yaml │ └── README.md ├── strapi │ ├── charts │ │ └── postgresql-13.2.9.tgz │ ├── Chart.lock │ ├── templates │ │ ├── serviceaccount.yaml │ │ ├── tests │ │ │ └── test-connection.yaml │ │ ├── service.yaml │ │ ├── hpa.yaml │ │ ├── secret.yaml │ │ ├── NOTES.txt │ │ ├── postgres_backup.yaml │ │ ├── _helpers.tpl │ │ ├── ingress.yaml │ │ └── deployment.yaml │ ├── .helmignore │ ├── Chart.yaml │ └── values.yaml ├── gtm-server-container-cluster │ ├── templates │ │ ├── serviceaccount.yaml │ │ ├── tests │ │ │ └── test-connection.yaml │ │ ├── service.yaml │ │ ├── NOTES.txt │ │ ├── ingress.yaml │ │ ├── _helpers.tpl │ │ ├── hpa.yaml │ │ └── deployment.yaml │ ├── .helmignore │ ├── Chart.yaml │ └── values.yaml └── test-values │ ├── test-tls-with-secret.yaml │ ├── test-tls-no-secret.yaml │ ├── saleor-omit-tls.yaml │ ├── saleor-no-tls.yaml │ ├── saleor-local-tls.yaml │ ├── saleor-global-tls.yaml │ ├── saleor-apps-no-tls.yaml │ ├── saleor-apps-omit-tls.yaml │ ├── saleor-apps-global-tls.yaml │ ├── saleor-apps-local-tls.yaml │ ├── saleor-apps-example-prod.yaml │ └── saleor-apps-custom.yaml ├── .github └── workflows │ └── helm.yml ├── private.pem └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | values_* 2 | .notes -------------------------------------------------------------------------------- /charts/saleor/charts/redis-22.0.7.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trieb-work/helm-charts/HEAD/charts/saleor/charts/redis-22.0.7.tgz -------------------------------------------------------------------------------- /charts/saleor-apps/charts/redis-0.6.4.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trieb-work/helm-charts/HEAD/charts/saleor-apps/charts/redis-0.6.4.tgz -------------------------------------------------------------------------------- /charts/strapi/charts/postgresql-13.2.9.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trieb-work/helm-charts/HEAD/charts/strapi/charts/postgresql-13.2.9.tgz -------------------------------------------------------------------------------- /charts/saleor/charts/postgresql-12.12.5.tgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trieb-work/helm-charts/HEAD/charts/saleor/charts/postgresql-12.12.5.tgz -------------------------------------------------------------------------------- /charts/saleor-apps/docs/images/marketplaceImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trieb-work/helm-charts/HEAD/charts/saleor-apps/docs/images/marketplaceImage.png -------------------------------------------------------------------------------- /charts/strapi/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://charts.bitnami.com/bitnami 4 | version: 13.2.9 5 | digest: sha256:dc1310557bc7c31b429f36615c584bbb97148ff4075b4a85882905e70235405e 6 | generated: "2023-11-15T11:49:39.33788+01:00" 7 | -------------------------------------------------------------------------------- /charts/saleor-apps/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: redis 3 | repository: oci://registry-1.docker.io/cloudpirates 4 | version: 0.6.4 5 | digest: sha256:fa735fc81401d78e3e011535b15b3f90d7bd12d45fe7f92730c07827d748f725 6 | generated: "2025-10-13T22:33:23.174772+02:00" 7 | -------------------------------------------------------------------------------- /charts/saleor/templates/imageSecret.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.imageCredentials.enabled }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: generated 6 | type: kubernetes.io/dockerconfigjson 7 | data: 8 | .dockerconfigjson: {{ template "imagePullSecret" . }} 9 | {{- end }} 10 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ include "saleor-apps.fullname" . }} 5 | labels: 6 | {{- include "saleor-apps.labels" . | nindent 4 }} 7 | type: Opaque 8 | data: 9 | secret-key: {{ .Values.global.secretKey | b64enc }} 10 | -------------------------------------------------------------------------------- /charts/saleor/test-values/minimal-values.yaml: -------------------------------------------------------------------------------- 1 | api: 2 | enabled: true 3 | replicaCount: 1 4 | 5 | dashboard: 6 | enabled: false 7 | 8 | worker: 9 | enabled: false 10 | 11 | postgresql: 12 | enabled: true 13 | architecture: standalone 14 | 15 | redis: 16 | enabled: true 17 | architecture: standalone 18 | -------------------------------------------------------------------------------- /charts/saleor/test-values/minimal-test.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | secretKey: "test-secret-key-123" 3 | database: 4 | url: "postgres://postgres:postgres@localhost:5432/saleor" 5 | 6 | api: 7 | enabled: true 8 | 9 | worker: 10 | enabled: true 11 | 12 | redis: 13 | enabled: true 14 | auth: 15 | enabled: false 16 | -------------------------------------------------------------------------------- /charts/saleor/Chart.lock: -------------------------------------------------------------------------------- 1 | dependencies: 2 | - name: postgresql 3 | repository: https://charts.bitnami.com/bitnami 4 | version: 12.12.5 5 | - name: redis 6 | repository: https://charts.bitnami.com/bitnami 7 | version: 22.0.7 8 | digest: sha256:a8d2019e0f2581ccc1a6e3e3dddcb339255da14d138702a730b88164ab392d74 9 | generated: "2025-10-13T11:38:25.851546+02:00" 10 | -------------------------------------------------------------------------------- /charts/saleor/test-values/redis-internal.yaml: -------------------------------------------------------------------------------- 1 | # Test case: Internal Redis with authentication 2 | global: 3 | secretKey: "test-secret-key" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | 7 | redis: 8 | enabled: true 9 | auth: 10 | enabled: true 11 | password: "test-password" 12 | architecture: standalone 13 | -------------------------------------------------------------------------------- /charts/saleor/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "saleor.serviceAccountName" . }} 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /charts/strapi/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "strapi.serviceAccountName" . }} 6 | labels: 7 | {{- include "strapi.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /charts/saleor/test-values/redis-external.yaml: -------------------------------------------------------------------------------- 1 | # Test case: External Redis with password authentication 2 | global: 3 | secretKey: "test-secret-key" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | 7 | redis: 8 | enabled: false 9 | external: 10 | host: "my-redis.example.com" 11 | port: 6379 12 | password: "external-password" 13 | tls: 14 | enabled: false 15 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/serviceaccount.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.serviceAccount.create -}} 2 | apiVersion: v1 3 | kind: ServiceAccount 4 | metadata: 5 | name: {{ include "gtm-server-container-cluster.serviceAccountName" . }} 6 | labels: 7 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 8 | {{- with .Values.serviceAccount.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /charts/saleor/test-values/redis-external-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case: External Redis with TLS and username/password authentication 2 | global: 3 | secretKey: "test-secret-key" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | 7 | redis: 8 | enabled: false 9 | external: 10 | host: "my-redis.example.com" 11 | port: 6379 12 | username: "redis-user" 13 | password: "external-password" 14 | tls: 15 | enabled: true 16 | -------------------------------------------------------------------------------- /charts/saleor/test-values/redis-sentinel.yaml: -------------------------------------------------------------------------------- 1 | # Test case: Redis with Sentinel architecture 2 | global: 3 | secretKey: "test-secret-key" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | 7 | redis: 8 | enabled: true 9 | architecture: replication 10 | auth: 11 | enabled: true 12 | password: "test-password" 13 | sentinel: 14 | enabled: true 15 | masterSet: "mymaster" 16 | replica: 17 | replicaCount: 2 18 | -------------------------------------------------------------------------------- /charts/saleor/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/strapi/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/saleor/test-values/redis-global-url.yaml: -------------------------------------------------------------------------------- 1 | # Test case: External Redis using global URLs 2 | global: 3 | secretKey: "test-secret-key" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | # Redis URL for general usage (database 0) 7 | redisUrl: "redis://user:pass@redis.example.com:6379/0" 8 | # Redis URL for Celery (database 1) 9 | celeryRedisUrl: "redis://user:pass@redis.example.com:6379/1" 10 | 11 | redis: 12 | enabled: false 13 | -------------------------------------------------------------------------------- /charts/strapi/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "strapi.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "strapi.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "strapi.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/.helmignore: -------------------------------------------------------------------------------- 1 | # Patterns to ignore when building packages. 2 | # This supports shell glob matching, relative path matching, and 3 | # negation (prefixed with !). Only one pattern per line. 4 | .DS_Store 5 | # Common VCS dirs 6 | .git/ 7 | .gitignore 8 | .bzr/ 9 | .bzrignore 10 | .hg/ 11 | .hgignore 12 | .svn/ 13 | # Common backup files 14 | *.swp 15 | *.bak 16 | *.tmp 17 | *.orig 18 | *~ 19 | # Various IDEs 20 | .project 21 | .idea/ 22 | *.tmproj 23 | .vscode/ 24 | -------------------------------------------------------------------------------- /charts/saleor/templates/gcs-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.storage.gcs.enabled .Values.storage.gcs.credentials.jsonKey }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-gcs-credentials 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | type: Opaque 9 | data: 10 | # Store the JSON key file content as a base64 encoded string 11 | credentials.json: {{ .Values.storage.gcs.credentials.jsonKey | b64enc | quote }} 12 | {{- end }} 13 | -------------------------------------------------------------------------------- /charts/saleor/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "saleor.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "saleor.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "saleor.fullname" . }}-api:{{ .Values.api.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /charts/saleor-apps/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: saleor-apps 3 | description: A Helm chart for deploying Saleor Apps with shared Redis and DynamoDB support for Avatax. Includes the official Saleor apps by default and allows to add custom apps. 4 | type: application 5 | version: 0.6.0 6 | appVersion: "1.0.0" 7 | maintainers: 8 | - name: trieb.work 9 | dependencies: 10 | - name: redis 11 | version: "0.6.4" 12 | repository: oci://registry-1.docker.io/cloudpirates 13 | condition: redis.enabled 14 | -------------------------------------------------------------------------------- /charts/saleor/test-values/external-redis-test.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | secretKey: "test-secret-key-123" 3 | database: 4 | url: "postgres://postgres:postgres@localhost:5432/saleor" 5 | 6 | api: 7 | enabled: true 8 | 9 | worker: 10 | enabled: true 11 | 12 | redis: 13 | enabled: false 14 | external: 15 | host: "my-redis.example.com" 16 | port: 6379 17 | username: "myuser" 18 | password: "mypassword" 19 | tls: 20 | enabled: true 21 | database: "0" 22 | celeryDatabase: "1" 23 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/marketplace-service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.marketplace.enabled }} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ .Release.Name }}-marketplace 6 | labels: 7 | {{- include "saleor-apps.labels" . | nindent 4 }} 8 | spec: 9 | ports: 10 | - port: 80 11 | targetPort: http 12 | protocol: TCP 13 | name: http 14 | selector: 15 | {{- include "saleor-apps.selectorLabels" . | nindent 4 }} 16 | app.kubernetes.io/component: marketplace 17 | {{- end }} 18 | -------------------------------------------------------------------------------- /charts/saleor/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "saleor.fullname" . }}-api 5 | labels: 6 | {{- include "saleor.labels" . | nindent 4 }} 7 | app.kubernetes.io/component: api 8 | spec: 9 | type: {{ .Values.api.service.type }} 10 | ports: 11 | - port: {{ .Values.api.service.port }} 12 | targetPort: http 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "saleor.selectorLabels" . | nindent 4 }} 17 | app.kubernetes.io/component: api 18 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/tests/test-connection.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Pod 3 | metadata: 4 | name: "{{ include "gtm-server-container-cluster.fullname" . }}-test-connection" 5 | labels: 6 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 7 | annotations: 8 | "helm.sh/hook": test 9 | spec: 10 | containers: 11 | - name: wget 12 | image: busybox 13 | command: ['wget'] 14 | args: ['{{ include "gtm-server-container-cluster.fullname" . }}:{{ .Values.service.port }}'] 15 | restartPolicy: Never 16 | -------------------------------------------------------------------------------- /charts/saleor/templates/s3-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.storage.s3.enabled }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-s3-credentials 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | type: Opaque 9 | data: 10 | {{- if .Values.storage.s3.credentials.accessKeyId }} 11 | AWS_ACCESS_KEY_ID: {{ .Values.storage.s3.credentials.accessKeyId | b64enc | quote }} 12 | {{- end }} 13 | {{- if .Values.storage.s3.credentials.secretAccessKey }} 14 | AWS_SECRET_ACCESS_KEY: {{ .Values.storage.s3.credentials.secretAccessKey | b64enc | quote }} 15 | {{- end }} 16 | {{- end }} 17 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/_redis-helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Generate Redis URL based on configuration 3 | Priority: 4 | 1. global.redisUrl if set 5 | 2. Internal Redis URL with password if redis.enabled=true 6 | */}} 7 | {{- define "saleor-apps.redis.url" -}} 8 | {{- if .Values.global.redisUrl -}} 9 | {{- .Values.global.redisUrl -}} 10 | {{- else -}} 11 | {{- $redisHost := printf "%s-redis" .Release.Name -}} 12 | {{- if .Values.redis.auth.enabled -}} 13 | {{- printf "redis://:%s@%s:6379" .Values.redis.auth.password $redisHost -}} 14 | {{- else -}} 15 | {{- printf "redis://%s:6379" $redisHost -}} 16 | {{- end -}} 17 | {{- end -}} 18 | {{- end -}} 19 | -------------------------------------------------------------------------------- /charts/saleor/templates/dashboard_service.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.dashboard.enabled -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-dashboard 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: dashboard 9 | spec: 10 | type: {{ .Values.dashboard.service.type }} 11 | ports: 12 | - port: {{ .Values.dashboard.service.port }} 13 | targetPort: http 14 | protocol: TCP 15 | name: http 16 | selector: 17 | {{- include "saleor.selectorLabels" . | nindent 4 }} 18 | app.kubernetes.io/component: dashboard 19 | {{- end }} 20 | -------------------------------------------------------------------------------- /charts/test-values/test-tls-with-secret.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | secretKey: "test-secret-key-for-testing-purposes-only" 3 | tls: 4 | enabled: true 5 | secretName: "global-tls-secret" 6 | 7 | ingress: 8 | enabled: true 9 | className: "nginx" 10 | api: 11 | enabled: true 12 | hosts: 13 | - host: saleor.example.com 14 | paths: 15 | - path: /graphql/ 16 | pathType: Prefix 17 | - path: /thumbnail/ 18 | pathType: Prefix 19 | - path: /.well-known/jwks.json 20 | pathType: Exact 21 | # Explicitly removing default TLS section 22 | tls: [] 23 | 24 | dashboard: 25 | enabled: true 26 | -------------------------------------------------------------------------------- /charts/test-values/test-tls-no-secret.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | secretKey: "test-secret-key-for-testing-purposes-only" 3 | tls: 4 | enabled: true 5 | # No secretName specified to test fallback certificate 6 | 7 | ingress: 8 | enabled: true 9 | className: "nginx" 10 | api: 11 | enabled: true 12 | hosts: 13 | - host: saleor.example.com 14 | paths: 15 | - path: /graphql/ 16 | pathType: Prefix 17 | - path: /thumbnail/ 18 | pathType: Prefix 19 | - path: /.well-known/jwks.json 20 | pathType: Exact 21 | # Explicitly removing default TLS section 22 | tls: [] 23 | 24 | dashboard: 25 | enabled: true 26 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- range $appName, $appConfig := .Values.apps }} 2 | {{- if $appConfig.enabled }} 3 | --- 4 | apiVersion: v1 5 | kind: Service 6 | metadata: 7 | name: {{ printf "%s-%s" (include "saleor-apps.fullname" $) $appName }} 8 | labels: 9 | {{- include "saleor-apps.labels" $ | nindent 4 }} 10 | app.kubernetes.io/component: {{ $appName }} 11 | spec: 12 | type: ClusterIP 13 | ports: 14 | - port: {{ $appConfig.port }} 15 | targetPort: http 16 | protocol: TCP 17 | name: http 18 | selector: 19 | {{- include "saleor-apps.selectorLabels" $ | nindent 4 }} 20 | app.kubernetes.io/component: {{ $appName }} 21 | {{- end }} 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /charts/saleor/test-values/external-db-values.yaml: -------------------------------------------------------------------------------- 1 | api: 2 | enabled: true 3 | replicaCount: 2 4 | resources: 5 | limits: 6 | cpu: "1" 7 | memory: "1Gi" 8 | requests: 9 | cpu: "500m" 10 | memory: "512Mi" 11 | 12 | dashboard: 13 | enabled: true 14 | replicaCount: 1 15 | 16 | worker: 17 | enabled: true 18 | replicaCount: 1 19 | 20 | postgresql: 21 | enabled: false 22 | 23 | global: 24 | secretKey: "test-secret-key-123" 25 | database: 26 | primaryUrl: "postgres://saleor:password@external-db.example.com:5432/saleor" 27 | maxConnections: 150 28 | connectionTimeout: 5 29 | 30 | redis: 31 | enabled: true 32 | auth: 33 | enabled: true 34 | architecture: standalone 35 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/dynamodb-service.yaml: -------------------------------------------------------------------------------- 1 | {{- if (index .Values.apps "app-avatax") }} 2 | {{- if (get (index .Values.apps "app-avatax") "enabled") }} 3 | {{- if (get (index .Values.apps "app-avatax") "dynamodb").enabled }} 4 | apiVersion: v1 5 | kind: Service 6 | metadata: 7 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" .) }} 8 | labels: 9 | {{- include "saleor-apps.labels" . | nindent 4 }} 10 | app.kubernetes.io/component: dynamodb 11 | spec: 12 | type: ClusterIP 13 | ports: 14 | - port: 8000 15 | targetPort: http 16 | protocol: TCP 17 | name: http 18 | selector: 19 | {{- include "saleor-apps.selectorLabels" . | nindent 4 }} 20 | app.kubernetes.io/component: dynamodb 21 | {{- end }} 22 | {{- end }} 23 | {{- end }} 24 | -------------------------------------------------------------------------------- /charts/saleor/test-values/redis-test.yaml: -------------------------------------------------------------------------------- 1 | # Test 1: Using internal Redis (default configuration) 2 | global: 3 | secretKey: "test-secret-key" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | 7 | --- 8 | # Test 2: Using external Redis URLs 9 | global: 10 | secretKey: "test-secret-key" 11 | database: 12 | url: "postgres://postgres:postgres@localhost:5432/saleor" 13 | redisUrl: "redis://external-redis:6379/0" 14 | celeryRedisUrl: "redis://external-redis:6379/1" 15 | redis: 16 | enabled: false 17 | 18 | --- 19 | # Test 3: Using external Redis with authentication 20 | global: 21 | secretKey: "test-secret-key" 22 | database: 23 | url: "postgres://postgres:postgres@localhost:5432/saleor" 24 | redisUrl: "redis://user:pass@external-redis:6379/0" 25 | celeryRedisUrl: "redis://user:pass@external-redis:6379/1" 26 | redis: 27 | enabled: false 28 | -------------------------------------------------------------------------------- /.github/workflows/helm.yml: -------------------------------------------------------------------------------- 1 | name: Release Charts 2 | 3 | on: 4 | push: 5 | branches: 6 | - main 7 | 8 | jobs: 9 | release: 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Checkout 13 | uses: actions/checkout@v4 14 | with: 15 | fetch-depth: 0 16 | 17 | - name: Configure Git 18 | run: | 19 | git config user.name "$GITHUB_ACTOR" 20 | git config user.email "$GITHUB_ACTOR@users.noreply.github.com" 21 | 22 | - name: Install Helm 23 | uses: azure/setup-helm@v4 24 | with: 25 | version: v3.4.0 26 | 27 | - name: Adding Helm Dependencies 28 | run: | 29 | helm repo add bitnami https://charts.bitnami.com/bitnami 30 | 31 | - name: Run chart-releaser 32 | uses: helm/chart-releaser-action@v1.7.0 33 | env: 34 | CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}" -------------------------------------------------------------------------------- /charts/saleor/templates/istio_virtual_service.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.serviceMesh.enabled .Values.serviceMesh.istio.enabled }} 2 | apiVersion: networking.istio.io/v1alpha3 3 | kind: VirtualService 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-api 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | spec: 9 | hosts: 10 | - {{ include "saleor.fullname" . }}-api 11 | http: 12 | - route: 13 | - destination: 14 | host: {{ include "saleor.fullname" . }}-api 15 | {{- if .Values.serviceMesh.istio.api.timeout.enabled }} 16 | timeout: {{ .Values.serviceMesh.istio.api.timeout.http }} 17 | {{- end }} 18 | retries: 19 | attempts: {{ .Values.serviceMesh.istio.api.circuitBreaker.maxRetries }} 20 | perTryTimeout: "2s" 21 | retryOn: "connect-failure,refused-stream,unavailable,cancelled,retriable-status-codes" 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /charts/strapi/templates/service.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Service 3 | metadata: 4 | name: {{ include "strapi.fullname" . }} 5 | labels: 6 | {{- include "strapi.labels" . | nindent 4 }} 7 | app.kubernetes.io/role: primary 8 | spec: 9 | type: {{ .Values.service.type }} 10 | ports: 11 | - port: {{ .Values.service.port }} 12 | targetPort: http 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "strapi.selectorLabels" . | nindent 4 }} 17 | {{- if .Values.readReplica.enabled }} 18 | # If we have Values.readReplica.enabled set to true, we will create a read replica service 19 | --- 20 | apiVersion: v1 21 | kind: Service 22 | metadata: 23 | name: {{ include "strapi.fullname" . }}-all 24 | labels: 25 | {{- include "strapi.labels" . | nindent 4 }} 26 | spec: 27 | type: {{ .Values.service.type }} 28 | ports: 29 | - port: {{ .Values.service.port }} 30 | targetPort: http 31 | protocol: TCP 32 | name: http 33 | selector: 34 | {{- include "strapi.selectorLabels" . | nindent 4 }} 35 | {{- end }} 36 | -------------------------------------------------------------------------------- /charts/saleor/templates/postgresql_credentials.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.postgresql.enabled }} 2 | apiVersion: v1 3 | kind: Secret 4 | metadata: 5 | name: postgresql-credentials 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | annotations: 9 | helm.sh/resource-policy: keep 10 | helm.sh/hook: pre-install 11 | type: Opaque 12 | data: 13 | {{- if .Values.postgresql.auth.postgresPassword }} 14 | postgresql-password: {{ .Values.postgresql.auth.postgresPassword | b64enc | quote }} 15 | replication-password: {{ .Values.postgresql.auth.replicationPassword | default (randAlphaNum 32) | b64enc | quote }} 16 | {{- else }} 17 | {{- $secret := lookup "v1" "Secret" .Release.Namespace "postgresql-credentials" }} 18 | {{- if $secret }} 19 | postgresql-password: {{ index $secret.data "postgresql-password" | quote }} 20 | replication-password: {{ index $secret.data "replication-password" | quote }} 21 | {{- else }} 22 | {{- fail "You must set .Values.postgresql.auth.postgresPassword on first install!" }} 23 | {{- end }} 24 | {{- end }} 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/service.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullName := include "gtm-server-container-cluster.fullname" . -}} 2 | apiVersion: v1 3 | kind: Service 4 | metadata: 5 | name: {{ include "gtm-server-container-cluster.fullname" . }} 6 | labels: 7 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 8 | spec: 9 | type: {{ .Values.service.type }} 10 | ports: 11 | - port: {{ .Values.service.port }} 12 | targetPort: http 13 | protocol: TCP 14 | name: http 15 | selector: 16 | {{- include "gtm-server-container-cluster.selectorLabels" . | nindent 4 }} 17 | app.kubernetes.io/type: "tagging" 18 | --- 19 | apiVersion: v1 20 | kind: Service 21 | metadata: 22 | name: "{{ $fullName }}-preview" 23 | labels: 24 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 25 | spec: 26 | type: {{ .Values.service.type }} 27 | ports: 28 | - port: {{ .Values.service.port }} 29 | targetPort: http 30 | protocol: TCP 31 | name: http 32 | selector: 33 | app.kubernetes.io/type: "preview" 34 | 35 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/dynamodb-secret.yaml: -------------------------------------------------------------------------------- 1 | {{- if (index .Values.apps "app-avatax") }} 2 | {{- if (get (index .Values.apps "app-avatax") "enabled") }} 3 | {{- if (get (index .Values.apps "app-avatax") "dynamodb").enabled }} 4 | apiVersion: v1 5 | kind: Secret 6 | metadata: 7 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" .) }} 8 | labels: 9 | {{- include "saleor-apps.labels" . | nindent 4 }} 10 | app.kubernetes.io/component: dynamodb 11 | type: Opaque 12 | data: 13 | {{- if (get (get (index .Values.apps "app-avatax") "dynamodb") "accessKeyId") }} 14 | access-key-id: {{ (get (get (index .Values.apps "app-avatax") "dynamodb") "accessKeyId") | b64enc }} 15 | {{- else }} 16 | access-key-id: {{ "dynamodb-local" | b64enc }} 17 | {{- end }} 18 | {{- if (get (get (index .Values.apps "app-avatax") "dynamodb") "secretAccessKey") }} 19 | secret-access-key: {{ (get (get (index .Values.apps "app-avatax") "dynamodb") "secretAccessKey") | b64enc }} 20 | {{- else }} 21 | secret-access-key: {{ "dynamodb-local" | b64enc }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | {{- end }} 26 | -------------------------------------------------------------------------------- /charts/strapi/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.autoscaling.enabled }} 2 | apiVersion: autoscaling/v2 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "strapi.fullname" . }} 6 | labels: 7 | {{- include "strapi.labels" . | nindent 4 }} 8 | spec: 9 | scaleTargetRef: 10 | apiVersion: apps/v1 11 | kind: Deployment 12 | name: {{ include "strapi.fullname" . }} 13 | minReplicas: {{ .Values.autoscaling.minReplicas }} 14 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 15 | metrics: 16 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 17 | - type: Resource 18 | resource: 19 | name: cpu 20 | target: 21 | averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 22 | type: Utilization 23 | {{- end }} 24 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 25 | - type: Resource 26 | resource: 27 | name: memory 28 | target: 29 | averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 30 | type: Utilization 31 | {{- end }} 32 | {{- end }} 33 | -------------------------------------------------------------------------------- /charts/strapi/templates/secret.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v1 2 | kind: Secret 3 | metadata: 4 | name: {{ include "strapi.fullname" . }} 5 | type: Opaque 6 | data: 7 | ADMIN_JWT_SECRET: {{ .Values.adminJWTSecret | b64enc | quote }} 8 | {{ if .Values.secrets.databaseUrl }} 9 | DATABASE_URL: {{ .Values.secrets.databaseUrl | b64enc | quote }} 10 | {{ end }} 11 | {{ if .Values.postgresql.enabled }} 12 | DATABASE_URL: {{ include "strapi.internalDatabaseUrl" . | b64enc | quote }} 13 | POSTGRES_DB_PASSWORD: {{ .Values.postgresql.auth.password | b64enc | quote }} 14 | POSTGRES_DB_USER: {{ .Values.postgresql.auth.username | b64enc | quote }} 15 | {{ end }} 16 | {{ if .Values.s3.enabled }} 17 | AWS_ACCESS_KEY_ID: {{ .Values.s3.accesKeyId | b64enc | quote }} 18 | AWS_SECRET_ACCESS_KEY: {{ .Values.s3.accessSecret | b64enc | quote }} 19 | AWS_ENDPOINT: {{ .Values.s3.endpoint | b64enc | quote }} 20 | AWS_BUCKET: {{ .Values.s3.bucket | b64enc | quote }} 21 | {{ end }} 22 | {{ if .Values.r2.enabled }} 23 | CF_ACCESS_KEY_ID: {{ .Values.r2.accesKeyId | b64enc | quote }} 24 | CF_SECRET_ACCESS_KEY: {{ .Values.r2.accessSecret | b64enc | quote }} 25 | CF_ENDPOINT: {{ .Values.r2.endpoint | b64enc | quote }} 26 | CF_BUCKET: {{ .Values.r2.bucket | b64enc | quote }} 27 | {{ end }} -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: gtm-server-container-cluster 3 | description: A Helm chart for Kubernetes 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.1.8 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | -------------------------------------------------------------------------------- /charts/saleor/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: saleor 3 | description: A Helm chart for deploying Saleor e-commerce platform with Dashboard 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | version: 2.3.9 18 | appVersion: "3.21.8" 19 | 20 | maintainers: 21 | - name: trieb.work 22 | email: info@trieb.work 23 | 24 | keywords: 25 | - saleor 26 | - ecommerce 27 | - graphql 28 | - dashboard 29 | 30 | dependencies: 31 | - name: postgresql 32 | repository: https://charts.bitnami.com/bitnami 33 | version: "12.12.5" 34 | condition: postgresql.enabled 35 | - name: redis 36 | repository: https://charts.bitnami.com/bitnami 37 | version: "22.0.7" 38 | condition: redis.enabled 39 | -------------------------------------------------------------------------------- /charts/test-values/saleor-omit-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor with TLS settings completely omitted 2 | global: 3 | secretKey: "test-secret-key" 4 | # No TLS configuration at all 5 | 6 | # PostgreSQL configuration 7 | postgresql: 8 | enabled: true 9 | architecture: standalone 10 | auth: 11 | database: postgres 12 | postgresPassword: "test-postgres-password" 13 | existingSecret: postgresql-credentials 14 | 15 | # Redis configuration 16 | redis: 17 | enabled: true 18 | architecture: standalone 19 | auth: 20 | enabled: true 21 | password: "test-redis-password" 22 | 23 | # Ingress configuration 24 | ingress: 25 | enabled: true 26 | className: "nginx" 27 | 28 | api: 29 | enabled: true 30 | annotations: {} 31 | hosts: 32 | - host: api-test-saleor.eu.fsn1.trwrk.xyz 33 | paths: 34 | - path: /graphql/ 35 | pathType: Prefix 36 | - path: /thumbnail/ 37 | pathType: Prefix 38 | - path: /.well-known/jwks.json 39 | pathType: Exact 40 | # No TLS configuration at all 41 | 42 | dashboard: 43 | enabled: true 44 | annotations: {} 45 | hosts: 46 | - host: dashboard-test-saleor.eu.fsn1.trwrk.xyz 47 | paths: 48 | - path: / 49 | pathType: Prefix 50 | # No TLS configuration at all 51 | -------------------------------------------------------------------------------- /charts/saleor/templates/istio_destination_rule.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.serviceMesh.enabled .Values.serviceMesh.istio.enabled }} 2 | apiVersion: networking.istio.io/v1alpha3 3 | kind: DestinationRule 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-api 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | spec: 9 | host: {{ include "saleor.fullname" . }}-api 10 | trafficPolicy: 11 | {{- if .Values.serviceMesh.istio.api.connectionPool.enabled }} 12 | connectionPool: 13 | http: 14 | http1MaxPendingRequests: {{ .Values.serviceMesh.istio.api.connectionPool.http1MaxPendingRequests }} 15 | maxRequestsPerConnection: {{ .Values.serviceMesh.istio.api.connectionPool.maxRequestsPerConnection }} 16 | {{- end }} 17 | {{- if .Values.serviceMesh.istio.api.outlierDetection.enabled }} 18 | outlierDetection: 19 | consecutive5xxErrors: {{ .Values.serviceMesh.istio.api.outlierDetection.consecutiveErrors }} 20 | interval: {{ .Values.serviceMesh.istio.api.outlierDetection.interval }} 21 | baseEjectionTime: {{ .Values.serviceMesh.istio.api.outlierDetection.baseEjectionTime }} 22 | maxEjectionPercent: {{ .Values.serviceMesh.istio.api.outlierDetection.maxEjectionPercent }} 23 | {{- end }} 24 | {{- if .Values.serviceMesh.istio.api.loadBalancer.enabled }} 25 | loadBalancer: 26 | simple: LEAST_REQUEST 27 | {{- end }} 28 | {{- end }} 29 | -------------------------------------------------------------------------------- /charts/strapi/Chart.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: v2 2 | name: strapi 3 | description: A Helm chart for Strapi Headless API 4 | 5 | # A chart can be either an 'application' or a 'library' chart. 6 | # 7 | # Application charts are a collection of templates that can be packaged into versioned archives 8 | # to be deployed. 9 | # 10 | # Library charts provide useful utilities or functions for the chart developer. They're included as 11 | # a dependency of application charts to inject those utilities and functions into the rendering 12 | # pipeline. Library charts do not define any templates and therefore cannot be deployed. 13 | type: application 14 | 15 | # This is the chart version. This version number should be incremented each time you make changes 16 | # to the chart and its templates, including the app version. 17 | # Versions are expected to follow Semantic Versioning (https://semver.org/) 18 | version: 0.2.7 19 | 20 | # This is the version number of the application being deployed. This version number should be 21 | # incremented each time you make changes to the application. Versions are not expected to 22 | # follow Semantic Versioning. They should reflect the version the application is using. 23 | # It is recommended to use it with quotes. 24 | appVersion: "1.16.0" 25 | 26 | dependencies: 27 | - name: postgresql 28 | repository: "https://charts.bitnami.com/bitnami" 29 | version: "13.2.9" 30 | condition: postgresql.enabled 31 | -------------------------------------------------------------------------------- /charts/test-values/saleor-no-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor with TLS completely disabled 2 | global: 3 | secretKey: "test-secret-key" 4 | # Global TLS configuration disabled 5 | tls: 6 | enabled: false 7 | secretName: "" 8 | 9 | # PostgreSQL configuration 10 | postgresql: 11 | enabled: true 12 | architecture: standalone 13 | auth: 14 | database: postgres 15 | postgresPassword: "test-postgres-password" 16 | existingSecret: postgresql-credentials 17 | 18 | # Redis configuration 19 | redis: 20 | enabled: true 21 | architecture: standalone 22 | auth: 23 | enabled: true 24 | password: "test-redis-password" 25 | 26 | # Ingress configuration 27 | ingress: 28 | enabled: true 29 | className: "nginx" 30 | 31 | api: 32 | enabled: true 33 | annotations: {} 34 | hosts: 35 | - host: api-test-saleor.eu.fsn1.trwrk.xyz 36 | paths: 37 | - path: /graphql/ 38 | pathType: Prefix 39 | - path: /thumbnail/ 40 | pathType: Prefix 41 | - path: /.well-known/jwks.json 42 | pathType: Exact 43 | # No TLS configuration at all 44 | tls: [] 45 | 46 | dashboard: 47 | enabled: true 48 | annotations: {} 49 | hosts: 50 | - host: dashboard-test-saleor.eu.fsn1.trwrk.xyz 51 | paths: 52 | - path: / 53 | pathType: Prefix 54 | # No TLS configuration at all 55 | tls: [] 56 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "saleor-apps.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create chart name and version as used by the chart label. 10 | */}} 11 | {{- define "saleor-apps.chart" -}} 12 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 13 | {{- end }} 14 | 15 | {{/* 16 | Create a default fully qualified app name. 17 | */}} 18 | {{- define "saleor-apps.fullname" -}} 19 | {{- if .Values.fullnameOverride }} 20 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 21 | {{- else }} 22 | {{- $name := default .Chart.Name .Values.nameOverride }} 23 | {{- if contains $name .Release.Name }} 24 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 25 | {{- else }} 26 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 27 | {{- end }} 28 | {{- end }} 29 | {{- end }} 30 | 31 | {{/* 32 | Common labels 33 | */}} 34 | {{- define "saleor-apps.labels" -}} 35 | helm.sh/chart: {{ include "saleor-apps.chart" . }} 36 | {{ include "saleor-apps.selectorLabels" . }} 37 | {{- if .Chart.AppVersion }} 38 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 39 | {{- end }} 40 | app.kubernetes.io/managed-by: {{ .Release.Service }} 41 | {{- end }} 42 | 43 | {{/* 44 | Selector labels 45 | */}} 46 | {{- define "saleor-apps.selectorLabels" -}} 47 | app.kubernetes.io/name: {{ include "saleor-apps.name" . }} 48 | app.kubernetes.io/instance: {{ .Release.Name }} 49 | {{- end }} 50 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/marketplace-ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if and .Values.marketplace.enabled .Values.marketplace.ingress.enabled }} 2 | apiVersion: networking.k8s.io/v1 3 | kind: Ingress 4 | metadata: 5 | name: {{ .Release.Name }}-marketplace 6 | labels: 7 | {{- include "saleor-apps.labels" . | nindent 4 }} 8 | {{- with .Values.marketplace.ingress.annotations }} 9 | annotations: 10 | {{- toYaml . | nindent 4 }} 11 | {{- end }} 12 | spec: 13 | {{- if .Values.marketplace.ingress.className }} 14 | ingressClassName: {{ .Values.marketplace.ingress.className }} 15 | {{- end }} 16 | {{- $globalTlsEnabled := and (hasKey .Values.global "tls") (hasKey .Values.global.tls "enabled") .Values.global.tls.enabled -}} 17 | {{- $marketplaceTlsEnabled := and (hasKey .Values.marketplace.ingress "tls") (hasKey .Values.marketplace.ingress.tls "enabled") .Values.marketplace.ingress.tls.enabled -}} 18 | {{- if or $globalTlsEnabled $marketplaceTlsEnabled }} 19 | tls: 20 | - hosts: 21 | - {{ .Values.marketplace.hostname | quote }} 22 | {{- if $globalTlsEnabled }} 23 | secretName: {{ .Values.global.tls.secretName }} 24 | {{- else }} 25 | secretName: {{ default (printf "%s-marketplace-tls" .Release.Name) .Values.marketplace.ingress.tls.secretName }} 26 | {{- end }} 27 | {{- end }} 28 | rules: 29 | - host: {{ .Values.marketplace.hostname | quote }} 30 | http: 31 | paths: 32 | - path: / 33 | pathType: Prefix 34 | backend: 35 | service: 36 | name: {{ .Release.Name }}-marketplace 37 | port: 38 | name: http 39 | {{- end }} 40 | -------------------------------------------------------------------------------- /charts/saleor/templates/_gcs-env.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | GCS environment variables generated if GCS is enabled 3 | */}} 4 | {{- define "saleor.gcsEnv" -}} 5 | {{- if .Values.storage.gcs.enabled }} 6 | {{- if .Values.storage.gcs.config.staticBucketName }} 7 | - name: GS_BUCKET_NAME 8 | value: {{ .Values.storage.gcs.config.staticBucketName | quote }} 9 | {{- end }} 10 | {{- if .Values.storage.gcs.config.mediaBucketName }} 11 | - name: GS_MEDIA_BUCKET_NAME 12 | value: {{ .Values.storage.gcs.config.mediaBucketName | quote }} 13 | {{- end }} 14 | {{- if .Values.storage.gcs.config.mediaPrivateBucketName }} 15 | - name: GS_MEDIA_PRIVATE_BUCKET_NAME 16 | value: {{ .Values.storage.gcs.config.mediaPrivateBucketName | quote }} 17 | {{- end }} 18 | {{- if .Values.storage.gcs.config.customEndpoint }} 19 | - name: GS_CUSTOM_ENDPOINT 20 | value: {{ .Values.storage.gcs.config.customEndpoint | quote }} 21 | {{- end }} 22 | {{- if .Values.storage.gcs.config.mediaCustomEndpoint }} 23 | - name: GS_MEDIA_CUSTOM_ENDPOINT 24 | value: {{ .Values.storage.gcs.config.mediaCustomEndpoint | quote }} 25 | {{- end }} 26 | {{- if .Values.storage.gcs.config.defaultAcl }} 27 | - name: GS_DEFAULT_ACL 28 | value: {{ .Values.storage.gcs.config.defaultAcl | quote }} 29 | {{- end }} 30 | - name: GS_QUERYSTRING_AUTH 31 | value: {{ .Values.storage.gcs.config.queryStringAuth | ternary "True" "False" | quote }} 32 | {{- if .Values.storage.gcs.config.queryStringExpire }} 33 | - name: GS_EXPIRATION 34 | value: {{ .Values.storage.gcs.config.queryStringExpire | quote }} 35 | {{- end }} 36 | {{- if .Values.storage.gcs.credentials.jsonKey }} 37 | - name: GOOGLE_APPLICATION_CREDENTIALS 38 | value: "/var/secrets/google/credentials.json" 39 | {{- end }} 40 | {{- end }} 41 | {{- end -}} 42 | -------------------------------------------------------------------------------- /private.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCxW0n5Ihq++Fvl 3 | poeHWflJYEhN28RdU8eFidEjwEvUTYHPVidKSQAOsYlXcYflBjpQe6Ue2MAxDhb8 4 | hxgAvemrNbUtZDDa+O11RNZBhZ6AXBLyvQc8+nAoB/eS3o9BOvvC/gZjT4mu/xn7 5 | BimJWUjaq3x85wGAUxD12oyZ59gJkXZ4l2yeWw6HS50MHxAjfDwSB6awWQXVjOoK 6 | zogRAjBplVewqRuM4HrdC3J6r3W30oKZKdj3Bv5KSq2Dot/fFLdsX3COADZmt+ke 7 | c1AEFcjRlwjDYDgjzWzCEeGXn3CP4oSIRkVw9Dj+easdfGQeAjV9zIP/Rv3yMgic 8 | RoQypEgbAgMBAAECggEAPaP+Qj3FsPDNs7Pcr8CoIQX7K0BB77PSCQn8q6HGWRu1 9 | DZQiZLGZeQHgO4mEUyeGdfl7SozHw2TjvVHQmFVpFK2+ce+8ASb6FMNfefdQPsmB 10 | dmcXUGy0NV2LgLqkbGXtIXi7TKHUtwMHixS5s/hZl1J5mkmJXonAP8p9CnKnRa96 11 | KwX65smS5Rg5J/5ZDt+eja4IS9b6mGxxbP9fEzV5tK8pIjeMiNggBtyR6yEcAFcu 12 | jFV1KPOaIPK3XsVImebRRkCCf4Sfxp/Iwdz/F253jyKQaGcIrBR0TBCRWvuEvusj 13 | 8FFE9GowaESiSeV4a/TAjfSaZhdRaeYRyXjh7UbNOQKBgQDZCQMplmCB6J1e2yWD 14 | NZ9qcQvN86SaRKKQzNy7hMgFrH3c4iICK1meMr+orbDk66rMueI76qIWG13VapbO 15 | HVuZ3BuzNznbG86QHuHy0GAcnE+Ooxvj7VwYMjNFVtk1Hcrt+Tvv3OxJFhhYCTQq 16 | 1s3wf7NBff5IhFj03hb1Q/X94wKBgQDRMqOFFKmRr9McNQ9o+9vkd8qRnI1TUwVb 17 | pdd0H20KvpxKEFp7guNyLhAZfWMZM76Rv9UexZcScpYvxlHPTwi0INBbBiqLeNy1 18 | 5knBF0HO60vJazAUrSkY/RT/YFGHHqGj7Z8GfHdrnh9gy9kzIZLRnsh/Lt1kOrXA 19 | FuCxu40iaQKBgQCBBmOT6Kss784Goz+U1l8UV2pOIMc9UwpWDQQ4koKbJOWaV/Eh 20 | 2wWnD8JzE/cy0Iu0s9k0B5QeklxhUMGgfUGEoZ7yFyXVBZ3yffmTcZ+BwsdlI8Cj 21 | 6usyEz35vdzZQAHxIZcpTOxHstP8GlSiFxtNG43EpJN0JwH/aLy7SJDIQwKBgQCN 22 | HUuQic+YprIRZPlwJ/S8uNG8R45NlsMWf1hGzKwRg2KJ01410qT6cHgLubkPVwhF 23 | 6NEqYL73grQspeqpnPaSC1CBFje8vVqkmSNHTRjnK3GD/PoB+IywfoebfK2CJ/eB 24 | TNjo1yz3O0KPWPK6uvr+y80Tfdl5suDHIqePPKSHgQKBgQCJpVbifw84ECZDTKXw 25 | RVG9lHxHzeE64W9iDc4eghH+VoC9N2J9YlgMkS/iRV3PNjs3+xIDMjC97hfs8ukZ 26 | kN4J6aDBqrviva9BDbXVjQJA8J4IaYIGNsZLcBTgGTZJowALWMtA4xqdJ4EL8WlF 27 | GKhPR8cEPHwPsMWnkIel6s0ViQ== 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /charts/strapi/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "strapi.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "strapi.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "strapi.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "strapi.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 20 | echo "Visit http://127.0.0.1:8080 to use your application" 21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- range $appName, $appConfig := .Values.apps }} 2 | {{- if and $appConfig.enabled (hasKey $appConfig "ingress") (hasKey $appConfig.ingress "enabled") $appConfig.ingress.enabled }} 3 | --- 4 | apiVersion: networking.k8s.io/v1 5 | kind: Ingress 6 | metadata: 7 | name: {{ printf "%s-%s" (include "saleor-apps.fullname" $) $appName }} 8 | labels: 9 | {{- include "saleor-apps.labels" $ | nindent 4 }} 10 | app.kubernetes.io/component: {{ $appName }} 11 | {{- with $appConfig.ingress.annotations }} 12 | annotations: 13 | {{- toYaml . | nindent 4 }} 14 | {{- end }} 15 | spec: 16 | {{- if $appConfig.ingress.className }} 17 | ingressClassName: {{ $appConfig.ingress.className }} 18 | {{- end }} 19 | 20 | {{- $globalTlsEnabled := and (hasKey $.Values.global "tls") (hasKey $.Values.global.tls "enabled") $.Values.global.tls.enabled -}} 21 | {{- $appTlsEnabled := and (hasKey $appConfig.ingress "tls") (hasKey $appConfig.ingress.tls "enabled") $appConfig.ingress.tls.enabled -}} 22 | {{- if or $globalTlsEnabled $appTlsEnabled }} 23 | tls: 24 | - hosts: 25 | - {{ $appConfig.hostname | quote }} 26 | {{- if $globalTlsEnabled }} 27 | secretName: {{ $.Values.global.tls.secretName }} 28 | {{- else }} 29 | secretName: {{ $appConfig.ingress.tls.secretName | default (printf "%s-%s-tls" (include "saleor-apps.fullname" $) $appName) }} 30 | {{- end }} 31 | {{- end }} 32 | rules: 33 | - host: {{ $appConfig.hostname | quote }} 34 | http: 35 | paths: 36 | - path: / 37 | pathType: Prefix 38 | backend: 39 | service: 40 | name: {{ printf "%s-%s" (include "saleor-apps.fullname" $) $appName }} 41 | port: 42 | number: {{ $appConfig.port }} 43 | {{- end }} 44 | {{- end }} 45 | -------------------------------------------------------------------------------- /charts/test-values/saleor-local-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor with local TLS (no global TLS) 2 | global: 3 | secretKey: "test-secret-key" 4 | # Global TLS configuration disabled 5 | tls: 6 | enabled: false 7 | secretName: "" 8 | 9 | # PostgreSQL configuration 10 | postgresql: 11 | enabled: true 12 | architecture: standalone 13 | auth: 14 | database: postgres 15 | postgresPassword: "test-postgres-password" 16 | existingSecret: postgresql-credentials 17 | 18 | # Redis configuration 19 | redis: 20 | enabled: true 21 | architecture: standalone 22 | auth: 23 | enabled: true 24 | password: "test-redis-password" 25 | 26 | # Ingress configuration 27 | ingress: 28 | enabled: true 29 | className: "nginx" 30 | 31 | api: 32 | enabled: true 33 | annotations: 34 | cert-manager.io/cluster-issuer: letsencrypt-prod 35 | hosts: 36 | - host: api-test-saleor.eu.fsn1.trwrk.xyz 37 | paths: 38 | - path: /graphql/ 39 | pathType: Prefix 40 | - path: /thumbnail/ 41 | pathType: Prefix 42 | - path: /.well-known/jwks.json 43 | pathType: Exact 44 | # This TLS config should be used when global.tls.enabled is false 45 | tls: 46 | - secretName: saleor-api-specific-tls 47 | hosts: 48 | - api-test-saleor.eu.fsn1.trwrk.xyz 49 | 50 | dashboard: 51 | enabled: true 52 | annotations: 53 | cert-manager.io/cluster-issuer: letsencrypt-prod 54 | hosts: 55 | - host: dashboard-test-saleor.eu.fsn1.trwrk.xyz 56 | paths: 57 | - path: / 58 | pathType: Prefix 59 | # This TLS config should be used when global.tls.enabled is false 60 | tls: 61 | - secretName: saleor-dashboard-specific-tls 62 | hosts: 63 | - dashboard-test-saleor.eu.fsn1.trwrk.xyz 64 | -------------------------------------------------------------------------------- /charts/test-values/saleor-global-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor with global TLS enabled 2 | global: 3 | secretKey: "test-secret-key" 4 | # Global TLS configuration 5 | tls: 6 | enabled: true 7 | secretName: "wildcard-test-tls" 8 | 9 | # PostgreSQL configuration 10 | postgresql: 11 | enabled: true 12 | architecture: standalone 13 | auth: 14 | database: postgres 15 | postgresPassword: "test-postgres-password" 16 | existingSecret: postgresql-credentials 17 | 18 | # Redis configuration 19 | redis: 20 | enabled: true 21 | architecture: standalone 22 | auth: 23 | enabled: true 24 | password: "test-redis-password" 25 | 26 | # Ingress configuration 27 | ingress: 28 | enabled: true 29 | className: "nginx" 30 | 31 | api: 32 | enabled: true 33 | annotations: 34 | cert-manager.io/cluster-issuer: letsencrypt-prod 35 | hosts: 36 | - host: api-test-saleor.eu.fsn1.trwrk.xyz 37 | paths: 38 | - path: /graphql/ 39 | pathType: Prefix 40 | - path: /thumbnail/ 41 | pathType: Prefix 42 | - path: /.well-known/jwks.json 43 | pathType: Exact 44 | # This TLS config should be ignored when global.tls.enabled is true 45 | tls: 46 | - secretName: saleor-api-specific-tls 47 | hosts: 48 | - api-test-saleor.eu.fsn1.trwrk.xyz 49 | 50 | dashboard: 51 | enabled: true 52 | annotations: 53 | cert-manager.io/cluster-issuer: letsencrypt-prod 54 | hosts: 55 | - host: dashboard-test-saleor.eu.fsn1.trwrk.xyz 56 | paths: 57 | - path: / 58 | pathType: Prefix 59 | # This TLS config should be ignored when global.tls.enabled is true 60 | tls: 61 | - secretName: saleor-dashboard-specific-tls 62 | hosts: 63 | - dashboard-test-saleor.eu.fsn1.trwrk.xyz 64 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | 1. Get the application URL by running these commands: 2 | {{- if .Values.ingress.enabled }} 3 | {{- range $host := .Values.ingress.hosts }} 4 | {{- range .paths }} 5 | http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }} 6 | {{- end }} 7 | {{- end }} 8 | {{- else if contains "NodePort" .Values.service.type }} 9 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "gtm-server-container-cluster.fullname" . }}) 10 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 11 | echo http://$NODE_IP:$NODE_PORT 12 | {{- else if contains "LoadBalancer" .Values.service.type }} 13 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 14 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "gtm-server-container-cluster.fullname" . }}' 15 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "gtm-server-container-cluster.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 16 | echo http://$SERVICE_IP:{{ .Values.service.port }} 17 | {{- else if contains "ClusterIP" .Values.service.type }} 18 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "gtm-server-container-cluster.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}") 19 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 20 | echo "Visit http://127.0.0.1:8080 to use your application" 21 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 22 | {{- end }} 23 | -------------------------------------------------------------------------------- /charts/test-values/saleor-apps-no-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor-apps with TLS completely disabled 2 | global: 3 | secretKey: "test-secret-key" 4 | appLogLevel: "info" 5 | # Global TLS configuration disabled 6 | tls: 7 | enabled: false 8 | secretName: "" 9 | 10 | # Redis configuration 11 | redis: 12 | enabled: true 13 | architecture: standalone 14 | auth: 15 | enabled: true 16 | password: "test-redis-password" 17 | 18 | # Marketplace configuration 19 | marketplace: 20 | enabled: true 21 | hostname: marketplace-test-saleor.eu.fsn1.trwrk.xyz 22 | ingress: 23 | enabled: true 24 | annotations: {} 25 | tls: 26 | enabled: false 27 | secretName: "" 28 | 29 | # Individual app configurations 30 | apps: 31 | smtp: 32 | enabled: true 33 | hostname: smtp-test-saleor.eu.fsn1.trwrk.xyz 34 | ingress: 35 | annotations: {} 36 | tls: 37 | enabled: false 38 | secretName: "" 39 | 40 | products-feed: 41 | enabled: true 42 | hostname: products-feed-test-saleor.eu.fsn1.trwrk.xyz 43 | ingress: 44 | annotations: {} 45 | tls: 46 | enabled: false 47 | secretName: "" 48 | 49 | search: 50 | enabled: true 51 | hostname: search-test-saleor.eu.fsn1.trwrk.xyz 52 | ingress: 53 | annotations: {} 54 | tls: 55 | enabled: false 56 | secretName: "" 57 | 58 | app-avatax: 59 | enabled: true 60 | hostname: app-avatax-test-saleor.eu.fsn1.trwrk.xyz 61 | # Enable DynamoDB for Avatax 62 | dynamodb: 63 | enabled: true 64 | logsTableName: "avatax-client-logs" 65 | logsItemTtlInDays: 14 66 | region: "us-east-1" 67 | # Using dummy credentials for local DynamoDB 68 | accessKeyId: "dynamodb-local" 69 | secretAccessKey: "dynamodb-local" 70 | ingress: 71 | annotations: {} 72 | tls: 73 | enabled: false 74 | secretName: "" 75 | -------------------------------------------------------------------------------- /charts/saleor/templates/_s3-env.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | S3 environment variables generated if S3 is enabled 3 | */}} 4 | {{- define "saleor.s3Env" -}} 5 | {{- if .Values.storage.s3.enabled }} 6 | {{- if .Values.storage.s3.credentials.accessKeyId }} 7 | - name: AWS_ACCESS_KEY_ID 8 | value: {{ .Values.storage.s3.credentials.accessKeyId | quote }} 9 | {{- end }} 10 | {{- if .Values.storage.s3.credentials.secretAccessKey }} 11 | - name: AWS_SECRET_ACCESS_KEY 12 | value: {{ .Values.storage.s3.credentials.secretAccessKey | quote }} 13 | {{- end }} 14 | {{- if .Values.storage.s3.config.staticBucketName }} 15 | - name: AWS_STATIC_BUCKET_NAME 16 | value: {{ .Values.storage.s3.config.staticBucketName | quote }} 17 | {{- end }} 18 | {{- if .Values.storage.s3.config.mediaBucketName }} 19 | - name: AWS_MEDIA_BUCKET_NAME 20 | value: {{ .Values.storage.s3.config.mediaBucketName | quote }} 21 | {{- end }} 22 | {{- if .Values.storage.s3.config.mediaPrivateBucketName }} 23 | - name: AWS_MEDIA_PRIVATE_BUCKET_NAME 24 | value: {{ .Values.storage.s3.config.mediaPrivateBucketName | quote }} 25 | {{- end }} 26 | {{- if .Values.storage.s3.config.customDomain }} 27 | - name: AWS_STATIC_CUSTOM_DOMAIN 28 | value: {{ .Values.storage.s3.config.customDomain | quote }} 29 | {{- end }} 30 | {{- if .Values.storage.s3.config.mediaCustomDomain }} 31 | - name: AWS_MEDIA_CUSTOM_DOMAIN 32 | value: {{ .Values.storage.s3.config.mediaCustomDomain | quote }} 33 | {{- end }} 34 | {{- if .Values.storage.s3.config.defaultAcl }} 35 | - name: AWS_DEFAULT_ACL 36 | value: {{ .Values.storage.s3.config.defaultAcl | quote }} 37 | {{- end }} 38 | - name: AWS_QUERYSTRING_AUTH 39 | value: {{ .Values.storage.s3.config.queryStringAuth | ternary "True" "False" | quote }} 40 | - name: AWS_QUERYSTRING_EXPIRE 41 | value: {{ .Values.storage.s3.config.queryStringExpire | quote }} 42 | {{- if .Values.storage.s3.config.endpointUrl }} 43 | - name: AWS_S3_ENDPOINT_URL 44 | value: {{ .Values.storage.s3.config.endpointUrl | quote }} 45 | {{- end }} 46 | {{- end }} 47 | {{- end -}} 48 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "gtm-server-container-cluster.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 5 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 6 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 7 | {{- end }} 8 | {{- end }} 9 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 10 | apiVersion: networking.k8s.io/v1 11 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 12 | apiVersion: networking.k8s.io/v1beta1 13 | {{- else -}} 14 | apiVersion: extensions/v1beta1 15 | {{- end }} 16 | kind: Ingress 17 | metadata: 18 | name: {{ $fullName }} 19 | labels: 20 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 21 | annotations: 22 | {{- toYaml .Values.ingress.annotations | nindent 4 }} 23 | spec: 24 | {{- if .Values.ingress.className }} 25 | ingressClassName: {{ .Values.ingress.className }} 26 | {{- end }} 27 | tls: 28 | - hosts: 29 | {{- range .Values.ingress.rules }} 30 | - {{ lower .taggingHost | quote }} 31 | {{- end }} 32 | secretName: "{{ $fullName }}-tls-secret" 33 | rules: 34 | {{- range .Values.ingress.rules }} 35 | - host: {{ .taggingHost }} 36 | http: 37 | paths: 38 | - path: / 39 | pathType: {{ .pathType }} 40 | backend: 41 | service: 42 | name: {{ $fullName }} 43 | port: 44 | number: {{ $svcPort }} 45 | - path: /preview 46 | pathType: {{ .pathType }} 47 | backend: 48 | service: 49 | name: "{{ $fullName }}-preview" 50 | port: 51 | number: {{ $svcPort }} 52 | {{- end }} 53 | {{- end }} 54 | -------------------------------------------------------------------------------- /charts/test-values/saleor-apps-omit-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor-apps with TLS settings completely omitted 2 | global: 3 | secretKey: "test-secret-key" 4 | appLogLevel: "info" 5 | # No TLS configuration at all 6 | 7 | # Redis configuration 8 | redis: 9 | enabled: true 10 | architecture: standalone 11 | auth: 12 | enabled: true 13 | password: "test-redis-password" 14 | 15 | # Marketplace configuration 16 | marketplace: 17 | enabled: true 18 | hostname: marketplace-test-saleor.eu.fsn1.trwrk.xyz 19 | ingress: 20 | enabled: true 21 | annotations: {} 22 | # Need to explicitly disable TLS to override the default value 23 | tls: 24 | enabled: false 25 | 26 | # Individual app configurations 27 | apps: 28 | smtp: 29 | enabled: true 30 | hostname: smtp-test-saleor.eu.fsn1.trwrk.xyz 31 | ingress: 32 | annotations: {} 33 | # Need to explicitly disable TLS to override the default value 34 | tls: 35 | enabled: false 36 | 37 | products-feed: 38 | enabled: true 39 | hostname: products-feed-test-saleor.eu.fsn1.trwrk.xyz 40 | ingress: 41 | annotations: {} 42 | # Need to explicitly disable TLS to override the default value 43 | tls: 44 | enabled: false 45 | 46 | search: 47 | enabled: true 48 | hostname: search-test-saleor.eu.fsn1.trwrk.xyz 49 | ingress: 50 | annotations: {} 51 | # Need to explicitly disable TLS to override the default value 52 | tls: 53 | enabled: false 54 | 55 | app-avatax: 56 | enabled: true 57 | hostname: app-avatax-test-saleor.eu.fsn1.trwrk.xyz 58 | # Enable DynamoDB for Avatax 59 | dynamodb: 60 | enabled: true 61 | logsTableName: "avatax-client-logs" 62 | logsItemTtlInDays: 14 63 | region: "us-east-1" 64 | # Using dummy credentials for local DynamoDB 65 | accessKeyId: "dynamodb-local" 66 | secretAccessKey: "dynamodb-local" 67 | ingress: 68 | annotations: {} 69 | # Need to explicitly disable TLS to override the default value 70 | tls: 71 | enabled: false 72 | -------------------------------------------------------------------------------- /charts/saleor/templates/saleor_secrets.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullName := include "saleor.fullname" . -}} 2 | {{- $existingSecret := (lookup "v1" "Secret" .Release.Namespace (printf "%s-secrets" $fullName)) -}} 3 | 4 | apiVersion: v1 5 | kind: Secret 6 | metadata: 7 | name: {{ include "saleor.fullname" . }}-secrets 8 | labels: 9 | {{- include "saleor.labels" . | nindent 4 }} 10 | type: Opaque 11 | data: 12 | {{- if .Values.global.secretKey }} 13 | secret-key: {{ .Values.global.secretKey | b64enc | quote }} 14 | {{- else }} 15 | secret-key: {{ required "A valid .Values.global.secretKey is required" .Values.global.secretKey | b64enc | quote }} 16 | {{- end }} 17 | 18 | database-url: {{ include "saleor.databaseUrl" . | b64enc | quote }} 19 | database-url-replica: {{ include "saleor.databaseReplicaUrl" . | b64enc | quote }} 20 | 21 | {{- if .Values.global.jwtRsaPrivateKey }} 22 | jwt-private-key: {{ .Values.global.jwtRsaPrivateKey | b64enc | quote }} 23 | {{- end }} 24 | {{- if .Values.global.jwtRsaPublicKey }} 25 | jwt-public-key: {{ .Values.global.jwtRsaPublicKey | b64enc | quote }} 26 | {{- end }} 27 | 28 | {{/* Handle Redis URL */}} 29 | {{- if .Values.global.redisUrl }} 30 | redis-url: {{ .Values.global.redisUrl | b64enc | quote }} 31 | {{- else if $existingSecret }} 32 | redis-url: {{ index $existingSecret.data "redis-url" | quote }} 33 | {{- else if not .Values.redis.enabled }} 34 | redis-url: {{ include "saleor.redisUrl" . | b64enc | quote }} 35 | {{- else }} 36 | redis-url: {{ include "saleor.internalRedisUrl" . | b64enc | quote }} 37 | {{- end }} 38 | 39 | {{/* Handle Celery Redis URL */}} 40 | {{- if .Values.global.celeryRedisUrl }} 41 | celery-redis-url: {{ .Values.global.celeryRedisUrl | b64enc | quote }} 42 | {{- else if $existingSecret }} 43 | celery-redis-url: {{ index $existingSecret.data "celery-redis-url" | quote }} 44 | {{- else }} 45 | celery-redis-url: {{ include "saleor.celeryRedisUrl" . | b64enc | quote }} 46 | {{- end }} 47 | 48 | {{- if .Values.global.extraSecrets }} 49 | {{- range $key, $value := .Values.global.extraSecrets }} 50 | {{ $key }}: {{ $value | b64enc | quote }} 51 | {{- end }} 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "gtm-server-container-cluster.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "gtm-server-container-cluster.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "gtm-server-container-cluster.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | {{/* 34 | Common labels 35 | */}} 36 | {{- define "gtm-server-container-cluster.labels" -}} 37 | helm.sh/chart: {{ include "gtm-server-container-cluster.chart" . }} 38 | {{ include "gtm-server-container-cluster.selectorLabels" . }} 39 | {{- if .Chart.AppVersion }} 40 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 41 | {{- end }} 42 | app.kubernetes.io/managed-by: {{ .Release.Service }} 43 | {{- end }} 44 | 45 | {{/* 46 | Selector labels 47 | */}} 48 | {{- define "gtm-server-container-cluster.selectorLabels" -}} 49 | app.kubernetes.io/name: {{ include "gtm-server-container-cluster.name" . }} 50 | app.kubernetes.io/instance: {{ .Release.Name }} 51 | {{- end }} 52 | 53 | {{/* 54 | Create the name of the service account to use 55 | */}} 56 | {{- define "gtm-server-container-cluster.serviceAccountName" -}} 57 | {{- if .Values.serviceAccount.create }} 58 | {{- default (include "gtm-server-container-cluster.fullname" .) .Values.serviceAccount.name }} 59 | {{- else }} 60 | {{- default "default" .Values.serviceAccount.name }} 61 | {{- end }} 62 | {{- end }} 63 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for gtm-server-container-cluster. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | image: 8 | repository: gcr.io/cloud-tagging-10302018/gtm-cloud-image 9 | pullPolicy: Always 10 | # Overrides the image tag whose default is the chart appVersion. 11 | tag: stable 12 | 13 | imagePullSecrets: [] 14 | nameOverride: "" 15 | fullnameOverride: "" 16 | 17 | serviceAccount: 18 | # Specifies whether a service account should be created 19 | create: true 20 | # Annotations to add to the service account 21 | annotations: {} 22 | # The name of the service account to use. 23 | # If not set and create is true, a name is generated using the fullname template 24 | name: "" 25 | 26 | podAnnotations: {} 27 | 28 | podSecurityContext: {} 29 | # fsGroup: 2000 30 | 31 | securityContext: {} 32 | # capabilities: 33 | # drop: 34 | # - ALL 35 | # readOnlyRootFilesystem: true 36 | # runAsNonRoot: true 37 | # runAsUser: 1000 38 | 39 | service: 40 | type: ClusterIP 41 | port: 8080 42 | 43 | ingress: 44 | enabled: true 45 | className: "" 46 | annotations: 47 | cert-manager.io/acme-challenge-type: "http01" 48 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 49 | rules: 50 | - taggingHost: "chart-example1.local" 51 | pathType: "ImplementationSpecific" 52 | - taggingHost: "chart-example2.local" 53 | pathType: "ImplementationSpecific" 54 | 55 | 56 | resources: 57 | # We usually recommend not to specify default resources and to leave this as a conscious 58 | # choice for the user. This also increases chances charts run on environments with little 59 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 60 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 61 | limits: 62 | memory: 100Mi 63 | requests: 64 | cpu: 100m 65 | memory: 100Mi 66 | 67 | autoscaling: 68 | enabled: false 69 | minReplicas: 1 70 | maxReplicas: 3 71 | targetCPUUtilizationPercentage: 80 72 | # targetMemoryUtilizationPercentage: 80 73 | 74 | gtm: 75 | containerSettings: 76 | 77 | nodeSelector: {} 78 | 79 | tolerations: [] 80 | 81 | affinity: {} 82 | -------------------------------------------------------------------------------- /charts/saleor/templates/celery-beat-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.worker.enabled }} 2 | apiVersion: apps/v1 3 | kind: StatefulSet 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-celery-beat 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: celery-beat 9 | spec: 10 | replicas: 1 11 | updateStrategy: 12 | type: RollingUpdate 13 | rollingUpdate: 14 | partition: 0 15 | selector: 16 | matchLabels: 17 | {{- include "saleor.selectorLabels" . | nindent 6 }} 18 | app.kubernetes.io/component: celery-beat 19 | template: 20 | metadata: 21 | {{- with .Values.worker.podAnnotations }} 22 | annotations: 23 | {{- toYaml . | nindent 8 }} 24 | {{- end }} 25 | labels: 26 | {{- include "saleor.selectorLabels" . | nindent 8 }} 27 | app.kubernetes.io/component: celery-beat 28 | spec: 29 | {{- with .Values.imagePullSecrets }} 30 | imagePullSecrets: 31 | {{- toYaml . | nindent 8 }} 32 | {{- end }} 33 | serviceAccountName: {{ include "saleor.serviceAccountName" . }} 34 | securityContext: 35 | runAsUser: 0 36 | runAsGroup: 0 37 | containers: 38 | - name: {{ .Chart.Name }}-celery-beat 39 | securityContext: 40 | {{- toYaml .Values.securityContext | nindent 12 }} 41 | image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.tag | default .Chart.AppVersion }}" 42 | imagePullPolicy: {{ .Values.global.image.pullPolicy }} 43 | command: ["celery", "--app", "saleor.celeryconf:app", "beat", "--scheduler", "saleor.schedulers.schedulers.DatabaseScheduler"] 44 | resources: 45 | requests: 46 | cpu: {{ .Values.worker.scheduler.resources.requests.cpu }} 47 | memory: {{ .Values.worker.scheduler.resources.requests.memory }} 48 | limits: 49 | cpu: {{ .Values.worker.scheduler.resources.limits.cpu }} 50 | memory: {{ .Values.worker.scheduler.resources.limits.memory }} 51 | env: 52 | {{- include "saleor.celery.env" . | nindent 12 }} 53 | {{- with .Values.tolerations }} 54 | tolerations: 55 | {{- toYaml . | nindent 8 }} 56 | {{- end }} 57 | {{- end }} 58 | -------------------------------------------------------------------------------- /charts/test-values/saleor-apps-global-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor-apps with global TLS enabled 2 | global: 3 | secretKey: "test-secret-key" 4 | appLogLevel: "info" 5 | # Global TLS configuration 6 | tls: 7 | enabled: true 8 | secretName: "wildcard-test-tls" 9 | 10 | # Redis configuration 11 | redis: 12 | enabled: true 13 | architecture: standalone 14 | auth: 15 | enabled: true 16 | password: "test-redis-password" 17 | 18 | # Marketplace configuration 19 | marketplace: 20 | enabled: true 21 | hostname: marketplace-test-saleor.eu.fsn1.trwrk.xyz 22 | ingress: 23 | enabled: true 24 | annotations: 25 | cert-manager.io/cluster-issuer: letsencrypt-prod 26 | tls: 27 | enabled: true 28 | # This secretName should be ignored when global.tls.enabled is true 29 | secretName: "marketplace-specific-tls" 30 | 31 | # Individual app configurations 32 | apps: 33 | smtp: 34 | enabled: true 35 | hostname: smtp-test-saleor.eu.fsn1.trwrk.xyz 36 | ingress: 37 | annotations: 38 | cert-manager.io/cluster-issuer: letsencrypt-prod 39 | tls: 40 | enabled: true 41 | 42 | products-feed: 43 | enabled: true 44 | hostname: products-feed-test-saleor.eu.fsn1.trwrk.xyz 45 | ingress: 46 | annotations: 47 | cert-manager.io/cluster-issuer: letsencrypt-prod 48 | tls: 49 | enabled: true 50 | 51 | search: 52 | enabled: true 53 | hostname: search-test-saleor.eu.fsn1.trwrk.xyz 54 | ingress: 55 | annotations: 56 | cert-manager.io/cluster-issuer: letsencrypt-prod 57 | tls: 58 | enabled: true 59 | 60 | app-avatax: 61 | enabled: true 62 | hostname: app-avatax-test-saleor.eu.fsn1.trwrk.xyz 63 | # Enable DynamoDB for Avatax 64 | dynamodb: 65 | enabled: true 66 | logsTableName: "avatax-client-logs" 67 | logsItemTtlInDays: 14 68 | region: "us-east-1" 69 | # Using dummy credentials for local DynamoDB 70 | accessKeyId: "dynamodb-local" 71 | secretAccessKey: "dynamodb-local" 72 | ingress: 73 | annotations: 74 | cert-manager.io/cluster-issuer: letsencrypt-prod 75 | tls: 76 | enabled: true 77 | # This secretName should be ignored when global.tls.enabled is true 78 | secretName: "avatax-specific-tls" 79 | -------------------------------------------------------------------------------- /charts/test-values/saleor-apps-local-tls.yaml: -------------------------------------------------------------------------------- 1 | # Test case for Saleor-apps with local TLS (no global TLS) 2 | global: 3 | secretKey: "test-secret-key" 4 | appLogLevel: "info" 5 | # Global TLS configuration disabled 6 | tls: 7 | enabled: false 8 | secretName: "" 9 | 10 | # Redis configuration 11 | redis: 12 | enabled: true 13 | architecture: standalone 14 | auth: 15 | enabled: true 16 | password: "test-redis-password" 17 | 18 | # Marketplace configuration 19 | marketplace: 20 | enabled: true 21 | hostname: marketplace-test-saleor.eu.fsn1.trwrk.xyz 22 | ingress: 23 | enabled: true 24 | annotations: 25 | cert-manager.io/cluster-issuer: letsencrypt-prod 26 | tls: 27 | enabled: true 28 | # This secretName should be used when global.tls.enabled is false 29 | secretName: "marketplace-specific-tls" 30 | 31 | # Individual app configurations 32 | apps: 33 | smtp: 34 | enabled: true 35 | hostname: smtp-test-saleor.eu.fsn1.trwrk.xyz 36 | ingress: 37 | annotations: 38 | cert-manager.io/cluster-issuer: letsencrypt-prod 39 | tls: 40 | enabled: true 41 | secretName: "smtp-specific-tls" 42 | 43 | products-feed: 44 | enabled: true 45 | hostname: products-feed-test-saleor.eu.fsn1.trwrk.xyz 46 | ingress: 47 | annotations: 48 | cert-manager.io/cluster-issuer: letsencrypt-prod 49 | tls: 50 | enabled: true 51 | secretName: "products-feed-specific-tls" 52 | 53 | search: 54 | enabled: true 55 | hostname: search-test-saleor.eu.fsn1.trwrk.xyz 56 | ingress: 57 | annotations: 58 | cert-manager.io/cluster-issuer: letsencrypt-prod 59 | tls: 60 | enabled: true 61 | secretName: "search-specific-tls" 62 | 63 | app-avatax: 64 | enabled: true 65 | hostname: app-avatax-test-saleor.eu.fsn1.trwrk.xyz 66 | # Enable DynamoDB for Avatax 67 | dynamodb: 68 | enabled: true 69 | logsTableName: "avatax-client-logs" 70 | logsItemTtlInDays: 14 71 | region: "us-east-1" 72 | # Using dummy credentials for local DynamoDB 73 | accessKeyId: "dynamodb-local" 74 | secretAccessKey: "dynamodb-local" 75 | ingress: 76 | annotations: 77 | cert-manager.io/cluster-issuer: letsencrypt-prod 78 | tls: 79 | enabled: true 80 | secretName: "avatax-specific-tls" 81 | -------------------------------------------------------------------------------- /charts/saleor/templates/saleor_hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.api.autoscaling.enabled }} 2 | apiVersion: autoscaling/v2 3 | kind: HorizontalPodAutoscaler 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-api 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: api 9 | spec: 10 | scaleTargetRef: 11 | apiVersion: apps/v1 12 | kind: Deployment 13 | name: {{ include "saleor.fullname" . }}-api 14 | minReplicas: {{ .Values.api.autoscaling.minReplicas }} 15 | maxReplicas: {{ .Values.api.autoscaling.maxReplicas }} 16 | metrics: 17 | {{- if .Values.api.autoscaling.targetCPUUtilizationPercentage }} 18 | - type: Resource 19 | resource: 20 | name: cpu 21 | target: 22 | type: Utilization 23 | averageUtilization: {{ .Values.api.autoscaling.targetCPUUtilizationPercentage }} 24 | {{- end }} 25 | {{- if .Values.api.autoscaling.targetMemoryUtilizationPercentage }} 26 | - type: Resource 27 | resource: 28 | name: memory 29 | target: 30 | type: Utilization 31 | averageUtilization: {{ .Values.api.autoscaling.targetMemoryUtilizationPercentage }} 32 | {{- end }} 33 | {{- end }} 34 | --- 35 | {{- if .Values.worker.autoscaling.enabled }} 36 | apiVersion: autoscaling/v2 37 | kind: HorizontalPodAutoscaler 38 | metadata: 39 | name: {{ include "saleor.fullname" . }}-worker 40 | labels: 41 | {{- include "saleor.labels" . | nindent 4 }} 42 | app.kubernetes.io/component: worker 43 | spec: 44 | scaleTargetRef: 45 | apiVersion: apps/v1 46 | kind: Deployment 47 | name: {{ include "saleor.fullname" . }}-worker 48 | minReplicas: {{ .Values.worker.autoscaling.minReplicas }} 49 | maxReplicas: {{ .Values.worker.autoscaling.maxReplicas }} 50 | metrics: 51 | {{- if .Values.worker.autoscaling.targetCPUUtilizationPercentage }} 52 | - type: Resource 53 | resource: 54 | name: cpu 55 | target: 56 | type: Utilization 57 | averageUtilization: {{ .Values.worker.autoscaling.targetCPUUtilizationPercentage }} 58 | {{- end }} 59 | {{- if .Values.worker.autoscaling.targetMemoryUtilizationPercentage }} 60 | - type: Resource 61 | resource: 62 | name: memory 63 | target: 64 | type: Utilization 65 | averageUtilization: {{ .Values.worker.autoscaling.targetMemoryUtilizationPercentage }} 66 | {{- end }} 67 | {{- end }} -------------------------------------------------------------------------------- /charts/saleor/test-values/custom-values.yaml: -------------------------------------------------------------------------------- 1 | api: 2 | enabled: true 3 | replicaCount: 1 4 | service: 5 | type: NodePort 6 | port: 8000 7 | image: 8 | repository: ghcr.io/saleor/saleor 9 | tag: "3.19" 10 | pullPolicy: IfNotPresent 11 | resources: 12 | limits: 13 | cpu: 500m 14 | memory: 512Mi 15 | requests: 16 | cpu: 200m 17 | memory: 256Mi 18 | extraEnv: 19 | - name: DEBUG 20 | value: "True" 21 | - name: ALLOWED_HOSTS 22 | value: "*" 23 | 24 | dashboard: 25 | enabled: true 26 | replicaCount: 1 27 | service: 28 | type: NodePort 29 | port: 80 30 | image: 31 | repository: ghcr.io/saleor/saleor-dashboard 32 | tag: "3.19" 33 | pullPolicy: IfNotPresent 34 | resources: 35 | limits: 36 | cpu: 200m 37 | memory: 256Mi 38 | requests: 39 | cpu: 100m 40 | memory: 128Mi 41 | 42 | worker: 43 | enabled: true 44 | replicaCount: 1 45 | resources: 46 | limits: 47 | cpu: 500m 48 | memory: 512Mi 49 | requests: 50 | cpu: 200m 51 | memory: 256Mi 52 | 53 | global: 54 | secretKey: "test-secret-key-123" 55 | database: 56 | url: "postgres://postgres:postgres@localhost:5432/saleor" 57 | 58 | postgresql: 59 | enabled: true 60 | architecture: standalone 61 | auth: 62 | database: saleor 63 | username: saleor 64 | postgresPassword: "test-postgres-password" 65 | primary: 66 | persistence: 67 | size: 4Gi 68 | resources: 69 | limits: 70 | cpu: 1000m 71 | memory: 1024Mi 72 | requests: 73 | cpu: 500m 74 | memory: 512Mi 75 | 76 | redis: 77 | enabled: true 78 | architecture: standalone 79 | auth: 80 | enabled: true 81 | master: 82 | persistence: 83 | size: 2Gi 84 | resources: 85 | limits: 86 | cpu: 500m 87 | memory: 512Mi 88 | requests: 89 | cpu: 200m 90 | memory: 256Mi 91 | 92 | ingress: 93 | enabled: true 94 | className: nginx 95 | api: 96 | enabled: true 97 | hosts: 98 | - host: api.saleor.local 99 | paths: 100 | - path: / 101 | pathType: Prefix 102 | dashboard: 103 | enabled: true 104 | hosts: 105 | - host: dashboard.saleor.local 106 | paths: 107 | - path: / 108 | pathType: Prefix 109 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/hpa.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.autoscaling.enabled }} 2 | {{- if semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion }} 3 | apiVersion: autoscaling/v2 4 | {{- else if semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion }} 5 | apiVersion: autoscaling/v2beta2 6 | {{- else if semverCompare ">=1.12-0" .Capabilities.KubeVersion.GitVersion }} 7 | apiVersion: autoscaling/v2beta1 8 | {{- else }} 9 | apiVersion: autoscaling/v1 10 | {{- end }} 11 | kind: HorizontalPodAutoscaler 12 | metadata: 13 | name: {{ include "gtm-server-container-cluster.fullname" . }} 14 | labels: 15 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 16 | spec: 17 | scaleTargetRef: 18 | apiVersion: apps/v1 19 | kind: Deployment 20 | name: {{ include "gtm-server-container-cluster.fullname" . }} 21 | minReplicas: {{ .Values.autoscaling.minReplicas }} 22 | maxReplicas: {{ .Values.autoscaling.maxReplicas }} 23 | {{- if or (semverCompare ">=1.12-0" .Capabilities.KubeVersion.GitVersion) (not (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion)) }} 24 | metrics: 25 | {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} 26 | - type: Resource 27 | resource: 28 | name: cpu 29 | target: 30 | type: Utilization 31 | {{- if or (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion) }} 32 | averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 33 | {{- else }} 34 | targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 35 | {{- end }} 36 | {{- end }} 37 | {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} 38 | - type: Resource 39 | resource: 40 | name: memory 41 | target: 42 | type: Utilization 43 | {{- if or (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) (semverCompare ">=1.23-0" .Capabilities.KubeVersion.GitVersion) }} 44 | averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 45 | {{- else }} 46 | targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} 47 | {{- end }} 48 | {{- end }} 49 | {{- else }} 50 | targetCPUUtilizationPercentage: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} 51 | {{- end }} 52 | {{- end }} 53 | -------------------------------------------------------------------------------- /charts/saleor/test-values/all-enabled-values.yaml: -------------------------------------------------------------------------------- 1 | # Test case: All features enabled 2 | global: 3 | secretKey: "test-secret-key-123" 4 | database: 5 | url: "postgres://postgres:postgres@localhost:5432/saleor" 6 | 7 | api: 8 | enabled: true 9 | replicaCount: 2 10 | service: 11 | type: ClusterIP 12 | port: 8000 13 | image: 14 | repository: ghcr.io/saleor/saleor 15 | tag: "3.19" 16 | pullPolicy: IfNotPresent 17 | autoscaling: 18 | enabled: true 19 | 20 | dashboard: 21 | enabled: true 22 | replicaCount: 2 23 | service: 24 | type: ClusterIP 25 | port: 80 26 | image: 27 | repository: ghcr.io/saleor/saleor-dashboard 28 | tag: "3.19" 29 | pullPolicy: IfNotPresent 30 | 31 | worker: 32 | enabled: true 33 | replicaCount: 2 34 | resources: 35 | limits: 36 | cpu: 1000m 37 | memory: 1024Mi 38 | requests: 39 | cpu: 500m 40 | memory: 512Mi 41 | 42 | postgresql: 43 | enabled: true 44 | architecture: replication 45 | auth: 46 | database: saleor 47 | username: saleor 48 | postgresPassword: "test-postgres-password" 49 | primary: 50 | persistence: 51 | size: 8Gi 52 | readReplicas: 53 | replicaCount: 2 54 | persistence: 55 | size: 8Gi 56 | 57 | redis: 58 | enabled: true 59 | architecture: replication 60 | auth: 61 | enabled: true 62 | master: 63 | persistence: 64 | size: 8Gi 65 | replica: 66 | replicaCount: 2 67 | persistence: 68 | size: 8Gi 69 | 70 | serviceMesh: 71 | enabled: true 72 | istio: 73 | enabled: true 74 | api: 75 | connectionPool: 76 | enabled: true 77 | http: 78 | http1MaxPendingRequests: 1 79 | maxRequestsPerConnection: 1 80 | tcp: 81 | maxConnections: 100 82 | loadBalancer: 83 | enabled: true 84 | simple: ROUND_ROBIN 85 | outlierDetection: 86 | enabled: true 87 | baseEjectionTime: 30s 88 | consecutiveErrors: 5 89 | interval: 10s 90 | maxEjectionPercent: 100 91 | dashboard: 92 | connectionPool: 93 | enabled: true 94 | http: 95 | http1MaxPendingRequests: 1 96 | maxRequestsPerConnection: 1 97 | tcp: 98 | maxConnections: 100 99 | loadBalancer: 100 | enabled: true 101 | simple: ROUND_ROBIN 102 | outlierDetection: 103 | enabled: true 104 | baseEjectionTime: 30s 105 | consecutiveErrors: 5 106 | interval: 10s 107 | maxEjectionPercent: 100 108 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # trieb.work HELM Charts 2 | 3 | This repository hosts our collection of Helm charts for various applications. We maintain these charts with stability and best practices in mind. 4 | 5 | ## Installation 6 | 7 | Add our Helm repository: 8 | 9 | ```bash 10 | helm repo add trieb.work https://trieb-work.github.io/helm-charts/ 11 | ``` 12 | 13 | ## Available Charts 14 | 15 | ### Saleor 16 | 17 | A production-ready Helm chart for deploying Saleor Core with PostgreSQL, Redis, and Celery Task Runner. 18 | 19 | ```bash 20 | helm install saleor trieb.work/saleor-helm 21 | ``` 22 | 23 | For detailed configuration options including storage setup (S3, GCS), database configuration, and more, see our [Saleor Chart Documentation](charts/saleor/README.md). 24 | 25 | ### Saleor Apps 26 | 27 | Deploy and manage Saleor Apps in your Kubernetes cluster. This chart supports multiple Saleor Apps with individual configurations. 28 | 29 | ```bash 30 | helm install saleor-apps trieb.work/saleor-apps 31 | ``` 32 | 33 | Key features: 34 | - Deploy multiple Saleor Apps in a single release 35 | - Configure each app independently 36 | - Automatic environment variable management 37 | - Built-in health checks and readiness probes 38 | - Support for custom domains and TLS 39 | - Shared Redis for improved performance 40 | 41 | Example configuration: 42 | ```yaml 43 | apps: 44 | search: 45 | enabled: true 46 | image: 47 | repository: ghcr.io/saleor/search 48 | tag: "3.14.0" 49 | env: 50 | - name: SALEOR_API_URL 51 | value: "https://saleor.example.com/graphql/" 52 | emails: 53 | enabled: true 54 | image: 55 | repository: ghcr.io/saleor/emails-and-messages 56 | tag: "3.14.0" 57 | env: 58 | - name: SALEOR_API_URL 59 | value: "https://saleor.example.com/graphql/" 60 | ``` 61 | 62 | This chart is using the docker container from this repository: https://github.com/trieb-work/saleor-apps-docker. You can optionally build them yourself. 63 | 64 | For detailed configuration options and examples, see our [Saleor Apps Chart Documentation](charts/saleor-apps/README.md). 65 | 66 | ### Strapi 67 | 68 | Deploy your custom Strapi instance with this configurable chart. The chart expects your Docker image to support the following environment variables: 69 | 70 | - `ADMIN_JWT_SECRET` 71 | - `DATABASE_URL` 72 | - `AWS_ACCESS_KEY_ID` 73 | - `AWS_SECRET_ACCESS_KEY` 74 | - `AWS_ENDPOINT` 75 | - `AWS_BUCKET` 76 | - `DATABASE_RUN_MIGRATIONS` 77 | 78 | Installation: 79 | ```bash 80 | helm install strapi trieb.work/strapi 81 | ``` 82 | 83 | To include PostgreSQL in your deployment: 84 | ```bash 85 | helm install strapi trieb.work/strapi --set postgresql.enabled=true 86 | ``` 87 | 88 | 89 | ### Google Tag Manager Server 90 | 91 | Deploy Google Tag Manager Server Side container: 92 | ```bash 93 | helm install gtm trieb.work/gtm-server-container-cluster 94 | ``` 95 | 96 | ## Contributing 97 | 98 | We welcome contributions! Please feel free to submit a Pull Request. 99 | -------------------------------------------------------------------------------- /charts/saleor/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "saleor.fullname" . -}} 3 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 4 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 5 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 6 | {{- end }} 7 | {{- end }} 8 | {{- if .Values.ingress.api.enabled -}} 9 | apiVersion: networking.k8s.io/v1 10 | kind: Ingress 11 | metadata: 12 | name: {{ $fullName }} 13 | labels: 14 | {{- include "saleor.labels" . | nindent 4 }} 15 | app.kubernetes.io/component: api 16 | {{- with .Values.ingress.api.annotations }} 17 | annotations: 18 | {{- toYaml . | nindent 4 }} 19 | {{- end }} 20 | spec: 21 | {{- if .Values.ingress.className }} 22 | ingressClassName: {{ .Values.ingress.className }} 23 | {{- end }} 24 | {{- $globalTlsEnabled := and (hasKey .Values.global "tls") (hasKey .Values.global.tls "enabled") .Values.global.tls.enabled -}} 25 | {{- $apiTlsExists := and (hasKey .Values.ingress.api "tls") (ne (len .Values.ingress.api.tls) 0) -}} 26 | {{- $globalTlsSecretExists := and $globalTlsEnabled (hasKey .Values.global.tls "secretName") (ne .Values.global.tls.secretName "") -}} 27 | {{- if or $globalTlsEnabled $apiTlsExists }} 28 | tls: 29 | {{- if and $globalTlsEnabled $globalTlsSecretExists }} 30 | - hosts: 31 | {{- range .Values.ingress.api.hosts }} 32 | - {{ .host | quote }} 33 | {{- end }} 34 | secretName: {{ .Values.global.tls.secretName }} 35 | {{- else if $apiTlsExists }} 36 | {{- range .Values.ingress.api.tls }} 37 | - hosts: 38 | {{- range .hosts }} 39 | - {{ . | quote }} 40 | {{- end }} 41 | {{- if .secretName }} 42 | secretName: {{ .secretName }} 43 | {{- end }} 44 | {{- end }} 45 | {{- else if $globalTlsEnabled }} 46 | # TLS enabled but no secret specified - using global ingress fallback certificate 47 | - hosts: 48 | {{- range .Values.ingress.api.hosts }} 49 | - {{ .host | quote }} 50 | {{- end }} 51 | {{- end }} 52 | {{- end }} 53 | rules: 54 | {{- range .Values.ingress.api.hosts }} 55 | - host: {{ .host | quote }} 56 | http: 57 | paths: 58 | {{- range .paths }} 59 | - path: {{ .path }} 60 | pathType: {{ .pathType }} 61 | backend: 62 | service: 63 | name: {{ $fullName }}-api 64 | port: 65 | name: http 66 | {{- end }} 67 | {{- if $.Values.dashboard.enabled }} 68 | - path: /dashboard/ 69 | pathType: Prefix 70 | backend: 71 | service: 72 | name: {{ $fullName }}-dashboard 73 | port: 74 | name: http 75 | {{- end }} 76 | {{- end }} 77 | {{- end }} 78 | {{- end }} 79 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/marketplace-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.marketplace.enabled }} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ .Release.Name }}-marketplace 6 | labels: 7 | {{- include "saleor-apps.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: marketplace 9 | spec: 10 | replicas: 1 11 | selector: 12 | matchLabels: 13 | {{- include "saleor-apps.selectorLabels" . | nindent 6 }} 14 | app.kubernetes.io/component: marketplace 15 | template: 16 | metadata: 17 | labels: 18 | {{- include "saleor-apps.selectorLabels" . | nindent 8 }} 19 | app.kubernetes.io/component: marketplace 20 | annotations: 21 | # Restart the pod if apps change to reflect this change in the marketplace.json / extensions.json 22 | checksum/marketplace-config: {{ toYaml .Values.apps | sha256sum }} 23 | spec: 24 | containers: 25 | - name: nginx 26 | image: nginx:alpine 27 | ports: 28 | - containerPort: 80 29 | name: http 30 | volumeMounts: 31 | - name: marketplace-config 32 | mountPath: /usr/share/nginx/html/marketplace.json 33 | subPath: marketplace.json 34 | - name: extensions-config 35 | mountPath: /usr/share/nginx/html/extensions.json 36 | subPath: extensions.json 37 | - name: nginx-config 38 | mountPath: /etc/nginx/conf.d 39 | resources: 40 | limits: 41 | cpu: 100m 42 | memory: 128Mi 43 | requests: 44 | cpu: 50m 45 | memory: 64Mi 46 | volumes: 47 | - name: marketplace-config 48 | configMap: 49 | name: {{ .Release.Name }}-marketplace 50 | items: 51 | - key: marketplace.json 52 | path: marketplace.json 53 | - name: extensions-config 54 | configMap: 55 | name: {{ .Release.Name }}-extensions 56 | items: 57 | - key: extensions.json 58 | path: extensions.json 59 | - name: nginx-config 60 | configMap: 61 | name: {{ .Release.Name }}-marketplace-nginx 62 | --- 63 | apiVersion: v1 64 | kind: ConfigMap 65 | metadata: 66 | name: {{ .Release.Name }}-marketplace-nginx 67 | labels: 68 | {{- include "saleor-apps.labels" . | nindent 4 }} 69 | data: 70 | default.conf: | 71 | server { 72 | listen 80; 73 | server_name _; 74 | 75 | location /marketplace.json { 76 | alias /usr/share/nginx/html/marketplace.json; 77 | add_header Content-Type application/json; 78 | add_header Access-Control-Allow-Origin "*"; 79 | } 80 | 81 | location /extensions.json { 82 | alias /usr/share/nginx/html/extensions.json; 83 | add_header Content-Type application/json; 84 | add_header Access-Control-Allow-Origin "*"; 85 | } 86 | } 87 | {{- end }} 88 | -------------------------------------------------------------------------------- /charts/saleor/templates/migration_job.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.migrations.enabled }} 2 | apiVersion: batch/v1 3 | kind: Job 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-migrations-{{ .Release.Revision }} 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | annotations: 9 | helm.sh/hook: post-install,post-upgrade 10 | helm.sh/hook-weight: "0" 11 | helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded 12 | spec: 13 | template: 14 | metadata: 15 | labels: 16 | {{- include "saleor.labels" . | nindent 8 }} 17 | app.kubernetes.io/component: migrations 18 | spec: 19 | restartPolicy: Never 20 | {{- with .Values.imagePullSecrets }} 21 | imagePullSecrets: 22 | {{- toYaml . | nindent 8 }} 23 | {{- end }} 24 | containers: 25 | - name: migrations 26 | image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.tag | default .Chart.AppVersion }}" 27 | imagePullPolicy: {{ .Values.global.image.pullPolicy }} 28 | command: ["python", "manage.py", "migrate", "--no-input"] 29 | env: 30 | # Core database configuration 31 | - name: DATABASE_URL 32 | valueFrom: 33 | secretKeyRef: 34 | name: {{ include "saleor.fullname" . }}-secrets 35 | key: database-url 36 | 37 | # Redis configuration 38 | - name: REDIS_URL 39 | valueFrom: 40 | secretKeyRef: 41 | name: {{ include "saleor.fullname" . }}-secrets 42 | key: redis-url 43 | 44 | # Secret key for Django 45 | - name: SECRET_KEY 46 | valueFrom: 47 | secretKeyRef: 48 | name: {{ include "saleor.fullname" . }}-secrets 49 | key: secret-key 50 | 51 | # JWT configuration 52 | {{- if .Values.global.jwtRsaPrivateKey }} 53 | - name: RSA_PRIVATE_KEY 54 | valueFrom: 55 | secretKeyRef: 56 | name: {{ include "saleor.fullname" . }}-secrets 57 | key: jwt-private-key 58 | {{- end }} 59 | 60 | # Add all extra environment variables from the API configuration 61 | {{- if .Values.api.extraEnv }} 62 | {{- toYaml .Values.api.extraEnv | nindent 12 }} 63 | {{- end }} 64 | 65 | # Add any migration-specific environment variables 66 | {{- if .Values.migrations.extraEnv }} 67 | {{- toYaml .Values.migrations.extraEnv | nindent 12 }} 68 | {{- end }} 69 | 70 | resources: 71 | {{- toYaml .Values.migrations.resources | nindent 12 }} 72 | {{- with .Values.migrations.nodeSelector }} 73 | nodeSelector: 74 | {{- toYaml . | nindent 8 }} 75 | {{- end }} 76 | {{- with .Values.migrations.affinity }} 77 | affinity: 78 | {{- toYaml . | nindent 8 }} 79 | {{- end }} 80 | {{- with .Values.migrations.tolerations }} 81 | tolerations: 82 | {{- toYaml . | nindent 8 }} 83 | {{- end }} 84 | {{- end }} 85 | -------------------------------------------------------------------------------- /charts/saleor-apps/values-example-prod.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | domain: "test-saleor.eu.fsn1.trwrk.xyz" 3 | secretKey: "your-secret-key-here" # Replace with actual secret key in production 4 | #redisUrl: "redis://test-saleor-redis-master:6379" 5 | 6 | redis: 7 | auth: 8 | enabled: true 9 | password: "your-redis-password-here" # Replace with actual password in production 10 | 11 | marketplace: 12 | hostname: marketplace-test-saleor.eu.fsn1.trwrk.xyz 13 | ingress: 14 | enabled: true 15 | annotations: 16 | cert-manager.io/cluster-issuer: letsencrypt-prod 17 | tls: 18 | enabled: true 19 | 20 | # Enable all apps for testing 21 | apps: 22 | smtp: 23 | enabled: true 24 | hostname: smtp-test-saleor.eu.fsn1.trwrk.xyz 25 | ingress: 26 | annotations: 27 | cert-manager.io/cluster-issuer: letsencrypt-prod 28 | tls: 29 | enabled: true 30 | 31 | products-feed: 32 | enabled: true 33 | hostname: products-feed-test-saleor.eu.fsn1.trwrk.xyz 34 | ingress: 35 | annotations: 36 | cert-manager.io/cluster-issuer: letsencrypt-prod 37 | tls: 38 | enabled: true 39 | 40 | search: 41 | enabled: true 42 | hostname: search-test-saleor.eu.fsn1.trwrk.xyz 43 | ingress: 44 | annotations: 45 | cert-manager.io/cluster-issuer: letsencrypt-prod 46 | tls: 47 | enabled: true 48 | 49 | app-avatax: 50 | enabled: true 51 | hostname: app-avatax-test-saleor.eu.fsn1.trwrk.xyz 52 | # Enable DynamoDB for Avatax 53 | dynamodb: 54 | enabled: true 55 | logsTableName: "avatax-client-logs" 56 | logsItemTtlInDays: 14 57 | region: "us-east-1" 58 | # Using dummy credentials for local DynamoDB 59 | accessKeyId: "dynamodb-local" 60 | secretAccessKey: "dynamodb-local" 61 | ingress: 62 | annotations: 63 | cert-manager.io/cluster-issuer: letsencrypt-prod 64 | tls: 65 | enabled: true 66 | 67 | cms: 68 | enabled: true 69 | hostname: cms-test-saleor.eu.fsn1.trwrk.xyz 70 | ingress: 71 | annotations: 72 | cert-manager.io/cluster-issuer: letsencrypt-prod 73 | tls: 74 | enabled: true 75 | 76 | klaviyo: 77 | enabled: true 78 | hostname: klaviyo-test-saleor.eu.fsn1.trwrk.xyz 79 | ingress: 80 | annotations: 81 | cert-manager.io/cluster-issuer: letsencrypt-prod 82 | tls: 83 | enabled: true 84 | 85 | 86 | test-customer-app: 87 | enabled: true 88 | hostname: test-customer-app-test-saleor.eu.fsn1.trwrk.xyz 89 | port: 8000 # Port that your app listens on. Optional, defaults to 3000 90 | extraEnvs: 91 | - name: MY_CUSTOM_ENV 92 | value: "custom-value" 93 | image: 94 | registry: us-central1-docker.pkg.dev # Required 95 | repository: kencove-prod/kencove-docker-repo/saleor-customer-app # Required 96 | tag: latest # Required 97 | manifestPath: /api/manifest # Optional, defaults to /api/manifest 98 | ingress: 99 | enabled: true 100 | annotations: 101 | cert-manager.io/cluster-issuer: letsencrypt-prod 102 | tls: 103 | enabled: true 104 | secretName: "" 105 | # Optional marketplace metadata 106 | marketplace: 107 | name: "This is a customer app for testing purposes for now" # Required if app is enabled 108 | description: 109 | en: "My custom app description" # Optional -------------------------------------------------------------------------------- /charts/test-values/saleor-apps-example-prod.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | domain: "test-saleor.eu.fsn1.trwrk.xyz" 3 | secretKey: "your-secret-key-here" # Replace with actual secret key in production 4 | #redisUrl: "redis://test-saleor-redis-master:6379" 5 | 6 | redis: 7 | auth: 8 | enabled: true 9 | password: "your-redis-password-here" # Replace with actual password in production 10 | 11 | marketplace: 12 | hostname: marketplace-test-saleor.eu.fsn1.trwrk.xyz 13 | ingress: 14 | enabled: true 15 | annotations: 16 | cert-manager.io/cluster-issuer: letsencrypt-prod 17 | tls: 18 | enabled: true 19 | 20 | # Enable all apps for testing 21 | apps: 22 | smtp: 23 | enabled: true 24 | hostname: smtp-test-saleor.eu.fsn1.trwrk.xyz 25 | ingress: 26 | annotations: 27 | cert-manager.io/cluster-issuer: letsencrypt-prod 28 | tls: 29 | enabled: true 30 | 31 | products-feed: 32 | enabled: true 33 | hostname: products-feed-test-saleor.eu.fsn1.trwrk.xyz 34 | ingress: 35 | annotations: 36 | cert-manager.io/cluster-issuer: letsencrypt-prod 37 | tls: 38 | enabled: true 39 | 40 | search: 41 | enabled: true 42 | hostname: search-test-saleor.eu.fsn1.trwrk.xyz 43 | ingress: 44 | annotations: 45 | cert-manager.io/cluster-issuer: letsencrypt-prod 46 | tls: 47 | enabled: true 48 | 49 | app-avatax: 50 | enabled: true 51 | hostname: app-avatax-test-saleor.eu.fsn1.trwrk.xyz 52 | # Enable DynamoDB for Avatax 53 | dynamodb: 54 | enabled: true 55 | logsTableName: "avatax-client-logs" 56 | logsItemTtlInDays: 14 57 | region: "us-east-1" 58 | # Using dummy credentials for local DynamoDB 59 | accessKeyId: "dynamodb-local" 60 | secretAccessKey: "dynamodb-local" 61 | ingress: 62 | annotations: 63 | cert-manager.io/cluster-issuer: letsencrypt-prod 64 | tls: 65 | enabled: true 66 | 67 | cms: 68 | enabled: true 69 | hostname: cms-test-saleor.eu.fsn1.trwrk.xyz 70 | ingress: 71 | annotations: 72 | cert-manager.io/cluster-issuer: letsencrypt-prod 73 | tls: 74 | enabled: true 75 | 76 | klaviyo: 77 | enabled: true 78 | hostname: klaviyo-test-saleor.eu.fsn1.trwrk.xyz 79 | ingress: 80 | annotations: 81 | cert-manager.io/cluster-issuer: letsencrypt-prod 82 | tls: 83 | enabled: true 84 | 85 | 86 | test-customer-app: 87 | enabled: true 88 | hostname: test-customer-app-test-saleor.eu.fsn1.trwrk.xyz 89 | port: 8000 # Port that your app listens on. Optional, defaults to 3000 90 | extraEnvs: 91 | - name: MY_CUSTOM_ENV 92 | value: "custom-value" 93 | image: 94 | registry: us-central1-docker.pkg.dev # Required 95 | repository: kencove-prod/kencove-docker-repo/saleor-customer-app # Required 96 | tag: latest # Required 97 | manifestPath: /api/manifest # Optional, defaults to /api/manifest 98 | ingress: 99 | enabled: true 100 | annotations: 101 | cert-manager.io/cluster-issuer: letsencrypt-prod 102 | tls: 103 | enabled: true 104 | secretName: "" 105 | # Optional marketplace metadata 106 | marketplace: 107 | name: "This is a customer app for testing purposes for now" # Required if app is enabled 108 | description: 109 | en: "My custom app description" # Optional -------------------------------------------------------------------------------- /charts/strapi/templates/postgres_backup.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.postgresBackup.enabled -}} 2 | {{- $fullName := include "strapi.fullname" . -}} 3 | apiVersion: batch/v1 4 | kind: CronJob 5 | metadata: 6 | annotations: 7 | labels: 8 | name: "{{ include "strapi.fullname" . }}-postgres-backup" 9 | spec: 10 | failedJobsHistoryLimit: 5 11 | successfulJobsHistoryLimit: 3 12 | concurrencyPolicy: Forbid 13 | schedule: {{ .Values.postgresBackup.schedule }} 14 | jobTemplate: 15 | metadata: 16 | spec: 17 | template: 18 | metadata: 19 | annotations: 20 | spec: 21 | containers: 22 | - image: registry.gitlab.com/trieb.work/postgres-backup-s3 23 | imagePullPolicy: Always 24 | name: "{{ include "strapi.fullname" . }}-postgres-backup" 25 | env: 26 | - name: NUMBER_OF_VERSIONS 27 | value: {{ .Values.postgresBackup.historyLimit | quote }} 28 | - name: DATABASES 29 | value: {{ .Values.postgresql.auth.database | quote }} 30 | 31 | {{- if .Values.r2.enabled }} 32 | - name: S3_KEY 33 | valueFrom: 34 | secretKeyRef: 35 | key: CF_ACCESS_KEY_ID 36 | name: {{ include "strapi.fullname" . }} 37 | - name: S3_ENDPOINT 38 | valueFrom: 39 | secretKeyRef: 40 | key: CF_ENDPOINT 41 | name: {{ include "strapi.fullname" . }} 42 | - name: S3_SECRET 43 | valueFrom: 44 | secretKeyRef: 45 | key: CF_SECRET_ACCESS_KEY 46 | name: {{ include "strapi.fullname" . }} 47 | {{- else }} 48 | - name: S3_KEY 49 | valueFrom: 50 | secretKeyRef: 51 | key: AWS_ACCESS_KEY_ID 52 | name: {{ include "strapi.fullname" . }} 53 | - name: S3_ENDPOINT 54 | valueFrom: 55 | secretKeyRef: 56 | key: AWS_ENDPOINT 57 | name: {{ include "strapi.fullname" . }} 58 | - name: S3_SECRET 59 | valueFrom: 60 | secretKeyRef: 61 | key: AWS_SECRET_ACCESS_KEY 62 | name: {{ include "strapi.fullname" . }} 63 | {{- end }} 64 | - name: S3_BUCKET_NAME 65 | value: {{ .Values.postgresBackup.bucketName | quote }} 66 | - name: POSTGRES_DB_PASSWORD 67 | valueFrom: 68 | secretKeyRef: 69 | key: POSTGRES_DB_PASSWORD 70 | name: {{ include "strapi.fullname" . }} 71 | - name: POSTGRES_DB_USER 72 | valueFrom: 73 | secretKeyRef: 74 | key: POSTGRES_DB_USER 75 | name: {{ include "strapi.fullname" . }} 76 | - name: POSTGRES_DB_HOST 77 | value: {{ include "strapi.internalDatabaseBackupHost" .}} 78 | - name: POSTGRES_DB_PORT 79 | value: "5432" 80 | envFrom: 81 | - secretRef: 82 | name: {{ include "strapi.fullname" . }} 83 | securityContext: 84 | allowPrivilegeEscalation: false 85 | privileged: false 86 | readOnlyRootFilesystem: false 87 | restartPolicy: Never 88 | terminationGracePeriodSeconds: 30 89 | {{- end -}} -------------------------------------------------------------------------------- /charts/saleor-apps/docs/marketplace.md: -------------------------------------------------------------------------------- 1 | # Saleor Apps Marketplace 2 | 3 | The Saleor Apps chart includes a built-in marketplace feature that allows you to deploy and manage both official Saleor apps and your own custom apps. The marketplace provides a centralized location in your Saleor Dashboard where you can discover and install apps with a single click. 4 | 5 | ![Saleor Apps Marketplace](./images/marketplaceImage.png) 6 | 7 | ## Adding Custom Apps 8 | 9 | You can easily add your own custom apps to the marketplace by adding them to the `apps` section in your values file. Here's an example: 10 | 11 | ```yaml 12 | apps: 13 | my-custom-app: 14 | enabled: true 15 | hostname: my-custom-app.apps.example.com 16 | port: 8000 # Port that your app listens on 17 | image: 18 | registry: my-registry.io # Optional, defaults to common.image.registry 19 | repository: myorg/my-custom-app # Required 20 | tag: v1.0.0 # Required 21 | manifestPath: /api/manifest # Optional, defaults to /api/manifest 22 | ingress: 23 | enabled: true 24 | annotations: 25 | cert-manager.io/cluster-issuer: letsencrypt-prod # Optional 26 | tls: 27 | enabled: true 28 | secretName: "" # Optional 29 | # Marketplace metadata 30 | marketplace: 31 | name: "My Custom App" # Required if app is enabled 32 | logo: # Optional 33 | source: "https://example.com/logo.svg" 34 | color: "#000000" 35 | description: # Optional 36 | en: "Description of my custom app" 37 | integrations: # Optional 38 | - name: "Integration Service" 39 | logo: 40 | light: 41 | source: "https://example.com/logo-light.svg" 42 | dark: 43 | source: "https://example.com/logo-dark.svg" 44 | privacyUrl: "https://example.com/privacy" # Optional 45 | supportUrl: "https://example.com/support" # Optional 46 | repositoryUrl: "https://github.com/myorg/my-app" # Optional 47 | ``` 48 | 49 | ## Configuration Reference 50 | 51 | ### App Configuration 52 | 53 | | Parameter | Description | Default | 54 | |-----------|-------------|---------| 55 | | `enabled` | Enable or disable the app | `false` | 56 | | `hostname` | Hostname where the app will be accessible | `nil` | 57 | | `port` | Port that the app listens on | `3000` | 58 | | `image.registry` | Docker registry for the app | Value from `common.image.registry` | 59 | | `image.repository` | Docker image repository | Required | 60 | | `image.tag` | Docker image tag | Required | 61 | | `manifestPath` | Path to the app manifest | `/api/manifest` | 62 | 63 | ### Marketplace Configuration 64 | 65 | | Parameter | Description | Required | 66 | |-----------|-------------|----------| 67 | | `marketplace.name` | Display name of the app | Yes | 68 | | `marketplace.logo.source` | URL to the app's logo | No | 69 | | `marketplace.logo.color` | Background color for the logo | No | 70 | | `marketplace.description.en` | English description of the app | No | 71 | | `marketplace.integrations` | List of integrations the app provides | No | 72 | | `marketplace.privacyUrl` | URL to privacy policy | No | 73 | | `marketplace.supportUrl` | URL to support page | No | 74 | | `marketplace.repositoryUrl` | URL to source code repository | No | 75 | 76 | ## How It Works 77 | 78 | The chart creates: 79 | 1. A deployment for each enabled app 80 | 2. An ingress for each app to make it accessible 81 | 3. A marketplace JSON endpoint that Saleor Dashboard uses to display available apps 82 | 83 | When you add a custom app: 84 | 1. The app will be deployed using the specified image 85 | 2. It will be accessible at the specified hostname 86 | 3. The app will appear in the Saleor Dashboard marketplace 87 | 4. Users can install it with one click, just like official apps 88 | 89 | ## Best Practices 90 | 91 | 1. Always use HTTPS by enabling TLS in the ingress configuration 92 | 2. Provide clear and helpful descriptions for your apps 93 | 3. Include relevant integration information if your app integrates with third-party services 94 | 4. Keep your app manifests up to date 95 | 5. Consider using semantic versioning for your app image tags 96 | -------------------------------------------------------------------------------- /charts/test-values/saleor-apps-custom.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | domain: test-saleor.eu.fsn1.trwrk.xyz 3 | database: 4 | url: postgresql://postgres:postgres@postgresql:5432/postgres 5 | replicaUrl: postgresql://postgres:postgres@postgresql-read:5432/postgres 6 | 7 | marketplace: 8 | enabled: true 9 | hostname: test-marketplace-test-saleor.eu.fsn1.trwrk.xyz 10 | ingress: 11 | enabled: true 12 | className: nginx 13 | annotations: {} 14 | 15 | apps: 16 | customer-app: 17 | enabled: true 18 | hostname: test-customer-app-test-saleor.eu.fsn1.trwrk.xyz 19 | port: 8000 # Port that your app listens on. Optional, defaults to 3000 20 | extraEnvs: 21 | - name: KENCOVE_API 22 | value: https://test-customer-app-test-saleor.eu.fsn1.trwrk.xyz 23 | - name: KENCOVE_API_TOKEN_ENDPOINT 24 | value: ${COGNITO_API_TOKEN_ENDPOINT} 25 | image: 26 | registry: us-central1-docker.pkg.dev # Required 27 | repository: kencove-prod/kencove-docker-repo/saleor-customer-app # Required 28 | tag: latest # Required 29 | ingress: 30 | enabled: true 31 | className: nginx 32 | annotations: {} 33 | # Optional marketplace metadata 34 | marketplace: 35 | name: "Customer App" # Required if app is enabled 36 | description: 37 | en: "This is the customer app that triggers the creation of a new customer in Odoo, so that we can run tax exemptions on them" # Optional 38 | smtp: 39 | enabled: true 40 | 41 | 42 | authorizenet: 43 | enabled: true 44 | port: 8000 45 | hostname: test-authorizenet-test-saleor.eu.fsn1.trwrk.xyz 46 | image: 47 | registry: us-central1-docker.pkg.dev 48 | repository: kencove-prod/kencove-docker-repo/saleor-payment-authorize-net-app 49 | tag: latest 50 | ingress: 51 | enabled: true 52 | className: nginx 53 | annotations: {} 54 | extraEnvs: 55 | - name: AUTHORIZE_API_LOGIN_ID 56 | value: ${AUTHORIZE_API_LOGIN_ID} 57 | - name: AUTHORIZE_TRANSACTION_KEY 58 | value: ${AUTHORIZE_TRANSACTION_KEY} 59 | - name: AUTHORIZE_PUBLIC_CLIENT_KEY 60 | value: ${AUTHORIZE_PUBLIC_CLIENT_KEY} 61 | - name: AUTHORIZE_ENVIRONMENT 62 | value: ${AUTHORIZE_ENVIRONMENT} 63 | - name: AUTHORIZE_SIGNATURE_KEY 64 | value: ${AUTHORIZE_SIGNATURE_KEY} 65 | - name: APP_API_BASE_URL 66 | value: ${AUTHORIZE_API_BASE_URL} 67 | marketplace: 68 | name: "Authorize.net" 69 | description: 70 | en: "This is the custom saleor app that handles the payment with Authorize.net" 71 | 72 | shipping: 73 | enabled: true 74 | port: 8000 75 | hostname: test-shipping-test-saleor.eu.fsn1.trwrk.xyz 76 | image: 77 | registry: us-central1-docker.pkg.dev 78 | repository: kencove-prod/kencove-docker-repo/saleor-shipping-app 79 | tag: latest 80 | ingress: 81 | enabled: true 82 | className: nginx 83 | annotations: {} 84 | marketplace: 85 | name: "Shipping" 86 | description: 87 | en: "This is the custom saleor app that handles the shipping calculations." 88 | extraEnvs: 89 | - name: KENCOVE_SHIPPING_API_URL 90 | value: ${KENCOVE_SHIPPING_API_URL} 91 | 92 | manual-payment: 93 | enabled: true 94 | port: 8000 95 | hostname: test-manual-payment-test-saleor.eu.fsn1.trwrk.xyz 96 | image: 97 | registry: us-central1-docker.pkg.dev 98 | repository: kencove-prod/kencove-docker-repo/saleor-manual-payment-app 99 | tag: latest 100 | ingress: 101 | enabled: true 102 | className: nginx 103 | annotations: {} 104 | marketplace: 105 | name: "Manual Payment" 106 | description: 107 | en: "This is the custom saleor app that allows the manual payment processing, like echeck and prepayment. Needs valid cognito credentials to authenticate" 108 | extraEnvs: 109 | - name: KENCOVE_API_CLIENT_ID 110 | value: ${KENCOVE_API_CLIENT_ID} 111 | - name: KENCOVE_API_CLIENT_SECRET 112 | value: ${KENCOVE_API_CLIENT_SECRET} 113 | - name: KENCOVE_API_SCOPE 114 | value: ${KENCOVE_API_SCOPE} 115 | - name: KENCOVE_API_TOKEN_ENDPOINT 116 | value: ${KENCOVE_API_TOKEN_ENDPOINT} 117 | - name: KENCOVE_API_URL 118 | value: ${KENCOVE_API_URL} 119 | -------------------------------------------------------------------------------- /charts/saleor/templates/worker_deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.worker.enabled -}} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-worker 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: worker 9 | spec: 10 | {{- if not .Values.worker.autoscaling.enabled }} 11 | replicas: {{ .Values.worker.replicaCount }} 12 | {{- end }} 13 | selector: 14 | matchLabels: 15 | {{- include "saleor.selectorLabels" . | nindent 6 }} 16 | app.kubernetes.io/component: worker 17 | template: 18 | metadata: 19 | {{- with .Values.worker.podAnnotations }} 20 | annotations: 21 | {{- toYaml . | nindent 8 }} 22 | {{- end }} 23 | labels: 24 | {{- include "saleor.selectorLabels" . | nindent 8 }} 25 | app.kubernetes.io/component: worker 26 | spec: 27 | {{- with .Values.imagePullSecrets }} 28 | imagePullSecrets: 29 | {{- toYaml . | nindent 8 }} 30 | {{- end }} 31 | serviceAccountName: {{ include "saleor.serviceAccountName" . }} 32 | securityContext: 33 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 34 | {{- if gt (int .Values.worker.replicaCount) 1 }} 35 | affinity: 36 | podAntiAffinity: 37 | preferredDuringSchedulingIgnoredDuringExecution: 38 | - weight: 100 39 | podAffinityTerm: 40 | labelSelector: 41 | matchExpressions: 42 | - key: app.kubernetes.io/component 43 | operator: In 44 | values: 45 | - worker 46 | topologyKey: kubernetes.io/hostname 47 | {{- end }} 48 | containers: 49 | - name: {{ .Chart.Name }}-worker 50 | securityContext: 51 | {{- toYaml .Values.securityContext | nindent 12 }} 52 | image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.tag | default .Chart.AppVersion }}" 53 | imagePullPolicy: {{ .Values.global.image.pullPolicy }} 54 | command: ["celery"] 55 | args: ["--app=saleor.celeryconf:app", "worker", "-E", "--loglevel=info" ] 56 | livenessProbe: 57 | exec: 58 | command: 59 | - /bin/sh 60 | - -c 61 | - celery -A saleor inspect ping -d celery@$HOSTNAME 62 | initialDelaySeconds: 30 63 | periodSeconds: 30 64 | timeoutSeconds: 15 65 | successThreshold: 1 66 | failureThreshold: 3 67 | readinessProbe: 68 | exec: 69 | command: 70 | - /bin/sh 71 | - -c 72 | - celery -A saleor inspect ping -d celery@$HOSTNAME 73 | initialDelaySeconds: 30 74 | periodSeconds: 30 75 | timeoutSeconds: 15 76 | successThreshold: 1 77 | failureThreshold: 3 78 | resources: 79 | {{- toYaml .Values.worker.resources | nindent 12 }} 80 | volumeMounts: 81 | {{- if include "saleor.readReplicaEnabled" . }} 82 | - name: settings 83 | mountPath: /app/saleor/settings.py 84 | subPath: settings.py 85 | {{- end }} 86 | {{- if and .Values.storage.gcs.enabled .Values.storage.gcs.credentials.jsonKey }} 87 | - name: gcs-credentials 88 | mountPath: /var/secrets/google 89 | readOnly: true 90 | {{- end }} 91 | env: 92 | {{- include "saleor.celery.env" . | nindent 12 }} 93 | 94 | volumes: 95 | {{- if include "saleor.readReplicaEnabled" . }} 96 | - name: settings 97 | configMap: 98 | name: {{ include "saleor.fullname" . }}-settings 99 | {{- end }} 100 | {{- if and .Values.storage.gcs.enabled .Values.storage.gcs.credentials.jsonKey }} 101 | - name: gcs-credentials 102 | secret: 103 | secretName: {{ include "saleor.fullname" . }}-gcs-credentials 104 | {{- end }} 105 | {{- with .Values.nodeSelector }} 106 | nodeSelector: 107 | {{- toYaml . | nindent 8 }} 108 | {{- end }} 109 | {{- with .Values.tolerations }} 110 | tolerations: 111 | {{- toYaml . | nindent 8 }} 112 | {{- end }} 113 | {{- end }} 114 | -------------------------------------------------------------------------------- /charts/strapi/templates/_helpers.tpl: -------------------------------------------------------------------------------- 1 | {{/* 2 | Expand the name of the chart. 3 | */}} 4 | {{- define "strapi.name" -}} 5 | {{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }} 6 | {{- end }} 7 | 8 | {{/* 9 | Create a default fully qualified app name. 10 | We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec). 11 | If release name contains chart name it will be used as a full name. 12 | */}} 13 | {{- define "strapi.fullname" -}} 14 | {{- if .Values.fullnameOverride }} 15 | {{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }} 16 | {{- else }} 17 | {{- $name := default .Chart.Name .Values.nameOverride }} 18 | {{- if contains $name .Release.Name }} 19 | {{- .Release.Name | trunc 63 | trimSuffix "-" }} 20 | {{- else }} 21 | {{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }} 22 | {{- end }} 23 | {{- end }} 24 | {{- end }} 25 | 26 | {{/* 27 | Create chart name and version as used by the chart label. 28 | */}} 29 | {{- define "strapi.chart" -}} 30 | {{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }} 31 | {{- end }} 32 | 33 | # just the internal database host name, used as backup target 34 | {{- define "strapi.internalDatabaseBackupHost" -}} 35 | {{- if eq .Values.postgresql.architecture "replication" }} 36 | {{- printf "%s%s" .Release.Name "-postgresql-primary" }} 37 | {{- else }} 38 | {{- printf "%s%s" .Release.Name "-postgresql" }} 39 | {{- end }} 40 | {{- end }} 41 | 42 | 43 | 44 | {{- define "strapi.internalDatabaseUrl" -}} 45 | {{- if eq .Values.postgresql.architecture "replication" }} 46 | {{- printf "%s%s%s%s%s%s%s%s" "postgresql://" .Values.postgresql.auth.username ":" .Values.postgresql.auth.password "@" .Release.Name "-postgresql-primary:5432/" .Values.postgresql.auth.database }} 47 | {{- else }} 48 | {{- printf "%s%s%s%s%s%s%s%s" "postgresql://" .Values.postgresql.auth.username ":" .Values.postgresql.auth.password "@" .Release.Name "-postgresql:5432/" .Values.postgresql.auth.database }} 49 | {{- end }} 50 | {{- end }} 51 | 52 | {{- define "strapi.internalDatabaseUrlReplica" -}} 53 | {{- if eq .Values.postgresql.architecture "replication" }} 54 | {{- printf "%s%s%s%s%s%s%s%s" "postgresql://" .Values.postgresql.auth.username ":" .Values.postgresql.auth.password "@" .Release.Name "-postgresql-read:5432/" .Values.postgresql.auth.database }} 55 | {{- end }} 56 | {{- end }} 57 | 58 | 59 | 60 | {{/* 61 | Common labels 62 | */}} 63 | {{- define "strapi.labels" -}} 64 | helm.sh/chart: {{ include "strapi.chart" . }} 65 | {{ include "strapi.selectorLabels" . }} 66 | {{- if .Chart.AppVersion }} 67 | app.kubernetes.io/version: {{ .Chart.AppVersion | quote }} 68 | {{- end }} 69 | app.kubernetes.io/managed-by: {{ .Release.Service }} 70 | {{- end }} 71 | 72 | {{/* 73 | Selector labels 74 | */}} 75 | {{- define "strapi.selectorLabels" -}} 76 | app.kubernetes.io/name: {{ include "strapi.name" . }} 77 | app.kubernetes.io/instance: {{ .Release.Name }} 78 | {{- end }} 79 | 80 | 81 | {{- define "strapi.ingressAnnotations" -}} 82 | nginx.ingress.kubernetes.io/cors-allow-credentials: "true" 83 | nginx.ingress.kubernetes.io/cors-allow-methods: "PUT, GET, POST, OPTIONS, DELETE" 84 | {{- if .Values.dashboardDomain }} 85 | nginx.ingress.kubernetess.io/cors-allow-origin: {{ printf "%s%s" "https://" .Values.dashboardDomain }} 86 | nginx.ingress.kubernetes.io/enable-cors: "true" 87 | {{- end }} 88 | {{- if .Values.ingress.annotations }} 89 | {{ toYaml .Values.ingress.annotations }} 90 | {{- end }} 91 | {{- end }} 92 | 93 | {{- define "strapi.readReplicaIngressAnnotations" -}} 94 | nginx.ingress.kubernetes.io/cors-allow-credentials: "true" 95 | nginx.ingress.kubernetes.io/cors-allow-methods: "GET, OPTIONS" 96 | {{- if .Values.readReplicaIngress.annotations }} 97 | {{ toYaml .Values.readReplicaIngress.annotations }} 98 | {{- end }} 99 | {{- end }} 100 | 101 | 102 | 103 | 104 | {{/* 105 | Create the name of the service account to use 106 | */}} 107 | {{- define "strapi.serviceAccountName" -}} 108 | {{- if .Values.serviceAccount.create }} 109 | {{- default (include "strapi.fullname" .) .Values.serviceAccount.name }} 110 | {{- else }} 111 | {{- default "default" .Values.serviceAccount.name }} 112 | {{- end }} 113 | {{- end }} 114 | 115 | {{/* 116 | When readReplica.enabled, but not postgresql.architecture=replication, throw an error 117 | */}} 118 | {{- define "strapi.validateReadReplica" -}} 119 | {{- if and .Values.readReplica.enabled (ne .Values.postgresql.architecture "replication") }} 120 | {{- fail "readReplica.enabled requires postgresql.architecture=replication" }} 121 | {{- end }} 122 | {{- end }} 123 | -------------------------------------------------------------------------------- /charts/saleor/templates/dashboard_deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.dashboard.enabled -}} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-dashboard 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: dashboard 9 | spec: 10 | {{- if not .Values.dashboard.autoscaling.enabled }} 11 | replicas: {{ .Values.dashboard.replicaCount }} 12 | {{- end }} 13 | selector: 14 | matchLabels: 15 | {{- include "saleor.selectorLabels" . | nindent 6 }} 16 | app.kubernetes.io/component: dashboard 17 | template: 18 | metadata: 19 | {{- with .Values.dashboard.podAnnotations }} 20 | annotations: 21 | {{- toYaml . | nindent 8 }} 22 | {{- end }} 23 | labels: 24 | {{- include "saleor.selectorLabels" . | nindent 8 }} 25 | app.kubernetes.io/component: dashboard 26 | spec: 27 | {{- with .Values.imagePullSecrets }} 28 | imagePullSecrets: 29 | {{- toYaml . | nindent 8 }} 30 | {{- end }} 31 | serviceAccountName: {{ include "saleor.serviceAccountName" . }} 32 | securityContext: 33 | {{- toYaml .Values.dashboard.securityContext | nindent 8 }} 34 | {{- if gt (int .Values.dashboard.replicaCount) 1 }} 35 | affinity: 36 | podAntiAffinity: 37 | preferredDuringSchedulingIgnoredDuringExecution: 38 | - weight: 100 39 | podAffinityTerm: 40 | labelSelector: 41 | matchExpressions: 42 | - key: app.kubernetes.io/component 43 | operator: In 44 | values: 45 | - dashboard 46 | topologyKey: kubernetes.io/hostname 47 | {{- end }} 48 | {{- if .Values.dashboard.initContainers }} 49 | initContainers: 50 | {{- toYaml .Values.dashboard.initContainers | nindent 8 }} 51 | {{- end }} 52 | containers: 53 | - name: {{ .Chart.Name }}-dashboard 54 | securityContext: 55 | {{- toYaml .Values.dashboard.securityContext | nindent 12 }} 56 | image: "{{ .Values.dashboard.image.repository }}:{{ .Values.dashboard.image.tag | default .Chart.AppVersion }}" 57 | imagePullPolicy: {{ .Values.dashboard.image.pullPolicy }} 58 | ports: 59 | - name: http 60 | containerPort: {{ .Values.dashboard.service.port }} 61 | protocol: TCP 62 | livenessProbe: 63 | httpGet: 64 | path: / 65 | port: http 66 | initialDelaySeconds: 30 67 | periodSeconds: 10 68 | timeoutSeconds: 5 69 | successThreshold: 1 70 | failureThreshold: 3 71 | readinessProbe: 72 | httpGet: 73 | path: / 74 | port: http 75 | initialDelaySeconds: 30 76 | periodSeconds: 10 77 | timeoutSeconds: 5 78 | successThreshold: 1 79 | failureThreshold: 3 80 | resources: 81 | {{- toYaml .Values.dashboard.resources | nindent 12 }} 82 | env: 83 | - name: API_URL 84 | value: {{ if .Values.ingress.api.tls }}https{{ else }}http{{ end }}://{{ (index .Values.ingress.api.hosts 0).host }}/graphql/ 85 | - name: APP_MOUNT_URI 86 | value: "/dashboard/" 87 | - name: APPS_MARKETPLACE_API_URL 88 | value: {{ .Values.dashboard.appsMarketplaceApiUrl | quote }} 89 | {{- if .Values.dashboard.appsExtensionsApiUrl }} 90 | - name: EXTENSIONS_API_URL 91 | value: {{ .Values.dashboard.appsExtensionsApiUrl | quote }} 92 | {{- end }} 93 | - name: IS_CLOUD_INSTANCE 94 | value: {{ include "saleor.isCloudInstance" . | quote }} 95 | {{- if .Values.dashboard.extraEnv }} 96 | {{- toYaml .Values.dashboard.extraEnv | nindent 12 }} 97 | {{- end }} 98 | {{- if .Values.dashboard.volumeMounts }} 99 | volumeMounts: 100 | {{- toYaml .Values.dashboard.volumeMounts | nindent 12 }} 101 | {{- end }} 102 | {{- if .Values.dashboard.volumes }} 103 | volumes: 104 | {{- toYaml .Values.dashboard.volumes | nindent 8 }} 105 | {{- end }} 106 | {{- with .Values.nodeSelector }} 107 | nodeSelector: 108 | {{- toYaml . | nindent 8 }} 109 | {{- end }} 110 | {{- with .Values.tolerations }} 111 | tolerations: 112 | {{- toYaml . | nindent 8 }} 113 | {{- end }} 114 | {{- end }} 115 | -------------------------------------------------------------------------------- /charts/saleor/test-values/production-values.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | secretKey: "qdfwd" 3 | 4 | api: 5 | enabled: true 6 | replicaCount: 3 7 | autoscaling: 8 | enabled: true 9 | minReplicas: 3 10 | maxReplicas: 10 11 | resources: 12 | requests: 13 | cpu: 1 14 | memory: 2Gi 15 | limits: 16 | cpu: 2 17 | memory: 4Gi 18 | service: 19 | type: ClusterIP 20 | port: 8000 21 | extraEnv: 22 | - name: ALLOWED_HOSTS 23 | value: "*" 24 | - name: DEBUG 25 | value: "False" 26 | - name: DEFAULT_FROM_EMAIL 27 | value: "noreply@saleor.io" 28 | - name: EMAIL_URL 29 | valueFrom: 30 | secretKeyRef: 31 | name: saleor-email 32 | key: url 33 | optional: true 34 | 35 | dashboard: 36 | enabled: true 37 | replicaCount: 2 38 | resources: 39 | requests: 40 | cpu: 500m 41 | memory: 512Mi 42 | limits: 43 | cpu: 1 44 | memory: 1Gi 45 | service: 46 | type: ClusterIP 47 | port: 80 48 | 49 | worker: 50 | enabled: true 51 | replicaCount: 2 52 | resources: 53 | requests: 54 | cpu: 500m 55 | memory: 1Gi 56 | limits: 57 | cpu: 1 58 | memory: 2Gi 59 | 60 | postgresql: 61 | enabled: true 62 | architecture: replication 63 | auth: 64 | username: saleor 65 | database: saleor 66 | primary: 67 | persistence: 68 | size: 50Gi 69 | resources: 70 | requests: 71 | cpu: 2 72 | memory: 4Gi 73 | extendedConfiguration: | 74 | work_mem = 64MB 75 | maintenance_work_mem = 256MB 76 | shared_buffers = 3000MB 77 | max_connections = 150 78 | readReplicas: 79 | replicaCount: 2 80 | persistence: 81 | size: 50Gi 82 | resources: 83 | requests: 84 | cpu: 1 85 | memory: 2Gi 86 | 87 | redis: 88 | enabled: true 89 | architecture: replication 90 | auth: 91 | enabled: true 92 | master: 93 | persistence: 94 | size: 8Gi 95 | resources: 96 | requests: 97 | cpu: 500m 98 | memory: 1Gi 99 | limits: 100 | cpu: 1 101 | memory: 2Gi 102 | replica: 103 | replicaCount: 2 104 | persistence: 105 | size: 8Gi 106 | resources: 107 | requests: 108 | cpu: 250m 109 | memory: 512Mi 110 | limits: 111 | cpu: 500m 112 | memory: 1Gi 113 | 114 | serviceMesh: 115 | enabled: true 116 | istio: 117 | enabled: true 118 | api: 119 | connectionPool: 120 | enabled: true 121 | http: 122 | http1MaxPendingRequests: 1 123 | maxRequestsPerConnection: 1 124 | tcp: 125 | maxConnections: 100 126 | loadBalancer: 127 | enabled: true 128 | simple: ROUND_ROBIN 129 | outlierDetection: 130 | enabled: true 131 | baseEjectionTime: 30s 132 | consecutiveErrors: 5 133 | interval: 10s 134 | maxEjectionPercent: 100 135 | dashboard: 136 | connectionPool: 137 | enabled: true 138 | http: 139 | http1MaxPendingRequests: 1 140 | maxRequestsPerConnection: 1 141 | tcp: 142 | maxConnections: 100 143 | loadBalancer: 144 | enabled: true 145 | simple: ROUND_ROBIN 146 | outlierDetection: 147 | enabled: true 148 | baseEjectionTime: 30s 149 | consecutiveErrors: 5 150 | interval: 10s 151 | maxEjectionPercent: 100 152 | 153 | ingress: 154 | enabled: true 155 | className: nginx 156 | annotations: 157 | nginx.ingress.kubernetes.io/proxy-body-size: "0" 158 | nginx.ingress.kubernetes.io/proxy-read-timeout: "600" 159 | nginx.ingress.kubernetes.io/proxy-send-timeout: "600" 160 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 161 | api: 162 | enabled: true 163 | hosts: 164 | - host: api.saleor.example.com 165 | paths: 166 | - path: / 167 | pathType: Prefix 168 | tls: 169 | - hosts: 170 | - api.saleor.example.com 171 | secretName: saleor-api-tls 172 | dashboard: 173 | enabled: true 174 | hosts: 175 | - host: dashboard.saleor.example.com 176 | paths: 177 | - path: / 178 | pathType: Prefix 179 | tls: 180 | - hosts: 181 | - dashboard.saleor.example.com 182 | secretName: saleor-dashboard-tls 183 | 184 | podSecurityContext: 185 | fsGroup: 1000 186 | runAsUser: 1000 187 | runAsNonRoot: true 188 | 189 | securityContext: 190 | capabilities: 191 | drop: 192 | - ALL 193 | readOnlyRootFilesystem: true 194 | runAsNonRoot: true 195 | runAsUser: 1000 196 | 197 | podDisruptionBudget: 198 | enabled: true 199 | minAvailable: 1 200 | -------------------------------------------------------------------------------- /charts/strapi/templates/ingress.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.ingress.enabled -}} 2 | {{- $fullName := include "strapi.fullname" . -}} 3 | {{- $svcPort := .Values.service.port -}} 4 | {{- if and .Values.ingress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 5 | {{- if not (hasKey .Values.ingress.annotations "kubernetes.io/ingress.class") }} 6 | {{- $_ := set .Values.ingress.annotations "kubernetes.io/ingress.class" .Values.ingress.className}} 7 | {{- end }} 8 | {{- end }} 9 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 10 | apiVersion: networking.k8s.io/v1 11 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 12 | apiVersion: networking.k8s.io/v1beta1 13 | {{- else -}} 14 | apiVersion: extensions/v1beta1 15 | {{- end }} 16 | kind: Ingress 17 | metadata: 18 | name: {{ $fullName }} 19 | labels: 20 | {{- include "strapi.labels" . | nindent 4 }} 21 | annotations: 22 | {{- include "strapi.ingressAnnotations" . | nindent 4 }} 23 | spec: 24 | {{- if and .Values.ingress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 25 | ingressClassName: {{ .Values.ingress.className }} 26 | {{- end }} 27 | {{- if .Values.ingress.tls.enabled }} 28 | tls: 29 | - hosts: 30 | - {{ lower .Values.ingress.host | quote }} 31 | {{- if .Values.ingress.tls.secretName }} 32 | secretName: {{ .Values.ingress.tls.secretName }} 33 | {{- else }} 34 | secretName: "{{ $fullName }}-tls-secret" 35 | {{- end }} 36 | {{- end }} 37 | rules: 38 | {{- if .Values.ingress.host }} 39 | - host: {{ lower .Values.ingress.host | quote }} 40 | http: 41 | paths: 42 | - path: "/" 43 | {{- if and .Values.ingress.pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 44 | pathType: {{ .Values.ingress.pathType }} 45 | {{- end }} 46 | backend: 47 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 48 | service: 49 | name: {{ $fullName }} 50 | port: 51 | number: {{ $svcPort }} 52 | {{- else }} 53 | serviceName: {{ $fullName }} 54 | servicePort: {{ $svcPort }} 55 | {{- end }} 56 | {{- end }} 57 | {{- end }} 58 | 59 | --- 60 | {{- if .Values.readReplicaIngress.enabled -}} 61 | {{- $fullName := include "strapi.fullname" . -}} 62 | {{- $svcPort := .Values.service.port -}} 63 | {{- if and .Values.readReplicaIngress.className (not (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion)) }} 64 | {{- if not (hasKey .Values.readReplicaIngress.annotations "kubernetes.io/ingress.class") }} 65 | {{- $_ := set .Values.readReplicaIngress.annotations "kubernetes.io/ingress.class" .Values.readReplicaIngress.className}} 66 | {{- end }} 67 | {{- end }} 68 | {{- if semverCompare ">=1.19-0" .Capabilities.KubeVersion.GitVersion -}} 69 | apiVersion: networking.k8s.io/v1 70 | {{- else if semverCompare ">=1.14-0" .Capabilities.KubeVersion.GitVersion -}} 71 | apiVersion: networking.k8s.io/v1beta1 72 | {{- else -}} 73 | apiVersion: extensions/v1beta1 74 | {{- end }} 75 | kind: Ingress 76 | metadata: 77 | name: {{ $fullName }}-all 78 | labels: 79 | {{- include "strapi.labels" . | nindent 4 }} 80 | annotations: 81 | {{- include "strapi.readReplicaIngressAnnotations" . | nindent 4 }} 82 | spec: 83 | {{- if and .Values.readReplicaIngress.className (semverCompare ">=1.18-0" .Capabilities.KubeVersion.GitVersion) }} 84 | ingressClassName: {{ .Values.readReplicaIngress.className }} 85 | {{- end }} 86 | {{- if .Values.readReplicaIngress.tls.enabled }} 87 | tls: 88 | - hosts: 89 | - {{ lower .Values.readReplicaIngress.host | quote }} 90 | {{- if .Values.readReplicaIngress.tls.secretName }} 91 | secretName: {{ .Values.readReplicaIngress.tls.secretName }} 92 | {{- else }} 93 | secretName: "{{ $fullName }}-all-tls-secret" 94 | {{- end }} 95 | {{- end }} 96 | rules: 97 | {{- if .Values.readReplicaIngress.host }} 98 | - host: {{ lower .Values.readReplicaIngress.host | quote }} 99 | http: 100 | paths: 101 | - path: "/" 102 | {{- if and .Values.readReplicaIngress.pathType (semverCompare ">=1.18-0" $.Capabilities.KubeVersion.GitVersion) }} 103 | pathType: {{ .Values.readReplicaIngress.pathType }} 104 | {{- end }} 105 | backend: 106 | {{- if semverCompare ">=1.19-0" $.Capabilities.KubeVersion.GitVersion }} 107 | service: 108 | name: {{ $fullName }}-all 109 | port: 110 | number: {{ $svcPort }} 111 | {{- else }} 112 | serviceName: {{ $fullName }}-all 113 | servicePort: {{ $svcPort }} 114 | {{- end }} 115 | {{- end }} 116 | {{- end }} -------------------------------------------------------------------------------- /charts/saleor/scripts/generate_settings_configmap.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # generate_settings_configmap.sh 4 | # 5 | # Description: 6 | # This script generates a Kubernetes ConfigMap containing a modified version of Saleor's settings.py 7 | # that includes read replica database configuration. The script should be run whenever: 8 | # 1. The Saleor version is updated in the Helm chart (check Chart.yaml for the version) 9 | # 2. The database configuration for read replicas needs to be modified 10 | # 11 | # Usage: 12 | # ./generate_settings_configmap.sh 13 | # 14 | # Example: 15 | # ./generate_settings_configmap.sh 3.20.65 16 | # 17 | # Dependencies: 18 | # - curl: for downloading the settings.py file 19 | # - sed: for text processing 20 | # 21 | # The script will: 22 | # 1. Download the settings.py file from the specified Saleor version 23 | # 2. Modify the DATABASES configuration to include read replica settings 24 | # 3. Generate a ConfigMap in the correct Helm chart templates directory 25 | # 26 | # Note: 27 | # This script should be run from the root of the helm-charts repository 28 | # or from within the charts/saleor directory. 29 | 30 | set -e # Exit on any error 31 | 32 | # Function to find the correct chart directory 33 | find_chart_dir() { 34 | local current_dir="$PWD" 35 | local chart_dir 36 | 37 | # Check if we're in the charts/saleor directory 38 | if [[ "$current_dir" == */charts/saleor ]]; then 39 | chart_dir="$current_dir" 40 | # Check if we're in the helm-charts root 41 | elif [[ "$current_dir" == */helm-charts ]]; then 42 | chart_dir="$current_dir/charts/saleor" 43 | # Check if we're in the scripts directory 44 | elif [[ "$current_dir" == */charts/saleor/scripts ]]; then 45 | chart_dir="$(dirname "$current_dir")" 46 | else 47 | echo "Error: Script must be run from helm-charts root or charts/saleor directory" 48 | echo "Current directory: $current_dir" 49 | exit 1 50 | fi 51 | 52 | echo "$chart_dir" 53 | } 54 | 55 | # Check if version parameter is provided 56 | if [ -z "$1" ]; then 57 | echo "Usage: $0 " 58 | echo "Example: $0 3.20.65" 59 | exit 1 60 | fi 61 | 62 | # Validate version format 63 | if ! [[ $1 =~ ^[0-9]+\.[0-9]+\.[0-9]+$ ]]; then 64 | echo "Error: Version must be in format X.Y.Z (e.g., 3.20.65)" 65 | exit 1 66 | fi 67 | 68 | VERSION=$1 69 | SETTINGS_URL="https://raw.githubusercontent.com/saleor/saleor/refs/tags/${VERSION}/saleor/settings.py" 70 | 71 | # Find the correct chart directory and set output paths 72 | CHART_DIR=$(find_chart_dir) 73 | TEMPLATES_DIR="$CHART_DIR/templates" 74 | OUTPUT_FILE="$TEMPLATES_DIR/configmap-settings.yaml" 75 | 76 | echo "Chart directory: $CHART_DIR" 77 | echo "Output file: $OUTPUT_FILE" 78 | 79 | # Verify the templates directory exists 80 | if [ ! -d "$TEMPLATES_DIR" ]; then 81 | echo "Error: Templates directory not found at $TEMPLATES_DIR" 82 | exit 1 83 | fi 84 | 85 | # Download the original settings.py 86 | echo "Downloading settings.py from version ${VERSION}..." 87 | SETTINGS_CONTENT=$(curl -s "$SETTINGS_URL") 88 | 89 | if [ $? -ne 0 ]; then 90 | echo "Error: Failed to download settings.py from $SETTINGS_URL" 91 | exit 1 92 | fi 93 | 94 | # Create a temporary file for the modified settings 95 | TEMP_FILE=$(mktemp) 96 | 97 | # Write the settings content to the temp file 98 | echo "$SETTINGS_CONTENT" > "$TEMP_FILE" 99 | 100 | # Use sed to replace the DATABASES block 101 | echo "Modifying settings.py..." 102 | sed -i.bak '/^DATABASES = {/,/^}/c\ 103 | DATABASES = {\ 104 | "default": dj_database_url.config(\ 105 | default=os.environ.get("DATABASE_URL"),\ 106 | conn_max_age=DB_CONN_MAX_AGE,\ 107 | ),\ 108 | "replica": dj_database_url.config(\ 109 | env="DATABASE_URL_REPLICA",\ 110 | conn_max_age=DB_CONN_MAX_AGE,\ 111 | test_options={"MIRROR": "default"},\ 112 | ),\ 113 | }\ 114 | \ 115 | DATABASE_CONNECTION_REPLICA_NAME = "replica"\ 116 | DATABASE_CONNECTION_DEFAULT_NAME = "default"\ 117 | DATABASE_CONNECTION_REPLICA_TIMEOUT = int(\ 118 | os.environ.get("DATABASE_CONNECTION_REPLICA_TIMEOUT", 3)\ 119 | )' "$TEMP_FILE" 120 | 121 | # Create the ConfigMap 122 | echo "Generating ConfigMap..." 123 | cat > "$OUTPUT_FILE" << EOF 124 | {{- if include "saleor.readReplicaEnabled" . }} 125 | apiVersion: v1 126 | kind: ConfigMap 127 | metadata: 128 | name: {{ include "saleor.fullname" . }}-settings 129 | labels: 130 | {{- include "saleor.labels" . | nindent 4 }} 131 | data: 132 | settings.py: | 133 | $(sed 's/^/ /' "$TEMP_FILE") 134 | {{- end }} 135 | EOF 136 | 137 | # Clean up 138 | rm "$TEMP_FILE" "$TEMP_FILE.bak" 139 | 140 | echo "ConfigMap generated at $OUTPUT_FILE" 141 | echo "Done!" 142 | 143 | # Add a reminder about Chart.yaml version 144 | echo 145 | echo "Remember to check that the Saleor version in Chart.yaml matches $VERSION" 146 | echo "Current location: $CHART_DIR/Chart.yaml" 147 | -------------------------------------------------------------------------------- /charts/strapi/values.yaml: -------------------------------------------------------------------------------- 1 | # Default values for strapi. 2 | # This is a YAML-formatted file. 3 | # Declare variables to be passed into your templates. 4 | 5 | replicaCount: 1 6 | 7 | # You can use read-only replicas of strapi. Only works, if you use the included DB and enable the replica there 8 | readReplica: 9 | enabled: false 10 | replicaCount: 0 11 | 12 | image: 13 | # image name overrides repository and tag. 14 | imageName: "" 15 | repository: ghcr.io/strapi/ 16 | pullPolicy: IfNotPresent 17 | # Overrides the image tag whose default is the chart appVersion. 18 | tag: "" 19 | 20 | dashboardDomain: "dashboard.domain.com" 21 | 22 | # change this secret 23 | adminJWTSecret: $XX2UnMcN6%%b@CkFof* 24 | 25 | imagePullSecrets: 26 | - name: github 27 | nameOverride: "" 28 | fullnameOverride: "" 29 | 30 | # enable the cronjob to create DB backups to S3. You can specify how many DB dumps should be kept. 31 | postgresBackup: 32 | enabled: false 33 | historyLimit: 5 34 | schedule: 0 */8 * * * 35 | bucketName: postgres-backup 36 | 37 | postgresql: 38 | enabled: true 39 | metrics: 40 | enabled: false 41 | auth: 42 | # set the master PW here 43 | postgresPassword: 44 | username: strapi 45 | # set a password here! 46 | password: 47 | database: strapi 48 | tls: 49 | enabled: true 50 | autoGenerated: true 51 | volumePermissions: 52 | enabled: true 53 | image: 54 | tag: "13.5.0" 55 | primary: 56 | persistence: 57 | enabled: false 58 | size: 59 | 60 | serviceAccount: 61 | # Specifies whether a service account should be created 62 | create: true 63 | # Annotations to add to the service account 64 | annotations: {} 65 | # The name of the service account to use. 66 | # If not set and create is true, a name is generated using the fullname template 67 | name: "" 68 | 69 | podAnnotations: {} 70 | 71 | podSecurityContext: 72 | {} 73 | # fsGroup: 2000 74 | 75 | securityContext: 76 | {} 77 | # capabilities: 78 | # drop: 79 | # - ALL 80 | # readOnlyRootFilesystem: true 81 | # runAsNonRoot: true 82 | # runAsUser: 1000 83 | 84 | service: 85 | type: ClusterIP 86 | port: 80 87 | 88 | # the full backend URL of strapi 89 | strapiApiUrl: https://strapi.example.com 90 | ingress: 91 | enabled: true 92 | className: "" 93 | host: chart-example.local 94 | pathType: ImplementationSpecific 95 | tls: 96 | enabled: true 97 | secretName: 98 | annotations: 99 | cert-manager.io/acme-challenge-type: http01 100 | cert-manager.io/cluster-issuer: letsencrypt-prod 101 | nginx.ingress.kubernetes.io/proxy-body-size: "800m" 102 | 103 | readReplicaIngress: 104 | enabled: false 105 | className: "" 106 | host: chart-example.local 107 | pathType: ImplementationSpecific 108 | tls: 109 | enabled: true 110 | secretName: 111 | annotations: 112 | cert-manager.io/acme-challenge-type: http01 113 | cert-manager.io/cluster-issuer: letsencrypt-prod 114 | 115 | # S3 storage options. Settings need to be set, as containers are volatile 116 | s3: 117 | enabled: false 118 | accesKeyId: "" 119 | accessSecret: "" 120 | endpoint: "s3.us-east-2.amazonaws.com" 121 | bucket: "strapi" 122 | 123 | # If you are using the cloudflare R2 plugin 124 | r2: 125 | enabled: false 126 | accesKeyId: "" 127 | accessSecret: "" 128 | endpoint: "" 129 | bucket: "strapi" 130 | 131 | resources: 132 | # We usually recommend not to specify default resources and to leave this as a conscious 133 | # choice for the user. This also increases chances charts run on environments with little 134 | # resources, such as Minikube. If you do want to specify resources, uncomment the following 135 | # lines, adjust them as necessary, and remove the curly braces after 'resources:'. 136 | limits: 137 | requests: 138 | cpu: 150m 139 | memory: 100Mi 140 | 141 | # autoscaling works just for the primary strapi pods. We wouldn't recommend it, as the startup is always expensive and 142 | # in general the whole strapi setup is not really meant to be autoscaled. 143 | autoscaling: 144 | enabled: true 145 | minReplicas: 1 146 | maxReplicas: 2 147 | targetCPUUtilizationPercentage: 80 148 | # targetMemoryUtilizationPercentage: 80 149 | 150 | livenessProbe: 151 | httpGet: 152 | path: "/_health" 153 | port: http 154 | periodSeconds: 10 155 | readinessProbe: 156 | httpGet: 157 | path: "/_health" 158 | port: http 159 | periodSeconds: 10 160 | failureThreshold: 5 161 | startupProbe: 162 | httpGet: 163 | path: "/_health" 164 | port: http 165 | initialDelaySeconds: 30 166 | periodSeconds: 5 167 | failureThreshold: 30 168 | 169 | nodeSelector: {} 170 | 171 | tolerations: [] 172 | 173 | affinity: {} 174 | 175 | # Just add here secrets, that you want to get mounted 176 | additionalSecretMounts: 177 | 178 | # Add env variables with key and value, that should be added to the strapi container 179 | additionalEnvVariables: 180 | # TESTKEY: value 181 | 182 | # You can set a database URL here if you don't want to use the included DB 183 | secrets: 184 | databaseUrl: 185 | -------------------------------------------------------------------------------- /charts/gtm-server-container-cluster/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- $fullName := include "gtm-server-container-cluster.fullname" . -}} 2 | {{- $taggingHost := .Values.ingress.taggingHost -}} 3 | 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: {{ include "gtm-server-container-cluster.fullname" . }} 8 | labels: 9 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 10 | spec: 11 | {{- if not .Values.autoscaling.enabled }} 12 | replicas: {{ .Values.replicaCount }} 13 | {{- end }} 14 | selector: 15 | matchLabels: 16 | {{- include "gtm-server-container-cluster.selectorLabels" . | nindent 6 }} 17 | app.kubernetes.io/type: "tagging" 18 | template: 19 | metadata: 20 | {{- with .Values.podAnnotations }} 21 | annotations: 22 | {{- toYaml . | nindent 8 }} 23 | {{- end }} 24 | labels: 25 | {{- include "gtm-server-container-cluster.selectorLabels" . | nindent 8 }} 26 | app.kubernetes.io/type: "tagging" 27 | spec: 28 | {{- with .Values.imagePullSecrets }} 29 | imagePullSecrets: 30 | {{- toYaml . | nindent 8 }} 31 | {{- end }} 32 | serviceAccountName: {{ include "gtm-server-container-cluster.serviceAccountName" . }} 33 | securityContext: 34 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 35 | containers: 36 | - name: gtm-server-tagging 37 | securityContext: 38 | {{- toYaml .Values.securityContext | nindent 12 }} 39 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 40 | imagePullPolicy: {{ .Values.image.pullPolicy }} 41 | ports: 42 | - name: http 43 | containerPort: 8080 44 | protocol: TCP 45 | livenessProbe: 46 | httpGet: 47 | path: /healthz 48 | port: http 49 | readinessProbe: 50 | httpGet: 51 | path: /healthz 52 | port: http 53 | resources: 54 | {{- toYaml .Values.resources | nindent 12 }} 55 | env: 56 | - name: CONTAINER_CONFIG 57 | value: {{ .Values.gtm.containerSettings }} 58 | - name: PREVIEW_SERVER_URL 59 | # we take the first entry from the ingress.rules.taggingHost 60 | value: "https://{{ (index .Values.ingress.rules 0).taggingHost }}/preview" 61 | 62 | {{- with .Values.nodeSelector }} 63 | nodeSelector: 64 | {{- toYaml . | nindent 8 }} 65 | {{- end }} 66 | {{- with .Values.affinity }} 67 | affinity: 68 | {{- toYaml . | nindent 8 }} 69 | {{- end }} 70 | {{- with .Values.tolerations }} 71 | tolerations: 72 | {{- toYaml . | nindent 8 }} 73 | {{- end }} 74 | 75 | --- 76 | apiVersion: apps/v1 77 | kind: Deployment 78 | metadata: 79 | name: "{{ $fullName }}-preview" 80 | labels: 81 | {{- include "gtm-server-container-cluster.labels" . | nindent 4 }} 82 | spec: 83 | replicas: 1 84 | selector: 85 | matchLabels: 86 | {{- include "gtm-server-container-cluster.selectorLabels" . | nindent 6 }} 87 | app.kubernetes.io/type: "preview" 88 | template: 89 | metadata: 90 | {{- with .Values.podAnnotations }} 91 | annotations: 92 | {{- toYaml . | nindent 8 }} 93 | {{- end }} 94 | labels: 95 | {{- include "gtm-server-container-cluster.selectorLabels" . | nindent 8 }} 96 | app.kubernetes.io/type: "preview" 97 | spec: 98 | {{- with .Values.imagePullSecrets }} 99 | imagePullSecrets: 100 | {{- toYaml . | nindent 8 }} 101 | {{- end }} 102 | serviceAccountName: {{ include "gtm-server-container-cluster.serviceAccountName" . }} 103 | securityContext: 104 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 105 | containers: 106 | - name: gtm-server-preview 107 | securityContext: 108 | {{- toYaml .Values.securityContext | nindent 12 }} 109 | image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 110 | imagePullPolicy: {{ .Values.image.pullPolicy }} 111 | ports: 112 | - name: http 113 | containerPort: 8080 114 | protocol: TCP 115 | livenessProbe: 116 | httpGet: 117 | path: /healthz 118 | port: http 119 | readinessProbe: 120 | httpGet: 121 | path: /healthz 122 | port: http 123 | resources: 124 | {{- toYaml .Values.resources | nindent 12 }} 125 | env: 126 | - name: CONTAINER_CONFIG 127 | value: {{ .Values.gtm.containerSettings }} 128 | - name: RUN_AS_PREVIEW_SERVER 129 | value: "true" 130 | {{- with .Values.nodeSelector }} 131 | nodeSelector: 132 | {{- toYaml . | nindent 8 }} 133 | {{- end }} 134 | {{- with .Values.affinity }} 135 | affinity: 136 | {{- toYaml . | nindent 8 }} 137 | {{- end }} 138 | {{- with .Values.tolerations }} 139 | tolerations: 140 | {{- toYaml . | nindent 8 }} 141 | {{- end }} -------------------------------------------------------------------------------- /charts/saleor-apps/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- range $appName, $appConfig := .Values.apps }} 2 | {{- if $appConfig.enabled }} 3 | --- 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: {{ printf "%s-%s" (include "saleor-apps.fullname" $) $appName }} 8 | labels: 9 | {{- include "saleor-apps.labels" $ | nindent 4 }} 10 | app.kubernetes.io/component: {{ $appName }} 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | {{- include "saleor-apps.selectorLabels" $ | nindent 6 }} 16 | app.kubernetes.io/component: {{ $appName }} 17 | template: 18 | metadata: 19 | labels: 20 | {{- include "saleor-apps.selectorLabels" $ | nindent 8 }} 21 | app.kubernetes.io/component: {{ $appName }} 22 | spec: 23 | containers: 24 | - name: {{ $appName }} 25 | {{- if and (hasKey $appConfig "image") (hasKey $appConfig.image "registry") (hasKey $appConfig.image "repository") (hasKey $appConfig.image "tag") }} 26 | image: "{{ $appConfig.image.registry }}/{{ $appConfig.image.repository }}:{{ $appConfig.image.tag }}" 27 | {{- else }} 28 | image: "{{ $.Values.common.image.registry }}/{{ printf "%s/saleor-app-%s" $.Values.common.image.repository (hasPrefix "app-" $appName | ternary (trimPrefix "app-" $appName) $appName) }}:{{ default $.Values.common.image.tag (hasKey $appConfig "image" | ternary (hasKey $appConfig.image "tag" | ternary $appConfig.image.tag "") "") }}" 29 | {{- end }} 30 | imagePullPolicy: {{ $.Values.common.image.pullPolicy }} 31 | env: 32 | - name: SECRET_KEY 33 | valueFrom: 34 | secretKeyRef: 35 | name: {{ include "saleor-apps.fullname" $ }} 36 | key: secret-key 37 | - name: PORT 38 | value: {{ $appConfig.port | default 3000 | quote }} 39 | - name: HOSTNAME 40 | value: "0.0.0.0" 41 | - name: REDIS_URL 42 | value: {{ include "saleor-apps.redis.url" $ | quote }} 43 | - name: APL 44 | value: {{ $.Values.common.apl | quote }} 45 | - name: APP_LOG_LEVEL 46 | value: {{ $.Values.global.appLogLevel | quote }} 47 | {{- if eq $appName "app-avatax" }} 48 | {{- if (get $appConfig "dynamodb").enabled }} 49 | # DynamoDB environment variables for Avatax app 50 | - name: DYNAMODB_LOGS_TABLE_NAME 51 | value: {{ (get $appConfig "dynamodb").logsTableName | quote }} 52 | - name: DYNAMODB_LOGS_ITEM_TTL_IN_DAYS 53 | value: {{ (get $appConfig "dynamodb").logsItemTtlInDays | quote }} 54 | - name: AWS_REGION 55 | value: {{ (get $appConfig "dynamodb").region | quote }} 56 | - name: AWS_ENDPOINT_URL 57 | value: "http://{{ printf "%s-dynamodb" (include "saleor-apps.fullname" $) }}:8000" 58 | - name: AWS_ACCESS_KEY_ID 59 | valueFrom: 60 | secretKeyRef: 61 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" $) }} 62 | key: access-key-id 63 | - name: AWS_SECRET_ACCESS_KEY 64 | valueFrom: 65 | secretKeyRef: 66 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" $) }} 67 | key: secret-access-key 68 | {{- end }} 69 | {{- end }} 70 | {{- if $appConfig.extraEnvs }} 71 | {{- toYaml $appConfig.extraEnvs | nindent 12 }} 72 | {{- end }} 73 | ports: 74 | - name: http 75 | containerPort: {{ $appConfig.port }} 76 | protocol: TCP 77 | {{- if $appConfig.probes | default $.Values.common.probes }} 78 | {{- with $appConfig.probes | default $.Values.common.probes }} 79 | livenessProbe: 80 | {{- if .path }} 81 | httpGet: 82 | path: {{ .path }} 83 | port: http 84 | {{- else }} 85 | tcpSocket: 86 | port: http 87 | {{- end }} 88 | initialDelaySeconds: {{ .initialDelaySeconds | default 10 }} 89 | periodSeconds: {{ .periodSeconds | default 10 }} 90 | timeoutSeconds: {{ .timeoutSeconds | default 5 }} 91 | successThreshold: {{ .successThreshold | default 1 }} 92 | failureThreshold: {{ .failureThreshold | default 3 }} 93 | readinessProbe: 94 | {{- if .path }} 95 | httpGet: 96 | path: {{ .path }} 97 | port: http 98 | {{- else }} 99 | tcpSocket: 100 | port: http 101 | {{- end }} 102 | initialDelaySeconds: {{ .initialDelaySeconds | default 5 }} 103 | periodSeconds: {{ .periodSeconds | default 10 }} 104 | timeoutSeconds: {{ .timeoutSeconds | default 5 }} 105 | successThreshold: {{ .successThreshold | default 1 }} 106 | failureThreshold: {{ .failureThreshold | default 3 }} 107 | {{- end }} 108 | {{- end }} 109 | resources: 110 | {{- toYaml $.Values.common.resources | nindent 12 }} 111 | {{- end }} 112 | {{- end }} 113 | -------------------------------------------------------------------------------- /charts/saleor/docs/gcs-storage.md: -------------------------------------------------------------------------------- 1 | # Google Cloud Storage (GCS) Configuration for Saleor 2 | 3 | This document explains how to configure Google Cloud Storage (GCS) for Saleor using the Helm chart. 4 | 5 | ## Prerequisites 6 | 7 | 1. A Google Cloud Platform (GCP) account with a project 8 | 2. A GCS bucket created for Saleor media files 9 | 3. A service account with appropriate permissions to access the GCS bucket 10 | 4. A service account key (JSON) for authentication 11 | 12 | ## Creating a Service Account and Key 13 | 14 | 1. Go to the [Google Cloud Console](https://console.cloud.google.com/) 15 | 2. Navigate to "IAM & Admin" > "Service Accounts" 16 | 3. Create a new service account or select an existing one 17 | 4. Assign the following roles to the service account: 18 | - Storage Object Admin (`roles/storage.objectAdmin`) for the bucket(s) 19 | - Storage Admin (`roles/storage.admin`) if you want Saleor to create buckets 20 | 5. Create a new JSON key for the service account 21 | 6. Download the JSON key file 22 | 23 | ## Configuring the Helm Chart 24 | 25 | Update your `values.yaml` file or use `--set` flags to configure GCS storage: 26 | 27 | ```yaml 28 | storage: 29 | gcs: 30 | enabled: true 31 | credentials: 32 | # Paste the entire content of your service account JSON key file 33 | jsonKey: | 34 | { 35 | "type": "service_account", 36 | "project_id": "your-project-id", 37 | "private_key_id": "key-id", 38 | "private_key": "-----BEGIN PRIVATE KEY-----\nkey-content\n-----END PRIVATE KEY-----\n", 39 | "client_email": "service-account@your-project-id.iam.gserviceaccount.com", 40 | "client_id": "client-id", 41 | "auth_uri": "https://accounts.google.com/o/oauth2/auth", 42 | "token_uri": "https://oauth2.googleapis.com/token", 43 | "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", 44 | "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/service-account%40your-project-id.iam.gserviceaccount.com" 45 | } 46 | config: 47 | 48 | # Static files configuration (CSS, JS, email templates) 49 | staticBucketName: "my-saleor-static" 50 | 51 | # Media files configuration (product images, category images) 52 | mediaBucketName: "my-saleor-media" 53 | 54 | # Private files configuration (webhook payloads, private data) 55 | mediaPrivateBucketName: "my-saleor-private" 56 | 57 | # Optional: Custom endpoints for GCS 58 | # customEndpoint: "https://storage.googleapis.com" 59 | # mediaCustomEndpoint: "https://storage.googleapis.com" 60 | 61 | # Access control and URL settings 62 | defaultAcl: "publicRead" # Options: "publicRead", leave empty for private 63 | queryStringAuth: true # Enable signed URLs for media access. Optional 64 | queryStringExpire: 86400 # Signed URLs expiration in seconds (1 day). Optional. 65 | ``` 66 | 67 | ## Security Considerations 68 | 69 | 1. The service account JSON key contains sensitive credentials. Ensure it's properly secured. 70 | 2. Consider using Kubernetes Secrets management solutions like Sealed Secrets, Vault, or a cloud provider's secret management service. 71 | 3. For the `mediaPrivateBucketName` bucket, ensure it has appropriate access controls to prevent public access to sensitive data. 72 | 73 | ## CORS Configuration for GCS Buckets 74 | 75 | For proper functioning of Saleor with GCS, you need to configure CORS settings on your buckets. This is especially important for serving SVG files, JavaScript files, and other web assets. 76 | 77 | 1. Go to the [Google Cloud Console](https://console.cloud.google.com/) 78 | 2. Navigate to "Storage" > "Browser" 79 | 3. Select your bucket 80 | 4. Go to the "Permissions" tab 81 | 5. Scroll down to the "CORS configuration" section 82 | 6. Add a CORS configuration like the following: 83 | 84 | ```xml 85 | 86 | 87 | 88 | 89 | https://your-saleor-domain.com 90 | 91 | 92 | GET 93 | HEAD 94 | 95 | 96 | Content-Type 97 | 98 | 3600 99 | 100 | 101 | ``` 102 | 103 | Replace `https://your-saleor-domain.com` with your actual Saleor domain. 104 | 105 | ## Troubleshooting 106 | 107 | 1. **Permission Issues**: Ensure the service account has the correct roles assigned for the GCS buckets. 108 | 2. **Invalid Credentials**: Verify the JSON key is correctly formatted and not corrupted. 109 | 3. **CORS Issues**: If you're experiencing issues with loading assets, check the CORS configuration on your GCS bucket. 110 | 4. **Bucket Not Found**: Confirm the bucket names are correct and the buckets exist in the specified project. 111 | 112 | ## Why Workload Identity Isn't Supported 113 | 114 | Saleor requires the `GOOGLE_APPLICATION_CREDENTIALS` environment variable to point to a JSON file containing the service account credentials. When using Workload Identity in Kubernetes, credentials are provided through the metadata server, not as a JSON file. Since Saleor's storage backend expects a file path, Workload Identity cannot be used directly. 115 | 116 | If you're running on GKE and want to avoid managing service account keys, consider implementing a sidecar container that fetches a short-lived service account key and periodically refreshes it for Saleor to use. 117 | -------------------------------------------------------------------------------- /charts/saleor-apps/templates/dynamodb-deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if (index .Values.apps "app-avatax") }} 2 | {{- if (get (index .Values.apps "app-avatax") "enabled") }} 3 | {{- if (get (index .Values.apps "app-avatax") "dynamodb").enabled }} 4 | apiVersion: apps/v1 5 | kind: Deployment 6 | metadata: 7 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" .) }} 8 | labels: 9 | {{- include "saleor-apps.labels" . | nindent 4 }} 10 | app.kubernetes.io/component: dynamodb 11 | spec: 12 | replicas: 1 13 | selector: 14 | matchLabels: 15 | {{- include "saleor-apps.selectorLabels" . | nindent 6 }} 16 | app.kubernetes.io/component: dynamodb 17 | template: 18 | metadata: 19 | labels: 20 | {{- include "saleor-apps.selectorLabels" . | nindent 8 }} 21 | app.kubernetes.io/component: dynamodb 22 | spec: 23 | containers: 24 | - name: dynamodb 25 | image: "amazon/dynamodb-local:latest" 26 | imagePullPolicy: IfNotPresent 27 | args: 28 | - "-jar" 29 | - "DynamoDBLocal.jar" 30 | - "-sharedDb" 31 | - "-dbPath" 32 | - "/home/dynamodblocal/data" 33 | ports: 34 | - name: http 35 | containerPort: 8000 36 | protocol: TCP 37 | volumeMounts: 38 | - name: data 39 | mountPath: /home/dynamodblocal/data 40 | resources: 41 | {{- if (get (get (index .Values.apps "app-avatax") "dynamodb") "resources") }} 42 | {{- toYaml (get (get (index .Values.apps "app-avatax") "dynamodb") "resources") | nindent 12 }} 43 | {{- else }} 44 | limits: 45 | cpu: 200m 46 | memory: 256Mi 47 | requests: 48 | cpu: 100m 49 | memory: 128Mi 50 | {{- end }} 51 | # DynamoDB Local doesn't have a health check endpoint, so we'll use a TCP socket check 52 | readinessProbe: 53 | tcpSocket: 54 | port: 8000 55 | initialDelaySeconds: 5 56 | periodSeconds: 10 57 | livenessProbe: 58 | tcpSocket: 59 | port: 8000 60 | initialDelaySeconds: 15 61 | periodSeconds: 20 62 | volumes: 63 | - name: data 64 | emptyDir: {} 65 | --- 66 | apiVersion: batch/v1 67 | kind: Job 68 | metadata: 69 | name: {{ printf "%s-dynamodb-setup" (include "saleor-apps.fullname" .) }} 70 | labels: 71 | {{- include "saleor-apps.labels" . | nindent 4 }} 72 | app.kubernetes.io/component: dynamodb-setup 73 | annotations: 74 | "helm.sh/hook": post-install,post-upgrade 75 | "helm.sh/hook-weight": "5" 76 | "helm.sh/hook-delete-policy": hook-succeeded 77 | spec: 78 | backoffLimit: 6 79 | template: 80 | metadata: 81 | labels: 82 | {{- include "saleor-apps.selectorLabels" . | nindent 8 }} 83 | app.kubernetes.io/component: dynamodb-setup 84 | spec: 85 | restartPolicy: OnFailure 86 | containers: 87 | - name: aws-cli 88 | image: "amazon/aws-cli:latest" 89 | imagePullPolicy: IfNotPresent 90 | env: 91 | - name: AWS_ACCESS_KEY_ID 92 | valueFrom: 93 | secretKeyRef: 94 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" .) }} 95 | key: access-key-id 96 | - name: AWS_SECRET_ACCESS_KEY 97 | valueFrom: 98 | secretKeyRef: 99 | name: {{ printf "%s-dynamodb" (include "saleor-apps.fullname" .) }} 100 | key: secret-access-key 101 | - name: AWS_DEFAULT_REGION 102 | value: {{ (get (get (index .Values.apps "app-avatax") "dynamodb") "region") }} 103 | - name: DYNAMODB_LOGS_TABLE_NAME 104 | value: {{ (get (get (index .Values.apps "app-avatax") "dynamodb") "logsTableName") }} 105 | - name: DYNAMODB_ENDPOINT 106 | value: "http://{{ printf "%s-dynamodb" (include "saleor-apps.fullname" .) }}:8000" 107 | command: 108 | - /bin/sh 109 | - -c 110 | - | 111 | # Wait for DynamoDB to be ready 112 | echo "Waiting for DynamoDB to be ready..." 113 | for i in {1..30}; do 114 | if aws dynamodb list-tables --endpoint-url ${DYNAMODB_ENDPOINT} 2>/dev/null; then 115 | echo "DynamoDB is ready!" 116 | break 117 | fi 118 | echo "DynamoDB not ready yet, retrying in 2 seconds (attempt $i/30)..." 119 | sleep 2 120 | done 121 | 122 | # Create the table 123 | echo "Creating table ${DYNAMODB_LOGS_TABLE_NAME}..." 124 | aws dynamodb create-table \ 125 | --table-name ${DYNAMODB_LOGS_TABLE_NAME} \ 126 | --attribute-definitions AttributeName=PK,AttributeType=S AttributeName=SK,AttributeType=S \ 127 | --key-schema AttributeName=PK,KeyType=HASH AttributeName=SK,KeyType=RANGE \ 128 | --provisioned-throughput ReadCapacityUnits=5,WriteCapacityUnits=5 \ 129 | --endpoint-url ${DYNAMODB_ENDPOINT} || echo "Table might already exist, continuing..." 130 | 131 | # Verify the table was created 132 | echo "Verifying table creation..." 133 | aws dynamodb describe-table --table-name ${DYNAMODB_LOGS_TABLE_NAME} --endpoint-url ${DYNAMODB_ENDPOINT} 134 | 135 | echo "DynamoDB setup complete" 136 | {{- end }} 137 | {{- end }} 138 | {{- end }} 139 | -------------------------------------------------------------------------------- /charts/strapi/templates/deployment.yaml: -------------------------------------------------------------------------------- 1 | apiVersion: apps/v1 2 | kind: Deployment 3 | metadata: 4 | name: {{ include "strapi.fullname" . }} 5 | labels: 6 | {{- include "strapi.labels" . | nindent 4 }} 7 | app.kubernetes.io/role: primary 8 | spec: 9 | {{- if not .Values.autoscaling.enabled }} 10 | replicas: {{ .Values.replicaCount }} 11 | {{- end }} 12 | selector: 13 | matchLabels: 14 | {{- include "strapi.selectorLabels" . | nindent 6 }} 15 | app.kubernetes.io/role: primary 16 | strategy: 17 | type: Recreate 18 | template: 19 | metadata: 20 | {{- with .Values.podAnnotations }} 21 | annotations: 22 | {{- toYaml . | nindent 8 }} 23 | {{- end }} 24 | labels: 25 | {{- include "strapi.selectorLabels" . | nindent 8 }} 26 | app.kubernetes.io/role: primary 27 | spec: 28 | {{- with .Values.imagePullSecrets }} 29 | imagePullSecrets: 30 | {{- toYaml . | nindent 8 }} 31 | {{- end }} 32 | serviceAccountName: {{ include "strapi.serviceAccountName" . }} 33 | securityContext: 34 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 35 | containers: 36 | - name: {{ .Chart.Name }} 37 | securityContext: 38 | {{- toYaml .Values.securityContext | nindent 12 }} 39 | {{- if .Values.image.imageName }} 40 | image: "{{ lower .Values.image.imageName }}" 41 | {{- else }} 42 | image: "{{ lower .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 43 | {{- end }} 44 | imagePullPolicy: {{ .Values.image.pullPolicy }} 45 | ports: 46 | - name: http 47 | containerPort: 1337 48 | protocol: TCP 49 | livenessProbe: 50 | {{- toYaml .Values.livenessProbe | nindent 12 }} 51 | readinessProbe: 52 | {{- toYaml .Values.readinessProbe | nindent 12 }} 53 | startupProbe: 54 | {{- toYaml .Values.startupProbe | nindent 12 }} 55 | resources: 56 | {{- toYaml .Values.resources | nindent 12 }} 57 | env: 58 | - name: STRAPI_API_URL 59 | value: {{ lower .Values.strapiApiUrl | quote }} 60 | {{- range $key, $val := .Values.additionalEnvVariables }} 61 | - name: {{ $key }} 62 | value: {{ $val | quote }} 63 | {{- end }} 64 | envFrom: 65 | - secretRef: 66 | name: {{ include "strapi.fullname" . }} 67 | {{- range .Values.additionalSecretMounts }} 68 | - secretRef: 69 | name: {{ . }} 70 | {{- end }} 71 | {{- with .Values.nodeSelector }} 72 | nodeSelector: 73 | {{- toYaml . | nindent 8 }} 74 | {{- end }} 75 | {{- with .Values.affinity }} 76 | affinity: 77 | {{- toYaml . | nindent 8 }} 78 | podAntiAffinity: 79 | requiredDuringSchedulingIgnoredDuringExecution: 80 | - labelSelector: 81 | matchExpressions: 82 | - key: app.kubernetes.io/name 83 | operator: In 84 | values: 85 | - {{ include "strapi.name" . }} 86 | topologyKey: kubernetes.io/hostname 87 | {{- end }} 88 | {{- with .Values.tolerations }} 89 | tolerations: 90 | {{- toYaml . | nindent 8 }} 91 | {{- end }} 92 | --- 93 | # If we have Values.readReplica.enabled set to true, we will create a read replica deployment 94 | {{- if .Values.readReplica.enabled }} 95 | apiVersion: apps/v1 96 | apiVersion: apps/v1 97 | kind: Deployment 98 | metadata: 99 | name: {{ include "strapi.fullname" . }}-read-replica 100 | labels: 101 | {{- include "strapi.labels" . | nindent 4 }} 102 | app.kubernetes.io/role: read-replica 103 | spec: 104 | replicas: {{ .Values.readReplica.replicaCount }} 105 | selector: 106 | matchLabels: 107 | {{- include "strapi.selectorLabels" . | nindent 6 }} 108 | app.kubernetes.io/role: read-replica 109 | 110 | strategy: 111 | type: Recreate 112 | template: 113 | metadata: 114 | {{- with .Values.podAnnotations }} 115 | annotations: 116 | {{- toYaml . | nindent 8 }} 117 | {{- end }} 118 | labels: 119 | {{- include "strapi.selectorLabels" . | nindent 8 }} 120 | app.kubernetes.io/role: read-replica 121 | spec: 122 | {{- with .Values.imagePullSecrets }} 123 | imagePullSecrets: 124 | {{- toYaml . | nindent 8 }} 125 | {{- end }} 126 | serviceAccountName: {{ include "strapi.serviceAccountName" . }} 127 | securityContext: 128 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 129 | containers: 130 | - name: {{ .Chart.Name }}-read-replica 131 | securityContext: 132 | {{- toYaml .Values.securityContext | nindent 12 }} 133 | {{- if .Values.image.imageName }} 134 | image: "{{ lower .Values.image.imageName }}" 135 | {{- else }} 136 | image: "{{ lower .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" 137 | {{- end }} 138 | imagePullPolicy: {{ .Values.image.pullPolicy }} 139 | ports: 140 | - name: http 141 | containerPort: 1337 142 | protocol: TCP 143 | livenessProbe: 144 | {{- toYaml .Values.livenessProbe | nindent 12 }} 145 | readinessProbe: 146 | {{- toYaml .Values.readinessProbe | nindent 12 }} 147 | startupProbe: 148 | {{- toYaml .Values.startupProbe | nindent 12 }} 149 | resources: 150 | {{- toYaml .Values.resources | nindent 12 }} 151 | env: 152 | - name: DATABASE_URL 153 | value: {{ include "strapi.internalDatabaseUrlReplica" . | quote }} 154 | - name: STRAPI_API_URL 155 | value: {{ lower .Values.strapiApiUrl | quote }} 156 | - name: DATABASE_RUN_MIGRATIONS 157 | value: "false" 158 | {{- range $key, $val := .Values.additionalEnvVariables }} 159 | - name: {{ $key }} 160 | value: {{ $val | quote }} 161 | {{- end }} 162 | envFrom: 163 | - secretRef: 164 | name: {{ include "strapi.fullname" . }} 165 | {{- range .Values.additionalSecretMounts }} 166 | - secretRef: 167 | name: {{ . }} 168 | {{- end }} 169 | {{- with .Values.nodeSelector }} 170 | nodeSelector: 171 | {{- toYaml . | nindent 8 }} 172 | {{- end }} 173 | {{- with .Values.affinity }} 174 | affinity: 175 | {{- toYaml . | nindent 8 }} 176 | {{- end }} 177 | {{- with .Values.tolerations }} 178 | tolerations: 179 | {{- toYaml . | nindent 8 }} 180 | {{- end }} 181 | {{- end }} 182 | 183 | -------------------------------------------------------------------------------- /charts/saleor/templates/saleor_deployment.yaml: -------------------------------------------------------------------------------- 1 | {{- if .Values.api.enabled -}} 2 | apiVersion: apps/v1 3 | kind: Deployment 4 | metadata: 5 | name: {{ include "saleor.fullname" . }}-api 6 | labels: 7 | {{- include "saleor.labels" . | nindent 4 }} 8 | app.kubernetes.io/component: api 9 | spec: 10 | {{- if not .Values.api.autoscaling.enabled }} 11 | replicas: {{ .Values.api.replicaCount }} 12 | {{- end }} 13 | selector: 14 | matchLabels: 15 | {{- include "saleor.selectorLabels" . | nindent 6 }} 16 | app.kubernetes.io/component: api 17 | template: 18 | metadata: 19 | {{- with .Values.api.podAnnotations }} 20 | annotations: 21 | {{- toYaml . | nindent 8 }} 22 | {{- end }} 23 | labels: 24 | {{- include "saleor.selectorLabels" . | nindent 8 }} 25 | app.kubernetes.io/component: api 26 | spec: 27 | {{- with .Values.imagePullSecrets }} 28 | imagePullSecrets: 29 | {{- toYaml . | nindent 8 }} 30 | {{- end }} 31 | serviceAccountName: {{ include "saleor.serviceAccountName" . }} 32 | securityContext: 33 | {{- toYaml .Values.podSecurityContext | nindent 8 }} 34 | {{- if gt (int .Values.api.replicaCount) 1 }} 35 | affinity: 36 | podAntiAffinity: 37 | preferredDuringSchedulingIgnoredDuringExecution: 38 | - weight: 100 39 | podAffinityTerm: 40 | labelSelector: 41 | matchExpressions: 42 | - key: app.kubernetes.io/component 43 | operator: In 44 | values: 45 | - api 46 | topologyKey: kubernetes.io/hostname 47 | {{- end }} 48 | containers: 49 | - name: {{ .Chart.Name }}-api 50 | securityContext: 51 | {{- toYaml .Values.api.securityContext | nindent 12 }} 52 | image: "{{ .Values.global.image.repository }}:{{ .Values.global.image.tag | default .Chart.AppVersion }}" 53 | imagePullPolicy: {{ .Values.global.image.pullPolicy }} 54 | ports: 55 | - name: http 56 | containerPort: {{ .Values.api.service.port }} 57 | protocol: TCP 58 | startupProbe: 59 | httpGet: 60 | path: /health/ 61 | port: http 62 | initialDelaySeconds: 10 63 | periodSeconds: 5 64 | timeoutSeconds: 5 65 | failureThreshold: 30 66 | livenessProbe: 67 | httpGet: 68 | path: /health/ 69 | port: http 70 | initialDelaySeconds: 30 71 | periodSeconds: 10 72 | timeoutSeconds: 5 73 | successThreshold: 1 74 | failureThreshold: 3 75 | readinessProbe: 76 | httpGet: 77 | path: /health/ 78 | port: http 79 | initialDelaySeconds: 30 80 | periodSeconds: 10 81 | timeoutSeconds: 5 82 | successThreshold: 1 83 | failureThreshold: 3 84 | resources: 85 | {{- toYaml .Values.api.resources | nindent 12 }} 86 | volumeMounts: 87 | {{- if include "saleor.readReplicaEnabled" . }} 88 | - name: settings 89 | mountPath: /app/saleor/settings.py 90 | subPath: settings.py 91 | {{- end }} 92 | {{- if and .Values.storage.gcs.enabled .Values.storage.gcs.credentials.jsonKey }} 93 | - name: gcs-credentials 94 | mountPath: /var/secrets/google 95 | readOnly: true 96 | {{- end }} 97 | env: 98 | - name: PORT 99 | value: {{ .Values.api.service.port | quote }} 100 | {{- if and .Values.ingress.api.enabled .Values.ingress.api.hosts }} 101 | {{- with index .Values.ingress.api.hosts 0 }} 102 | {{- if .host }} 103 | - name: PUBLIC_URL 104 | value: {{ printf "https://%s" .host | quote }} 105 | {{- end }} 106 | {{- end }} 107 | {{- end }} 108 | - name: DATABASE_URL 109 | valueFrom: 110 | secretKeyRef: 111 | name: {{ include "saleor.fullname" . }}-secrets 112 | key: database-url 113 | - name: DATABASE_URL_REPLICA 114 | {{- if .Values.global.database.replicaUrl }} 115 | value: {{ .Values.global.database.replicaUrl | quote }} 116 | {{- else }} 117 | valueFrom: 118 | secretKeyRef: 119 | name: {{ include "saleor.fullname" . }}-secrets 120 | key: database-url-replica 121 | {{- end }} 122 | - name: DB_CONN_MAX_AGE 123 | value: {{ .Values.global.database.connMaxAge | quote }} 124 | {{- if .Values.global.jwtRsaPrivateKey }} 125 | - name: RSA_PRIVATE_KEY 126 | valueFrom: 127 | secretKeyRef: 128 | name: {{ include "saleor.fullname" . }}-secrets 129 | key: jwt-private-key 130 | {{- end }} 131 | - name: DATABASE_CONNECTION_TIMEOUT 132 | value: {{ .Values.global.database.connectionTimeout | default "5" | quote }} 133 | - name: DATABASE_MAX_CONNECTIONS 134 | value: {{ .Values.global.database.maxConnections | default "150" | quote }} 135 | - name: REDIS_URL 136 | valueFrom: 137 | secretKeyRef: 138 | name: {{ include "saleor.fullname" . }}-secrets 139 | key: redis-url 140 | - name: CELERY_BROKER_URL 141 | valueFrom: 142 | secretKeyRef: 143 | name: {{ include "saleor.fullname" . }}-secrets 144 | key: celery-redis-url 145 | - name: SECRET_KEY 146 | valueFrom: 147 | secretKeyRef: 148 | name: {{ include "saleor.fullname" . }}-secrets 149 | key: secret-key 150 | {{- with .Values.api.extraEnv }} 151 | {{- toYaml . | nindent 12 }} 152 | {{- end }} 153 | {{- include "saleor.s3Env" . | nindent 12 }} 154 | {{- include "saleor.gcsEnv" . | nindent 12 }} 155 | volumes: 156 | {{- if include "saleor.readReplicaEnabled" . }} 157 | - name: settings 158 | configMap: 159 | name: {{ include "saleor.fullname" . }}-settings 160 | {{- end }} 161 | {{- if and .Values.storage.gcs.enabled .Values.storage.gcs.credentials.jsonKey }} 162 | - name: gcs-credentials 163 | secret: 164 | secretName: {{ include "saleor.fullname" . }}-gcs-credentials 165 | {{- end }} 166 | {{- with .Values.nodeSelector }} 167 | nodeSelector: 168 | {{- toYaml . | nindent 8 }} 169 | {{- end }} 170 | {{- with .Values.tolerations }} 171 | tolerations: 172 | {{- toYaml . | nindent 8 }} 173 | {{- end }} 174 | {{- end }} 175 | -------------------------------------------------------------------------------- /charts/saleor/test-values/test-values.yaml: -------------------------------------------------------------------------------- 1 | global: 2 | jwtRsaPrivateKey: | 3 | -----BEGIN PRIVATE KEY----- 4 | MIIJQQIBADANBgkqhkiG9w0BAQEFAASCCSswggknAgEAAoICAQC9goRE4A8Rdh6L 5 | vq603wjkoLysGMBjne0ixmpYihinogM2UYti6/ffL/OpYpjzw8c2SnjloQ4NLHrX 6 | ZofY1xjF1izsbPRbcOft0GwdTO/CKHi6PgRzEM43Vv3C3srpBNHdQJ5j5KWZ8C+V 7 | e6t5j8vnwoqO2001rMIC1zHuJfMb6HOqKAYfMolXYvwLo/fVf95/ROkU/B9isndX 8 | nhemEyztIGHqAyAvo8eBQiQxumIUx3gnK6he0ItCcSB1fJp8bts8vpzIPIAgwUVn 9 | BC9trsEsQGGVg/jikLGuit6dDG8U0hF1ZFgZ9WEVSUZQe9rA7XjXM6mtNTtD8Uhf 10 | V8dSNCLHsalbxUJXVIUUU6uaH19b3mpR62N2vPM/+oJwwFxV4HvxG7iZWBvJxVeb 11 | +bF/hTgvRIpbzKpQzh/hJTFx08eJJiVb2SGnIxrCg2GuauF+lsr/pfubrClVifs7 12 | hnLEV6sPfu6exbDhBMSgGYHZP0wBuXwX9JmxFJHzk3SsxIng/LwZZVcqn/0h6bj8 13 | stw/It8B0X2vYoJ40EqXlRE5XiqTp+6LXw2wgZtc4/8PgbI56HuZ5RJMLtzkQXbU 14 | 4GI6fehxABnUdx3zaWI8/Rhl4ri6e0t0YhUKGudtxQDjL29J2t+S5QyF0ja8pIvI 15 | wPlnDMdUZv5x/jVBrIF5fF/NVXADzwIDAQABAoICAB907zy5jnbBCx/6NmjKjuDY 16 | d4j/kMvYVpkLo3Jv9di5kVvuXDs+3QW8oW8P8UChUkuGQBwpyDnSlM91cv5A8hlA 17 | zHMwQL1+99inXJLehvvNGQEdM0LgWsKf236B2d+lD6rww3nkZcKwNk3TWerTPi8J 18 | wVMmPuI2e3vaOa0Eup56ztxDSYTbMCYDxb+u54AWehnZF/GGSjVpV1sBYH6ON0pj 19 | Mi2UeD7AKmkfz/87J3W4iI7D9e5LIpqUSaWG2ePmyNiD8WVheYk2W61WagMEW4db 20 | ZndZkTIWf4/v+DTMcBHeLsy0K9WfQA62+4d3j5+vq3vZVQRtzhkgj3lYCjtwcQc4 21 | G8nQ2NOJTJ+wpPl9BbZQjAAiV2KvsbHIZSYA8h74AYblfqu34LL27/CgqHcInjnG 22 | /oTn3kAVnk3Zw0wD4QCWr2+oeBAP+o/CwpKdc2PcOGaDQTEeN3EqlbVshW1LgABD 23 | a0wqokNz5EFiYo1+5NQKSr1+m0ypUN+eButU1azMNlNIzl6PLY5q4fma/aNjDnQK 24 | E3wUkqHS0PawwDTFcHAsUafo/ETgJb97etuWfwVJ6Tm9dzQuzTkSwqvRQVcaKDmz 25 | /QLDtea1vq4SiHMzPSmDn9Ch4rFHkqGGZRy7DUzTmT2jHSWn7raePvQJQqF8S8hR 26 | HsAe42cxhLJUc5rY5+jJAoIBAQD5YoypE1zyyMcbnaAoA0tKcCl3UoI6+HcVu/ta 27 | upU0bQWMsl3/uM9SvQOb6vUHmYb6vScJ7knDaTK3TQlvHp+lKgjUb1qgPQX6+r17 28 | 5x+GIKtdsGwRo+K90PHTjTgoaj1RiWR0XYKqIOug/AWVcZ6i9dKvjrt4C/ZjE/21 29 | Q6bYlPgXMT+GTueDl8QCup9VmPtRRBi65X1WJP4oYtTjj7niG6LZLFq4l11wl5Om 30 | rD/3byuVlE8v5mYU2NwUkNoMwNfy2IexCrG5DZEYsBqt0RTPm7weHAmhiXU3z82a 31 | YXARbqG10/uPGXbTc+m+p7uUt/TrUvhxbUodJCQxPCmlYumHAoIBAQDCiWJ67DHz 32 | gTwjw/yUFRgXMxpQYOUXi1Km1sHgO+rE36Ix83uoq5SMTcVz29hkw17riNiZAeWm 33 | 8BEEi3ipcgLeHJRh7XuWWSjbmxGksnK/YJ6VRqWrSXFiirNy/EjS9oKsk4O3t8fG 34 | 1nVaV/bnp2q4tHhf3PVimNEUUGoRVVH4fzN+L7kOmA7gcXrW0DRAxov3NJuPWJZM 35 | uNrRFfKKyllEQc/zmNWRyxfENRZHwOC0VX8JqQmrDDFjOwnq+7EZqhDyFONIjFJ8 36 | 2Aj4evAbeCS6fhJVAK5u2Z72TA/BCTGyDFKc8msOVWuifDIrHudxlQ8xI+vJM14/ 37 | IfC5JOcz4AV5AoIBAGzCCr/tntqOry6e9mqczSgAdEUCaaMYGq8S1RKDTnCXnxT1 38 | 8MKGMXxOzBUiSYvv64rMFQtirS6YYTLJWPTp8QuRoloq2eYJ1uLWmO5BJGFVPAbW 39 | 2rpys36+ccglzTjq5CT7+yA4a7SQONJzNmgvLdS5yhEf+SfoZ6Jb5Ig5objQdsV+ 40 | h8ql/JdKB4R9KOGmnuuY/AP980QvS9wHBfrcAl/WV5XInyPjdy+UGyNT+W2KQQKx 41 | tDsaiqhKzuf1J/Lp4wOYZMzT8h/XB9Exc+EbzqyfqVGkPpsBHGqjqHHMTph7m/B1 42 | Kz8EBus+oNCxy7+W3iwGeizVUb4Vteb26t6inV8CggEAZDbj7ZD5loiP05jl598J 43 | /wGLX7barYtPM7VUQNB8+5h89KCKpnRlXPW/bxTk39upbUqc0g2hIaNwENhMe3XJ 44 | NmSgp+XwEZ6yppa2uxJWfHIon5u6QofeCjaLhQOj/FGTNZX0d9ML7kmSQM0p22Jq 45 | XuZRUIkCPB2fL4jRa0Z5qLrWav3opjT9DPBIqJqvIGNnvRxzup+XJcTgrG9S996P 46 | p9MDbmjgNG/cOW5joOkimKOmgvJ6kYwBcS37yPqJ3D+45QyPnVL0N24PCPpD8NKu 47 | kQfbJ8DnGyGuexDp2LaEzET+1e0n60Vj4lt6eK496kwwfE8V6xs0RO+WE7qIBDg2 48 | eQKCAQAZtziYgb6FQnlmLjEarIiPWM/O2bvhQykRhcq3b7xCYtENzgDR/Ue2gogj 49 | rwqXbV+PhFCz85w4oWCRB6BnqGyJrHBDOzVzIJc7jOTtYxZkGM6mB3hQJMNHRDSV 50 | 9wgJinGZfF55iL93QE5TeE3gvJxNGlrT7GlMFahmhqBOeGEu9hJH8Ubvt2KV5fqf 51 | B286SJCAw6FgxswiTDxwf+TlGSjQ4NxzIbH3FPGyRdgx5ovZKvu+zaOoDGIcE2FY 52 | X2TaHjGk9lT3K4jUb13PVC/DjInjlrZBHgyV5ErvekavTIvJCN7i+fCggMq0wKFB 53 | 6tKQ0JqxhYiaET1SuIz5IPB7LOLV 54 | -----END PRIVATE KEY----- 55 | 56 | secretKey: "test-secret-key-123" 57 | database: 58 | url: "postgres://postgres:postgres@localhost:5432/saleor" 59 | replicaUrl: "postgres://postgres:postgres@localhost-read:5432/saleor" 60 | 61 | api: 62 | enabled: true 63 | replicaCount: 2 64 | autoscaling: 65 | enabled: true 66 | resources: 67 | limits: 68 | memory: "1Gi" 69 | requests: 70 | cpu: "500m" 71 | memory: "512Mi" 72 | extraEnv: 73 | - name: ALLOWED_HOSTS 74 | value: "test-saleor.eu.fsn1.trwrk.xyz" 75 | - name: ALLOWED_CLIENT_HOSTS 76 | value: "test-saleor.eu.fsn1.trwrk.xyz" 77 | - name: DEBUG 78 | value: "False" 79 | - name: DEFAULT_FROM_EMAIL 80 | value: "noreply@test-saleor.eu.fsn1.trwrk.xyz" 81 | - name: EMAIL_URL 82 | value: "smtp://localhost:25" 83 | 84 | dashboard: 85 | enabled: true 86 | replicaCount: 2 87 | appsMarketplaceApiUrl: "https://marketplace-test-saleor.eu.fsn1.trwrk.xyz/marketplace.json" 88 | 89 | worker: 90 | enabled: true 91 | replicaCount: 2 92 | 93 | redis: 94 | enabled: true 95 | auth: 96 | enabled: false 97 | 98 | ingress: 99 | enabled: true 100 | className: "nginx" 101 | api: 102 | enabled: true 103 | annotations: 104 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 105 | hosts: 106 | - host: test-saleor.eu.fsn1.trwrk.xyz 107 | paths: 108 | - path: /graphql/ 109 | pathType: Prefix 110 | - path: /thumbnail/ 111 | pathType: Prefix 112 | tls: 113 | - secretName: test-saleor-api-tls 114 | hosts: 115 | - test-saleor.eu.fsn1.trwrk.xyz 116 | dashboard: 117 | enabled: true 118 | annotations: 119 | cert-manager.io/cluster-issuer: "letsencrypt-prod" 120 | hosts: 121 | - host: test-saleor.eu.fsn1.trwrk.xyz 122 | paths: 123 | - path: /dashboard/ 124 | pathType: Prefix 125 | tls: 126 | - secretName: test-saleor-dashboard-tls 127 | hosts: 128 | - test-saleor.eu.fsn1.trwrk.xyz 129 | 130 | postgresql: 131 | enabled: true 132 | architecture: replication 133 | auth: 134 | existingSecret: postgresql-credentials 135 | secretKeys: 136 | userPasswordKey: password 137 | adminPasswordKey: postgresql-password 138 | replicationPasswordKey: replication-password 139 | primary: 140 | persistence: 141 | size: 10Gi 142 | readReplicas: 143 | replicaCount: 1 144 | persistence: 145 | size: 10Gi 146 | 147 | podSecurityContext: 148 | fsGroup: 1000 149 | runAsUser: 1000 150 | runAsNonRoot: true 151 | 152 | securityContext: 153 | capabilities: 154 | drop: 155 | - ALL 156 | readOnlyRootFilesystem: false 157 | runAsNonRoot: true 158 | runAsUser: 1000 159 | 160 | podDisruptionBudget: 161 | enabled: true 162 | minAvailable: 1 163 | 164 | 165 | storage: 166 | s3: 167 | enabled: true 168 | config: 169 | customDomain: test-saleor-publ.fsn1.your-objectstorage.com 170 | mediaCustomDomain: test-saleor-publ.fsn1.your-objectstorage.com 171 | staticBucketName: test-saleor-publ 172 | mediaBucketName: test-saleor-publ 173 | mediaPrivateBucketName: test-saleor-private 174 | queryStringAuth: false 175 | queryStringExpire: 3600 176 | endpointUrl: https://fsn1.your-objectstorage.com 177 | defaultAcl: public-read 178 | credentials: {} # Credentials will be set via --set flags -------------------------------------------------------------------------------- /charts/saleor/templates/NOTES.txt: -------------------------------------------------------------------------------- 1 | Thank you for installing {{ .Chart.Name }}. 2 | 3 | Your release is named {{ .Release.Name }}. 4 | 5 | To learn more about the release, try: 6 | 7 | $ helm status {{ .Release.Name }} 8 | $ helm get all {{ .Release.Name }} 9 | 10 | {{- if .Values.ingress.enabled }} 11 | 12 | You can access the application at: 13 | {{- range .Values.ingress.api.hosts }} 14 | API: {{ if $.Values.ingress.api.tls }}https{{ else }}http{{ end }}://{{ .host }}/graphql/ 15 | Dashboard: {{ if $.Values.ingress.api.tls }}https{{ else }}http{{ end }}://{{ .host }}/dashboard/ 16 | {{- end }} 17 | 18 | {{- else }} 19 | To access the application, you need to: 20 | 21 | 1. Get the application URL by running these commands: 22 | {{- if contains "NodePort" .Values.api.service.type }} 23 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "saleor.fullname" . }}-api) 24 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 25 | echo http://$NODE_IP:$NODE_PORT 26 | {{- else if contains "LoadBalancer" .Values.api.service.type }} 27 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 28 | You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "saleor.fullname" . }}-api' 29 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "saleor.fullname" . }}-api --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 30 | echo http://$SERVICE_IP:{{ .Values.api.service.port }} 31 | {{- else if contains "ClusterIP" .Values.api.service.type }} 32 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "saleor.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=api" -o jsonpath="{.items[0].metadata.name}") 33 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 34 | echo "Visit http://127.0.0.1:8080 to use your application" 35 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 36 | {{- end }} 37 | {{- end }} 38 | 39 | IMPORTANT: Create a superuser (admin) account to access the dashboard: 40 | 41 | # Get the API pod name 42 | POD=$(kubectl get pod -l app.kubernetes.io/component=api -o jsonpath="{.items[0].metadata.name}") 43 | 44 | # Create a superuser account 45 | kubectl exec -it $POD -- python manage.py createsuperuser 46 | 47 | Follow the prompts to create your admin account with: 48 | - Email address 49 | - Password (minimum 8 characters) 50 | 51 | Use these credentials to log into the Saleor Dashboard. 52 | 53 | {{- if .Values.migrations.enabled }} 54 | Database migrations will be run automatically. 55 | To check the migration status: 56 | 57 | kubectl get job {{ include "saleor.fullname" . }}-migrations-{{ .Release.Revision }} 58 | 59 | To view migration logs: 60 | 61 | kubectl logs job/{{ include "saleor.fullname" . }}-migrations-{{ .Release.Revision }} 62 | {{- else }} 63 | NOTICE: Automatic migrations are disabled. Run them manually with: 64 | 65 | kubectl exec -it $POD -- python manage.py migrate 66 | {{- end }} 67 | 68 | {{- if .Values.api.enabled }} 69 | {{- if contains "NodePort" .Values.api.service.type }} 70 | Get the application URL by running these commands: 71 | export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "saleor.fullname" . }}-api) 72 | export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}") 73 | echo http://$NODE_IP:$NODE_PORT 74 | {{- else if contains "LoadBalancer" .Values.api.service.type }} 75 | Get the application URL by running these commands: 76 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 77 | You can watch the status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "saleor.fullname" . }}-api' 78 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "saleor.fullname" . }}-api --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 79 | echo http://$SERVICE_IP:{{ .Values.api.service.port }} 80 | {{- else if contains "ClusterIP" .Values.api.service.type }} 81 | Get the application URL by running these commands: 82 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "saleor.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=api" -o jsonpath="{.items[0].metadata.name}") 83 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 84 | echo "Visit http://127.0.0.1:8080 to use your application" 85 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT 86 | {{- end }} 87 | {{- end }} 88 | 89 | {{- if .Values.dashboard.enabled }} 90 | {{- if contains "NodePort" .Values.dashboard.service.type }} 91 | Get the dashboard URL by running these commands: 92 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "saleor.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=dashboard" -o jsonpath="{.items[0].metadata.name}") 93 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 94 | echo "Visit http://127.0.0.1:8081/dashboard/ to use your dashboard" 95 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8081:$CONTAINER_PORT 96 | {{- else if contains "LoadBalancer" .Values.dashboard.service.type }} 97 | Get the dashboard URL by running these commands: 98 | NOTE: It may take a few minutes for the LoadBalancer IP to be available. 99 | You can watch the status by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "saleor.fullname" . }}-dashboard' 100 | export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "saleor.fullname" . }}-dashboard --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}") 101 | echo http://$SERVICE_IP:{{ .Values.dashboard.service.port }}/dashboard/ 102 | {{- else if contains "ClusterIP" .Values.dashboard.service.type }} 103 | Get the dashboard URL by running these commands: 104 | export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "saleor.name" . }},app.kubernetes.io/instance={{ .Release.Name }},app.kubernetes.io/component=dashboard" -o jsonpath="{.items[0].metadata.name}") 105 | export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}") 106 | echo "Visit http://127.0.0.1:8081/dashboard/ to use your dashboard" 107 | kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8081:$CONTAINER_PORT 108 | {{- end }} 109 | {{- end }} 110 | -------------------------------------------------------------------------------- /charts/saleor-apps/values.yaml: -------------------------------------------------------------------------------- 1 | # Global settings 2 | global: 3 | # Secret key used by all apps 4 | secretKey: "" 5 | # -- External Redis URL (if not using internal Redis) 6 | redisUrl: "" 7 | # -- Log level for all Saleor apps (can be 'info', 'debug', or 'trace') 8 | appLogLevel: "info" 9 | # -- Global TLS certificate configuration 10 | tls: 11 | # -- Enable global TLS certificate 12 | enabled: false 13 | # -- Existing TLS secret name to use for all ingress resources 14 | secretName: "" 15 | 16 | # Redis configuration 17 | redis: 18 | enabled: true 19 | architecture: standalone 20 | auth: 21 | enabled: true 22 | password: "" 23 | 24 | # Common settings for all default marketplace apps 25 | common: 26 | # set the APL name that should be used. Defaults to "redis", as we natively support that. Could be upstash or file as well 27 | apl: "redis" 28 | image: 29 | registry: ghcr.io 30 | repository: trieb-work/saleor-apps 31 | pullPolicy: IfNotPresent 32 | resources: 33 | limits: 34 | cpu: 200m 35 | memory: 256Mi 36 | requests: 37 | cpu: 100m 38 | memory: 128Mi 39 | # -- Health check probes configuration 40 | probes: 41 | # -- HTTP path to use for health checks (if not specified, TCP socket check will be used) 42 | path: "" 43 | # -- Number of seconds to wait before performing first probe 44 | initialDelaySeconds: 10 45 | # -- How often to perform probe 46 | periodSeconds: 10 47 | # -- Number of seconds after which probe times out 48 | timeoutSeconds: 5 49 | # -- Minimum consecutive successes for the probe to be considered successful 50 | successThreshold: 1 51 | # -- Minimum consecutive failures for the probe to be considered failed 52 | failureThreshold: 3 53 | 54 | # Marketplace configuration 55 | # Provides a custom marketplace JSON endpoint for your Saleor apps. Access it at https://marketplace.apps.example.com/marketplace.json 56 | marketplace: 57 | # Enable or disable the marketplace service 58 | enabled: true 59 | # Hostname where the marketplace JSON will be served 60 | hostname: marketplace.apps.example.com 61 | ingress: 62 | # Enable ingress for the marketplace service 63 | enabled: true 64 | # Additional annotations for the ingress (e.g., for cert-manager) 65 | annotations: {} 66 | className: "" 67 | tls: 68 | # Enable TLS for the marketplace ingress 69 | enabled: true 70 | # TLS secret name. Leave empty to use default: -marketplace-tls 71 | secretName: "" 72 | 73 | # Individual app configurations 74 | apps: 75 | # Example of how to add your own custom app: 76 | # my-custom-app: 77 | # enabled: false 78 | # hostname: my-custom-app.apps.example.com 79 | # port: 8000 # Port that your app listens on. Optional, defaults to 3000 80 | # image: 81 | # registry: ghcr.io # Required 82 | # repository: myorg/my-custom-app # Required 83 | # tag: v1.0.0 # Required 84 | # manifestPath: /api/manifest # Optional, defaults to /api/manifest 85 | # extraEnvs: # Optional, array of extra environment variables 86 | # # Example: 87 | # # extraEnvs: 88 | # # - name: MY_CUSTOM_ENV 89 | # # value: "custom-value" 90 | # # - name: SECRET_ENV 91 | # # valueFrom: 92 | # # secretKeyRef: 93 | # # name: my-secret 94 | # # key: secret-key 95 | # ingress: 96 | # enabled: true 97 | # annotations: {} 98 | # tls: 99 | # enabled: true 100 | # secretName: "" 101 | # # Optional marketplace metadata 102 | # marketplace: 103 | # name: "My Custom App" # Required if app is enabled 104 | # logo: 105 | # source: "https://example.com/logo.svg" # Optional 106 | # color: "#000000" # Optional 107 | # description: 108 | # en: "My custom app description" # Optional 109 | # integrations: # Optional 110 | # - name: "Integration Name" 111 | # logo: 112 | # light: 113 | # source: "https://example.com/logo-light.svg" 114 | # dark: 115 | # source: "https://example.com/logo-dark.svg" 116 | # privacyUrl: "https://example.com/privacy" # Optional 117 | # supportUrl: "https://example.com/support" # Optional 118 | # repositoryUrl: "https://github.com/myorg/my-custom-app" # Optional 119 | 120 | smtp: 121 | enabled: true 122 | hostname: smtp.apps.example.com 123 | extraEnvs: [] 124 | port: 3000 125 | image: 126 | tag: "1.4.3" 127 | ingress: 128 | enabled: true 129 | annotations: {} 130 | className: "" 131 | tls: 132 | enabled: true 133 | secretName: "" # Leave empty to use default name: -smtp-tls 134 | 135 | search: 136 | enabled: true 137 | hostname: search.apps.example.com 138 | port: 3000 139 | image: 140 | tag: "1.24.3" 141 | ingress: 142 | enabled: true 143 | annotations: {} 144 | className: "" 145 | tls: 146 | enabled: true 147 | secretName: "" 148 | 149 | products-feed: 150 | enabled: true 151 | hostname: products-feed.apps.example.com 152 | port: 3000 153 | image: 154 | tag: "1.23.1" 155 | ingress: 156 | enabled: true 157 | annotations: {} 158 | className: "" 159 | tls: 160 | enabled: true 161 | secretName: "" 162 | 163 | app-avatax: 164 | enabled: false 165 | hostname: app-avatax.apps.example.com 166 | port: 3000 167 | image: 168 | tag: "1.16.2" 169 | # DynamoDB configuration for Avatax app 170 | dynamodb: 171 | # -- Enable or disable DynamoDB deployment for Avatax app 172 | enabled: false 173 | # -- DynamoDB table name for Avatax client logs 174 | logsTableName: "avatax-client-logs" 175 | # -- Time to live for logs in DynamoDB (in days) 176 | logsItemTtlInDays: 14 177 | # -- AWS region for DynamoDB 178 | region: "us-east-1" 179 | # -- AWS access key ID for DynamoDB (will be auto-generated if not provided) 180 | accessKeyId: "" 181 | # -- AWS secret access key for DynamoDB (will be auto-generated if not provided) 182 | secretAccessKey: "" 183 | # -- Resource limits for DynamoDB container 184 | resources: 185 | limits: 186 | cpu: 200m 187 | memory: 256Mi 188 | requests: 189 | cpu: 100m 190 | memory: 128Mi 191 | ingress: 192 | enabled: true 193 | annotations: {} 194 | className: "" 195 | tls: 196 | enabled: true 197 | secretName: "" 198 | 199 | cms: 200 | enabled: false 201 | hostname: cms.apps.example.com 202 | port: 3000 203 | image: 204 | tag: "2.12.3" 205 | ingress: 206 | enabled: true 207 | annotations: {} 208 | className: "" 209 | tls: 210 | enabled: true 211 | secretName: "" 212 | 213 | klaviyo: 214 | enabled: false 215 | hostname: klaviyo.apps.example.com 216 | port: 3000 217 | image: 218 | tag: "1.13.1" 219 | ingress: 220 | enabled: true 221 | annotations: {} 222 | className: "" 223 | tls: 224 | enabled: true 225 | secretName: "" 226 | -------------------------------------------------------------------------------- /charts/saleor-apps/README.md: -------------------------------------------------------------------------------- 1 | # Saleor Apps Helm Chart 2 | 3 | This Helm chart deploys the official Saleor Apps to a Kubernetes cluster. It supports multiple apps that can be enabled or disabled as needed, with a shared Redis instance for persistence (APL). 4 | 5 | ## Available Apps 6 | 7 | - **CRM Klaviyo**: Integration with Klaviyo CRM 8 | - **SMTP**: Email sending functionality 9 | - **Products Feed**: Product feed generation and management 10 | - **Search**: Provides search functionality 11 | - **Avatax**: Tax calculations via Avatax 12 | - **CMS v2**: Content Management System 13 | 14 | ## Prerequisites 15 | 16 | - Kubernetes 1.19+ 17 | - Helm 3.0+ 18 | - Ingress controller (e.g., nginx-ingress) 19 | 20 | ## Dependencies 21 | 22 | - Redis (Bitnami chart) 23 | 24 | ## Installation 25 | 26 | 1. Add the Bitnami repository for Redis dependency: 27 | ```bash 28 | helm repo add bitnami https://charts.bitnami.com/bitnami 29 | helm repo update 30 | ``` 31 | 32 | 2. Create a values file (e.g., `my-values.yaml`) to configure your deployment: 33 | ```yaml 34 | global: 35 | domain: "your-domain.com" 36 | secretKey: "your-secret-key" # Required for app security 37 | 38 | redis: 39 | auth: 40 | password: "your-redis-password" # Set a secure password 41 | 42 | # Enable the apps you need 43 | apps: 44 | crm-klaviyo: 45 | enabled: true 46 | hostname: crm-klaviyo.your-domain.com 47 | emails-and-messages: 48 | enabled: true 49 | hostname: emails.your-domain.com 50 | # ... configure other apps as needed 51 | ``` 52 | 53 | 3. Install the chart: 54 | ```bash 55 | helm install saleor-apps . -f my-values.yaml 56 | ``` 57 | 58 | ## Configuration 59 | 60 | ### Global Parameters 61 | 62 | | Parameter | Description | Default | 63 | |-----------|-------------|---------| 64 | | `global.secretKey` | Secret key for app security | `""` | 65 | | `global.redisUrl` | External Redis URL (takes precedence if set) | `""` | 66 | | `global.appLogLevel` | Log level for all Saleor apps | `"info"` | 67 | | `global.tls.enabled` | Enable global TLS certificate for all ingress resources | `false` | 68 | | `global.tls.secretName` | Existing TLS secret name to use for all ingress resources | `""` | 69 | 70 | ### Redis Configuration 71 | 72 | The chart supports both internal and external Redis configurations. You can either: 73 | 1. Use the built-in Redis (default) 74 | 2. Connect to an external Redis instance 75 | 76 | #### Using External Redis 77 | 78 | To use an external Redis instance, simply set the full Redis URL in the global configuration: 79 | 80 | ```yaml 81 | global: 82 | redisUrl: "redis://user:password@your-redis-host:6379" 83 | ``` 84 | 85 | This takes precedence over any internal Redis configuration. 86 | 87 | #### Using Internal Redis 88 | 89 | By default, the chart will deploy a Redis instance using the Bitnami Redis chart. You can configure authentication: 90 | 91 | ```yaml 92 | redis: 93 | auth: 94 | enabled: true # Enable Redis password authentication 95 | password: "your-password" # Set your Redis password 96 | ``` 97 | 98 | | Parameter | Description | Default | 99 | |-----------|-------------|---------| 100 | | `global.redisUrl` | External Redis URL (takes precedence if set) | `""` | 101 | | `redis.enabled` | Enable internal Redis deployment | `true` | 102 | | `redis.auth.enabled` | Enable Redis authentication | `true` | 103 | | `redis.auth.password` | Redis password | `""` | 104 | 105 | ### Common App Configuration 106 | 107 | | Parameter | Description | Default | 108 | |-----------|-------------|---------| 109 | | `common.image.registry` | Docker registry | `ghcr.io` | 110 | | `common.image.repository` | Docker repository | `trieb-work/saleor-apps-docker` | 111 | | `common.image.tag` | Docker image tag | `latest` | 112 | | `common.image.pullPolicy` | Image pull policy | `IfNotPresent` | 113 | 114 | ### App-Specific Configuration 115 | 116 | Each app supports the following configuration parameters: 117 | 118 | | Parameter | Description | Default | 119 | |-----------|-------------|---------| 120 | | `apps..enabled` | Enable the app | `false` | 121 | | `apps..hostname` | Hostname for the app | `.apps.example.com` | 122 | | `apps..port` | Container port | `3000` | 123 | | `apps..ingress.enabled` | Enable ingress | `true` | 124 | | `apps..ingress.annotations` | Ingress annotations | `{}` | 125 | 126 | ### Avatax DynamoDB Support 127 | 128 | The Avatax app can optionally use DynamoDB for storing client logs. When enabled, the chart will: 129 | 130 | 1. Deploy a local DynamoDB instance 131 | 2. Create a table for Avatax client logs 132 | 3. Configure the Avatax app to use this DynamoDB instance 133 | 134 | #### Configuration 135 | 136 | Enable and configure DynamoDB for Avatax in your values.yaml: 137 | 138 | ```yaml 139 | apps: 140 | app-avatax: 141 | enabled: true 142 | hostname: avatax.your-domain.com 143 | # Enable the built-in DynamoDB deployment 144 | dynamodb: 145 | enabled: true 146 | # Optional: customize these settings if needed 147 | logsTableName: "avatax-client-logs" 148 | logsItemTtlInDays: 14 149 | region: "us-east-1" 150 | # Optional: provide your own AWS credentials 151 | # accessKeyId: "your-access-key" 152 | # secretAccessKey: "your-secret-key" 153 | ``` 154 | 155 | When DynamoDB is enabled: 156 | 1. A DynamoDB local instance is deployed in your cluster 157 | 2. The required table is automatically created during installation 158 | 3. All necessary environment variables are set on the Avatax app 159 | 4. No additional configuration is needed for the app to work with DynamoDB 160 | 161 | #### Using with External AWS DynamoDB 162 | 163 | If you want to use an external AWS DynamoDB instance instead of the local one: 164 | 165 | 1. Set `apps.app-avatax.dynamodb.enabled` to `false` 166 | 2. Provide the AWS credentials and region 167 | 3. Set the appropriate environment variables in the Avatax app configuration 168 | 169 | #### AWS Credentials 170 | 171 | By default, the chart uses dummy credentials ("dynamodb-local") for local development and testing. For production environments, you should provide actual AWS credentials. 172 | 173 | ## Marketplace Service 174 | 175 | The chart includes a marketplace service that provides a custom marketplace JSON endpoint for your Saleor apps. This allows you to have a self-hosted marketplace that lists all your enabled Saleor apps with their correct manifest URLs. 176 | 177 | ### Configuration 178 | 179 | Enable and configure the marketplace in your values.yaml: 180 | 181 | ```yaml 182 | marketplace: 183 | # Enable or disable the marketplace service 184 | enabled: true 185 | # Your marketplace hostname 186 | hostname: marketplace.apps.example.com 187 | ingress: 188 | enabled: true 189 | annotations: 190 | cert-manager.io/cluster-issuer: letsencrypt-prod # Optional: for automatic SSL 191 | tls: 192 | enabled: true 193 | secretName: "" # Leave empty to use default name: -marketplace-tls 194 | ``` 195 | 196 | ### Usage with Saleor Dashboard 197 | 198 | To use your custom marketplace with Saleor Dashboard, set the `APPS_MARKETPLACE_API_URL` environment variable in your dashboard deployment: 199 | 200 | ```yaml 201 | env: 202 | - name: APPS_MARKETPLACE_API_URL 203 | value: "https://marketplace.apps.example.com/marketplace.json" 204 | ``` 205 | 206 | This will allow you to install your apps directly from the Saleor Dashboard with one click. The marketplace JSON will only include apps that are enabled in your saleor-apps deployment. 207 | 208 | ### Marketplace JSON Format 209 | 210 | The marketplace service generates a JSON file that follows the official Saleor marketplace format. For each enabled app, it includes: 211 | - App name and description 212 | - Logo and branding information 213 | - Integration details 214 | - Manifest URL pointing to your deployed app instance 215 | - Standard privacy and support URLs 216 | 217 | The manifest URLs are automatically set to match your app hostnames as configured in the chart. 218 | 219 | ## Usage 220 | 221 | 1. After installation, each enabled app will be available at its configured hostname. 222 | 2. All apps share the same Redis instance for persistence. 223 | 3. Configure your DNS to point the hostnames to your ingress controller. 224 | 225 | ## Upgrading 226 | 227 | To upgrade the release: 228 | 229 | ```bash 230 | helm upgrade saleor-apps . -f my-values.yaml 231 | ``` 232 | 233 | ## Uninstallation 234 | 235 | To uninstall the release: 236 | 237 | ```bash 238 | helm uninstall saleor-apps 239 | ``` 240 | 241 | ## Notes 242 | 243 | - The Redis password must be set before installation 244 | - Each app requires its own hostname for ingress 245 | - The secret key should be securely generated and kept private 246 | - All apps use port 3000 by default inside their containers 247 | --------------------------------------------------------------------------------