mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-17 04:55:42 +09:00
feat(deploy): add a complete fluxer helm chart (#3436)
This commit is contained in:
1 parent
fb58447ba1
commit
8e39380ee6
80 files changed
+5128
-3078
No files matched your search
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-api
|
||||
description: Fluxer HTTP API and background job workers
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,244 +0,0 @@
|
||||
{{- define "fluxer-api.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.labels" -}}
|
||||
{{ include "fluxer-api.selectorLabels" . }}
|
||||
app.kubernetes.io/component: {{ .component }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ include "fluxer-api.chart" .root }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.image" -}}
|
||||
{{- $g := .root.Values.image | default dict -}}
|
||||
{{- $i := .w.image | default dict -}}
|
||||
{{- $repo := $i.repository -}}
|
||||
{{- if not $repo -}}
|
||||
{{- $repo = printf "%s/%s" (required "image.registry is required" $g.registry) ($i.name | default "fluxer-api") -}}
|
||||
{{- end -}}
|
||||
{{- $tag := required "image.tag is required" ($i.tag | default $g.tag) -}}
|
||||
{{- if $i.digest -}}
|
||||
{{- printf "%s:%s@%s" $repo $tag $i.digest | quote -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" $repo $tag | quote -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.pick" -}}
|
||||
{{- $v := ternary (get .w .key) (get .root.Values .key) (hasKey .w .key) -}}
|
||||
{{- if $v }}
|
||||
{{- toYaml $v }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.str" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (floor .)) -}}
|
||||
{{- int64 . | toString | quote -}}
|
||||
{{- else -}}
|
||||
{{- toString . | quote -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.env" -}}
|
||||
{{- $env := dict -}}
|
||||
{{- range $k, $val := .root.Values.env | default dict }}
|
||||
{{- $_ := set $env $k $val }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := .w.env | default dict }}
|
||||
{{- $_ := set $env $k $val }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := $env }}
|
||||
{{- if not (kindIs "invalid" $val) }}
|
||||
- name: {{ $k }}
|
||||
value: {{ include "fluxer-api.str" $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .w.buildVersion }}
|
||||
- name: BUILD_VERSION
|
||||
value: {{ include "fluxer-api.str" . }}
|
||||
{{- end }}
|
||||
{{- with concat (.root.Values.extraEnv | default list) (.w.extraEnv | default list) }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.topologySpread" -}}
|
||||
{{- $tscs := ternary .w.topologySpreadConstraints .root.Values.topologySpreadConstraints (hasKey .w "topologySpreadConstraints") -}}
|
||||
{{- range $tscs }}
|
||||
{{- $c := deepCopy . }}
|
||||
{{- if not $c.labelSelector }}
|
||||
{{- $_ := set $c "labelSelector" (dict "matchLabels" (include "fluxer-api.selectorLabels" $ | fromYaml)) }}
|
||||
{{- end }}
|
||||
- {{- toYaml $c | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.pdb" -}}
|
||||
{{- with .w.pdb }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $.name }}-pdb
|
||||
namespace: {{ $.root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-api.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-api.selectorLabels" $ | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.hpa" -}}
|
||||
{{- with .w.hpa }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $.name }}
|
||||
namespace: {{ $.root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-api.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ $.name }}
|
||||
minReplicas: {{ required (printf "%s.hpa.minReplicas is required" $.name) .minReplicas }}
|
||||
maxReplicas: {{ required (printf "%s.hpa.maxReplicas is required" $.name) .maxReplicas }}
|
||||
{{- with .targetCPUUtilizationPercentage }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-api.deployment" -}}
|
||||
{{- $root := .root -}}
|
||||
{{- $v := $root.Values -}}
|
||||
{{- $w := .w -}}
|
||||
{{- $envFrom := concat ($v.envFrom | default list) ($w.envFrom | default list) -}}
|
||||
{{- $podAnnotations := merge (dict) ($w.podAnnotations | default dict) ($v.podAnnotations | default dict) -}}
|
||||
{{- $wProbes := $w.probes | default dict -}}
|
||||
{{- $gProbes := .probes | default dict -}}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ $root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-api.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not $w.hpa }}
|
||||
replicas: {{ if kindIs "invalid" $w.replicas }}1{{ else }}{{ int $w.replicas }}{{ end }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.minReadySeconds) }}
|
||||
minReadySeconds: {{ int $w.minReadySeconds }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-api.selectorLabels" . | nindent 6 }}
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "strategy") }}
|
||||
strategy:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer-api.labels" . | nindent 8 }}
|
||||
{{- with $podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "imagePullSecrets") }}
|
||||
imagePullSecrets:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "podSecurityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.terminationGracePeriodSeconds) }}
|
||||
terminationGracePeriodSeconds: {{ int $w.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "nodeSelector") }}
|
||||
nodeSelector:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "affinity") }}
|
||||
affinity:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "tolerations") }}
|
||||
tolerations:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.topologySpread" . | trim }}
|
||||
topologySpreadConstraints:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .name }}
|
||||
image: {{ include "fluxer-api.image" . }}
|
||||
imagePullPolicy: {{ ($w.image | default dict).pullPolicy | default ($v.image | default dict).pullPolicy | default "IfNotPresent" }}
|
||||
{{- with .command }}
|
||||
command:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.env" . | trim }}
|
||||
env:
|
||||
{{- . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
{{- with $w.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- range $probe := list "startup" "liveness" "readiness" }}
|
||||
{{- with hasKey $wProbes $probe | ternary (get $wProbes $probe) (get $gProbes $probe) }}
|
||||
{{ $probe }}Probe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-api.pick" (dict "root" $root "w" $w "key" "securityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,24 +0,0 @@
|
||||
{{- range $name, $w := .Values.api }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "w" $w "component" "api" "probes" ($.Values.probes | default dict) }}
|
||||
{{ include "fluxer-api.deployment" $ctx }}
|
||||
{{ include "fluxer-api.hpa" $ctx }}
|
||||
{{ include "fluxer-api.pdb" $ctx }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-api.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer-api.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,8 +0,0 @@
|
||||
{{- range $name, $w := .Values.workers }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "w" $w "component" "worker" "command" (list "node" "dist/WorkerEntrypoint.js") "probes" (dict) }}
|
||||
{{ include "fluxer-api.deployment" $ctx }}
|
||||
{{ include "fluxer-api.hpa" $ctx }}
|
||||
{{ include "fluxer-api.pdb" $ctx }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,86 +0,0 @@
|
||||
image:
|
||||
registry: ghcr.io/fluxerapp
|
||||
tag: v1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
env:
|
||||
NODE_ENV: production
|
||||
FLUXER_ENV: production
|
||||
FLUXER_PUBLIC_ORIGIN: https://web.example.com
|
||||
FLUXER_API_ENDPOINT: https://api.example.com
|
||||
FLUXER_GATEWAY_ENDPOINT: wss://gateway.example.com
|
||||
FLUXER_MEDIA_ENDPOINT: https://media.example.com
|
||||
FLUXER_ADMIN_ENDPOINT: https://admin.example.com
|
||||
FLUXER_MEDIA_PROXY_UPLOAD_RELAY_ENDPOINT: https://uploads.example.com
|
||||
FLUXER_INTERNAL_MEDIA_PROXY_ENDPOINT: http://media-proxy:8080
|
||||
FLUXER_KV_URL: redis://valkey:6379/0
|
||||
FLUXER_NATS_URL: nats://nats:4222
|
||||
FLUXER_NATS_JETSTREAM_URL: nats://nats:4222
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: fluxer-env
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
probes:
|
||||
startup:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
|
||||
topologySpreadConstraints: []
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
api:
|
||||
api:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
memory: 2560Mi
|
||||
|
||||
workers:
|
||||
worker:
|
||||
replicas: 1
|
||||
env:
|
||||
FLUXER_API_WORKER_MODE: all_lanes
|
||||
FLUXER_API_WORKER_ENABLE_CRON_SCHEDULER: "true"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
memory: 2560Mi
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-gateway
|
||||
description: A Helm chart for the Fluxer realtime gateway.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,280 +0,0 @@
|
||||
{{- define "gateway.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.labels" -}}
|
||||
{{ include "gateway.selectorLabels" . }}
|
||||
{{- with .component }}
|
||||
app.kubernetes.io/component: {{ . }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ printf "%s-%s" .root.Chart.Name .root.Chart.Version | replace "+" "_" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.headlessName" -}}
|
||||
{{ printf "%s-headless" .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.pick" -}}
|
||||
{{- $v := get .root.Values .key }}
|
||||
{{- if hasKey .w .key }}
|
||||
{{- $v = get .w .key }}
|
||||
{{- end }}
|
||||
{{- with $v }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.string" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (float64 (int64 .))) }}
|
||||
{{- int64 . | toString }}
|
||||
{{- else }}
|
||||
{{- toString . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.envList" -}}
|
||||
{{- $env := deepCopy (.root.Values.env | default dict) }}
|
||||
{{- range $k, $v := .w.env | default dict }}
|
||||
{{- if kindIs "invalid" $v }}
|
||||
{{- $_ := unset $env $k }}
|
||||
{{- else }}
|
||||
{{- $_ := set $env $k $v }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $k, $v := $env }}
|
||||
{{- if not (kindIs "invalid" $v) }}
|
||||
- name: {{ $k }}
|
||||
value: {{ include "gateway.string" $v | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with concat (.root.Values.extraEnv | default list) (.w.extraEnv | default list) }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.envFrom" -}}
|
||||
{{- with concat (.root.Values.envFrom | default list) (.w.envFrom | default list) }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.podAnnotations" -}}
|
||||
{{- with merge (deepCopy (.w.podAnnotations | default dict)) (deepCopy (.root.Values.podAnnotations | default dict)) }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.probes" -}}
|
||||
{{- $global := .root.Values.probes | default dict }}
|
||||
{{- $own := .w.probes | default dict }}
|
||||
{{- range $probe := list "startup" "liveness" "readiness" }}
|
||||
{{- $p := get $global $probe }}
|
||||
{{- if hasKey $own $probe }}
|
||||
{{- $p = get $own $probe }}
|
||||
{{- end }}
|
||||
{{- with $p }}
|
||||
{{ $probe }}Probe:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.topologySpreadConstraints" -}}
|
||||
{{- $out := list }}
|
||||
{{- range include "gateway.pick" (dict "root" .root "w" .w "key" "topologySpreadConstraints") | fromYamlArray }}
|
||||
{{- $c := deepCopy . }}
|
||||
{{- if not (hasKey $c "labelSelector") }}
|
||||
{{- $_ := set $c "labelSelector" (dict "matchLabels" (include "gateway.selectorLabels" $ | fromYaml)) }}
|
||||
{{- end }}
|
||||
{{- $out = append $out $c }}
|
||||
{{- end }}
|
||||
{{- with $out }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.image" -}}
|
||||
{{- $img := .w.image | default dict }}
|
||||
{{- $v := .root.Values.image }}
|
||||
{{- $repo := $img.repository | default (printf "%s/%s" $v.registry ($img.name | default "fluxer-gateway")) }}
|
||||
{{- $ref := printf "%s:%s" $repo ($img.tag | default $v.tag) }}
|
||||
{{- with $img.digest }}
|
||||
{{- $ref = printf "%s@%s" $ref . }}
|
||||
{{- end }}
|
||||
{{- $ref | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.replicas" -}}
|
||||
{{- if kindIs "invalid" .w.replicas }}1{{ else }}{{ .w.replicas }}{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.env" -}}
|
||||
{{- $root := .root }}
|
||||
{{- $w := .w -}}
|
||||
{{- with $w.role }}
|
||||
- name: FLUXER_GATEWAY_ROLE
|
||||
value: {{ . | quote }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.buildVersion) }}
|
||||
- name: BUILD_VERSION
|
||||
value: {{ include "gateway.string" $w.buildVersion | quote }}
|
||||
{{- end }}
|
||||
- name: POD_IP
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: status.podIP
|
||||
- name: FLUXER_ERLANG_NODE_NAME
|
||||
value: fluxer_gateway@$(POD_IP)
|
||||
- name: FLUXER_ERLANG_DIST_PORT
|
||||
value: "8081"
|
||||
- name: FLUXER_GATEWAY_CLUSTER_ENABLED
|
||||
value: "true"
|
||||
- name: FLUXER_GATEWAY_CLUSTER_DISCOVERY_DNS_NAME
|
||||
value: {{ printf "%s.%s.svc.%s" (include "gateway.headlessName" $root) $root.Release.Namespace $root.Values.clusterDomain | quote }}
|
||||
- name: FLUXER_GATEWAY_CLUSTER_DISCOVERY_NODE_BASENAME
|
||||
value: fluxer_gateway
|
||||
{{- include "gateway.envList" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.pod" -}}
|
||||
{{- $root := .root }}
|
||||
{{- $w := .w -}}
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "gateway.labels" . | nindent 4 }}
|
||||
{{- with include "gateway.podAnnotations" . }}
|
||||
annotations:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with include "gateway.pick" (dict "root" $root "w" $w "key" "affinity") }}
|
||||
affinity:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with include "gateway.pick" (dict "root" $root "w" $w "key" "imagePullSecrets") }}
|
||||
imagePullSecrets:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with include "gateway.pick" (dict "root" $root "w" $w "key" "nodeSelector") }}
|
||||
nodeSelector:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with include "gateway.pick" (dict "root" $root "w" $w "key" "tolerations") }}
|
||||
tolerations:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with include "gateway.topologySpreadConstraints" . }}
|
||||
topologySpreadConstraints:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with include "gateway.pick" (dict "root" $root "w" $w "key" "podSecurityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.terminationGracePeriodSeconds) }}
|
||||
terminationGracePeriodSeconds: {{ $w.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: gateway
|
||||
image: {{ include "gateway.image" . }}
|
||||
imagePullPolicy: {{ ($w.image | default dict).pullPolicy | default $root.Values.image.pullPolicy }}
|
||||
env:
|
||||
{{- include "gateway.env" . | trim | nindent 6 }}
|
||||
{{- with include "gateway.envFrom" . }}
|
||||
envFrom:
|
||||
{{- . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with $w.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
- name: epmd
|
||||
containerPort: 4369
|
||||
protocol: TCP
|
||||
- name: erl-dist
|
||||
containerPort: 8081
|
||||
protocol: TCP
|
||||
{{- with include "gateway.probes" . | trim }}
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with include "gateway.pick" (dict "root" $root "w" $w "key" "securityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.pdb" -}}
|
||||
{{- with .w.pdb }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $.name }}-pdb
|
||||
namespace: {{ $.root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
{{- if not (kindIs "invalid" .minAvailable) }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" .maxUnavailable) }}
|
||||
maxUnavailable: {{ .maxUnavailable }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gateway.selectorLabels" $ | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "gateway.hpa" -}}
|
||||
{{- with .w.hpa }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $.name }}
|
||||
namespace: {{ $.root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ $.name }}
|
||||
minReplicas: {{ required (printf "%s.hpa.minReplicas is required" $.name) .minReplicas }}
|
||||
maxReplicas: {{ required (printf "%s.hpa.maxReplicas is required" $.name) .maxReplicas }}
|
||||
{{- if not (kindIs "invalid" .targetCPUUtilizationPercentage) }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .targetCPUUtilizationPercentage }}
|
||||
{{- end }}
|
||||
{{- with .behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,48 +0,0 @@
|
||||
{{- range $name, $w := .Values.deployments }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "component" $w.role "w" $w }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- if not $w.hpa }}
|
||||
replicas: {{ include "gateway.replicas" $ctx }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.minReadySeconds) }}
|
||||
minReadySeconds: {{ $w.minReadySeconds }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gateway.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- with include "gateway.pick" (dict "root" $ "w" $w "key" "strategy") }}
|
||||
strategy:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
{{- include "gateway.pod" $ctx | nindent 4 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
selector:
|
||||
{{- include "gateway.selectorLabels" $ctx | nindent 4 }}
|
||||
{{- include "gateway.hpa" $ctx }}
|
||||
{{- include "gateway.pdb" $ctx }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,26 +0,0 @@
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "gateway.headlessName" . }}
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" (dict "root" . "name" "gateway" "component" "discovery") | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
- name: epmd
|
||||
port: 4369
|
||||
protocol: TCP
|
||||
targetPort: epmd
|
||||
- name: erl-dist
|
||||
port: 8081
|
||||
protocol: TCP
|
||||
targetPort: erl-dist
|
||||
selector:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
@@ -1,53 +0,0 @@
|
||||
{{- $np := .Values.networkPolicy | default dict }}
|
||||
{{- if $np.enabled }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: gateway
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" (dict "root" . "name" "gateway") | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
policyTypes:
|
||||
- Ingress
|
||||
- Egress
|
||||
egress:
|
||||
- {}
|
||||
ingress:
|
||||
{{- with $np.ingressNamespace }}
|
||||
- from:
|
||||
- namespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: {{ . }}
|
||||
ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- with $np.clients }}
|
||||
- from:
|
||||
{{- range . }}
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
- port: 4369
|
||||
protocol: TCP
|
||||
- port: 8081
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
@@ -1,29 +0,0 @@
|
||||
{{- range $name, $w := .Values.statefulsets }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "component" $w.role "w" $w }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "gateway.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ include "gateway.replicas" $ctx }}
|
||||
{{- if not (kindIs "invalid" $w.minReadySeconds) }}
|
||||
minReadySeconds: {{ $w.minReadySeconds }}
|
||||
{{- end }}
|
||||
serviceName: {{ include "gateway.headlessName" $ }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "gateway.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- with include "gateway.pick" (dict "root" $ "w" $w "key" "updateStrategy") }}
|
||||
updateStrategy:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
{{- include "gateway.pod" $ctx | nindent 4 }}
|
||||
{{- include "gateway.pdb" $ctx }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,86 +0,0 @@
|
||||
image:
|
||||
registry: ghcr.io/fluxerapp
|
||||
tag: v1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
clusterDomain: cluster.local
|
||||
|
||||
env:
|
||||
FLUXER_ENV: production
|
||||
FLUXER_GATEWAY_PORT: "8080"
|
||||
FLUXER_GATEWAY_MEDIA_PROXY_ENDPOINT: https://media.example.com
|
||||
FLUXER_INTERNAL_API_ENDPOINT: http://api:8080
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: fluxer-env
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
probes:
|
||||
startup:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
failureThreshold: 30
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
readiness:
|
||||
exec:
|
||||
command:
|
||||
- curl
|
||||
- -fsS
|
||||
- -o
|
||||
- /dev/null
|
||||
- --max-time
|
||||
- "2"
|
||||
- http://127.0.0.1:8080/_health/ready
|
||||
timeoutSeconds: 3
|
||||
|
||||
strategy: {}
|
||||
updateStrategy: {}
|
||||
|
||||
topologySpreadConstraints: []
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
ingressNamespace: ingress-nginx
|
||||
clients:
|
||||
- app.kubernetes.io/part-of: fluxer
|
||||
|
||||
deployments:
|
||||
gateway:
|
||||
role: all
|
||||
replicas: 1
|
||||
lifecycle:
|
||||
preStop:
|
||||
exec:
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- curl -fsS -o /dev/null --max-time 2 http://127.0.0.1:8080/_health/drain; sleep 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 384Mi
|
||||
limits:
|
||||
memory: 1Gi
|
||||
|
||||
statefulsets: {}
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-infra
|
||||
description: NATS and Valkey for a Fluxer installation.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,282 +0,0 @@
|
||||
{{- define "fluxer-infra.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.labels" -}}
|
||||
{{ include "fluxer-infra.selectorLabels" . }}
|
||||
app.kubernetes.io/component: {{ .component }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ include "fluxer-infra.chart" .root }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.pick" -}}
|
||||
{{- $v := get .root.Values .key }}
|
||||
{{- if hasKey .w .key }}
|
||||
{{- $v = get .w .key }}
|
||||
{{- end }}
|
||||
{{- with $v }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.string" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (float64 (int64 .))) }}
|
||||
{{- int64 . | toString }}
|
||||
{{- else }}
|
||||
{{- toString . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.envList" -}}
|
||||
{{- $env := deepCopy (.root.Values.env | default dict) }}
|
||||
{{- range $k, $v := .w.env | default dict }}
|
||||
{{- if kindIs "invalid" $v }}
|
||||
{{- $_ := unset $env $k }}
|
||||
{{- else }}
|
||||
{{- $_ := set $env $k $v }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $k, $v := $env }}
|
||||
{{- if not (kindIs "invalid" $v) }}
|
||||
- name: {{ $k }}
|
||||
value: {{ include "fluxer-infra.string" $v | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with concat (.root.Values.extraEnv | default list) (.w.extraEnv | default list) }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.envFrom" -}}
|
||||
{{- with concat (.root.Values.envFrom | default list) (.w.envFrom | default list) }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.probes" -}}
|
||||
{{- $global := .root.Values.probes | default dict }}
|
||||
{{- $own := .w.probes | default dict }}
|
||||
{{- range $probe := list "startup" "liveness" "readiness" }}
|
||||
{{- $p := get $global $probe }}
|
||||
{{- if hasKey $own $probe }}
|
||||
{{- $p = get $own $probe }}
|
||||
{{- end }}
|
||||
{{- with $p }}
|
||||
{{ $probe }}Probe:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.topologySpreadConstraints" -}}
|
||||
{{- $out := list }}
|
||||
{{- range include "fluxer-infra.pick" (dict "root" .root "w" .w "key" "topologySpreadConstraints") | fromYamlArray }}
|
||||
{{- $c := deepCopy . }}
|
||||
{{- if not (hasKey $c "labelSelector") }}
|
||||
{{- $_ := set $c "labelSelector" (dict "matchLabels" (include "fluxer-infra.selectorLabels" $ | fromYaml)) }}
|
||||
{{- end }}
|
||||
{{- $out = append $out $c }}
|
||||
{{- end }}
|
||||
{{- with $out }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.replicas" -}}
|
||||
{{- if kindIs "invalid" .w.replicas }}1{{ else }}{{ .w.replicas }}{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.image" -}}
|
||||
{{- $ref := printf "%s:%s" .repository .tag }}
|
||||
{{- with .digest }}
|
||||
{{- $ref = printf "%s@%s" $ref . }}
|
||||
{{- end }}
|
||||
{{- $ref | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.podAnnotations" -}}
|
||||
{{- with merge (deepCopy (.extra | default dict)) (deepCopy (.w.podAnnotations | default dict)) (deepCopy (.root.Values.podAnnotations | default dict)) }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.podSpec" -}}
|
||||
{{- $root := .root }}
|
||||
{{- $w := .w }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" $root "w" $w "key" "affinity") }}
|
||||
affinity:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" $root "w" $w "key" "imagePullSecrets") }}
|
||||
imagePullSecrets:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" $root "w" $w "key" "nodeSelector") }}
|
||||
nodeSelector:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" $root "w" $w "key" "tolerations") }}
|
||||
tolerations:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.topologySpreadConstraints" . }}
|
||||
topologySpreadConstraints:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" $root "w" $w "key" "podSecurityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.terminationGracePeriodSeconds) }}
|
||||
terminationGracePeriodSeconds: {{ $w.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.containerCommon" -}}
|
||||
{{- $root := .root }}
|
||||
{{- $w := .w }}
|
||||
{{- $img := $w.image | default dict }}
|
||||
image: {{ include "fluxer-infra.image" $img }}
|
||||
imagePullPolicy: {{ $img.pullPolicy }}
|
||||
{{- $env := include "fluxer-infra.envList" . | trim }}
|
||||
{{- if or .env $env }}
|
||||
env:
|
||||
{{- with .env }}
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with $env }}
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.envFrom" . }}
|
||||
envFrom:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with $w.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- include "fluxer-infra.probes" . }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" $root "w" $w "key" "securityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with concat .mounts ($w.extraVolumeMounts | default list) }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.statefulSetSpec" -}}
|
||||
{{- $w := .w }}
|
||||
{{- with include "fluxer-infra.pick" (dict "root" .root "w" $w "key" "updateStrategy") }}
|
||||
updateStrategy:
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.minReadySeconds) }}
|
||||
minReadySeconds: {{ $w.minReadySeconds }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.volumeClaim" -}}
|
||||
- metadata:
|
||||
name: data
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- with .storageClassName }}
|
||||
storageClassName: {{ . | quote }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .size }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.pdb" -}}
|
||||
{{- with .w.pdb }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $.name }}-pdb
|
||||
namespace: {{ $.root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
{{- if not (kindIs "invalid" .minAvailable) }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" .maxUnavailable) }}
|
||||
maxUnavailable: {{ .maxUnavailable }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-infra.selectorLabels" $ | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.service" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .svcName }}
|
||||
namespace: {{ .root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .headless }}
|
||||
clusterIP: None
|
||||
{{- end }}
|
||||
{{- if .publishNotReady }}
|
||||
publishNotReadyAddresses: true
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "fluxer-infra.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
{{- range .ports }}
|
||||
- name: {{ index . 0 }}
|
||||
port: {{ index . 1 }}
|
||||
targetPort: {{ index . 0 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-infra.natsConf" -}}
|
||||
{{- $w := .Values.nats -}}
|
||||
{{- with $w.config -}}
|
||||
listen: 0.0.0.0:4222
|
||||
http: 0.0.0.0:8222
|
||||
max_payload: {{ .maxPayload }}
|
||||
max_pending: {{ .maxPending }}
|
||||
max_connections: {{ .maxConnections }}
|
||||
{{- if $w.jetstream.enabled }}
|
||||
server_name: $POD_NAME
|
||||
|
||||
jetstream {
|
||||
store_dir: /data
|
||||
}
|
||||
{{- end }}
|
||||
|
||||
cluster {
|
||||
name: {{ .clusterName }}
|
||||
listen: 0.0.0.0:6222
|
||||
|
||||
routes = [
|
||||
{{- range $i := until (int (include "fluxer-infra.replicas" (dict "w" $w))) }}
|
||||
nats-route://nats-{{ $i }}.nats-headless.{{ $.Release.Namespace }}.svc.{{ $.Values.clusterDomain }}:6222
|
||||
{{- end }}
|
||||
]
|
||||
}
|
||||
{{ end }}
|
||||
{{- end }}
|
||||
@@ -1,71 +0,0 @@
|
||||
{{- with .Values.nats }}
|
||||
{{- $ctx := dict "root" $ "w" . "name" "nats" "component" "messaging" }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nats-config
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" $ctx | nindent 4 }}
|
||||
data:
|
||||
nats.conf: {{ include "fluxer-infra.natsConf" $ | toJson }}
|
||||
{{- include "fluxer-infra.pdb" $ctx }}
|
||||
{{- include "fluxer-infra.service" (merge (dict "svcName" "nats" "ports" (list (list "client" 4222))) $ctx) }}
|
||||
{{- include "fluxer-infra.service" (merge (dict "svcName" "nats-headless" "headless" true "ports" (list (list "client" 4222) (list "cluster" 6222) (list "monitor" 8222))) $ctx) }}
|
||||
{{- $mounts := list (dict "name" "config" "mountPath" "/etc/nats") }}
|
||||
{{- $env := list }}
|
||||
{{- if .jetstream.enabled }}
|
||||
{{- $mounts = append $mounts (dict "name" "data" "mountPath" "/data") }}
|
||||
{{- $env = append $env (dict "name" "POD_NAME" "valueFrom" (dict "fieldRef" (dict "fieldPath" "metadata.name"))) }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: nats
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ include "fluxer-infra.replicas" $ctx }}
|
||||
serviceName: nats-headless
|
||||
{{- with include "fluxer-infra.statefulSetSpec" $ctx | trim }}
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-infra.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" $ctx | nindent 8 }}
|
||||
{{- with include "fluxer-infra.podAnnotations" (merge (dict "extra" (dict "checksum/config" (include "fluxer-infra.natsConf" $ | sha256sum))) $ctx) | trim }}
|
||||
{{- . | nindent 6 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- include "fluxer-infra.podSpec" $ctx | trim | nindent 6 }}
|
||||
containers:
|
||||
- name: nats
|
||||
{{- include "fluxer-infra.containerCommon" (merge (dict "env" $env "mounts" $mounts) $ctx) | trim | nindent 10 }}
|
||||
args:
|
||||
- -c
|
||||
- /etc/nats/nats.conf
|
||||
ports:
|
||||
- name: client
|
||||
containerPort: 4222
|
||||
- name: cluster
|
||||
containerPort: 6222
|
||||
- name: monitor
|
||||
containerPort: 8222
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: nats-config
|
||||
{{- with .extraVolumes }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .jetstream.enabled }}
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer-infra.volumeClaim" .jetstream.storage | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,67 +0,0 @@
|
||||
{{- with .Values.valkey }}
|
||||
{{- $ctx := dict "root" $ "w" . "name" "valkey" "component" "cache" }}
|
||||
{{- include "fluxer-infra.pdb" $ctx }}
|
||||
{{- include "fluxer-infra.service" (merge (dict "svcName" "valkey" "ports" (list (list "valkey" 6379))) $ctx) }}
|
||||
{{- include "fluxer-infra.service" (merge (dict "svcName" "valkey-headless" "headless" true "publishNotReady" true "ports" (list (list "valkey" 6379))) $ctx) }}
|
||||
{{- $mounts := list }}
|
||||
{{- if .persistence.enabled }}
|
||||
{{- $mounts = append $mounts (dict "name" "data" "mountPath" "/data") }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: valkey
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: valkey-headless
|
||||
{{- with include "fluxer-infra.statefulSetSpec" $ctx | trim }}
|
||||
{{- . | nindent 2 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-infra.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer-infra.labels" $ctx | nindent 8 }}
|
||||
{{- with include "fluxer-infra.podAnnotations" $ctx | trim }}
|
||||
{{- . | nindent 6 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- include "fluxer-infra.podSpec" $ctx | trim | nindent 6 }}
|
||||
containers:
|
||||
- name: valkey
|
||||
{{- include "fluxer-infra.containerCommon" (merge (dict "env" list "mounts" $mounts) $ctx) | trim | nindent 10 }}
|
||||
command:
|
||||
- valkey-server
|
||||
{{- if .persistence.enabled }}
|
||||
- --appendonly
|
||||
- "yes"
|
||||
- --dir
|
||||
- /data
|
||||
{{- else }}
|
||||
- --save
|
||||
- ""
|
||||
- --appendonly
|
||||
- "no"
|
||||
{{- end }}
|
||||
- --maxmemory
|
||||
- {{ .maxmemory | quote }}
|
||||
- --maxmemory-policy
|
||||
- {{ .maxmemoryPolicy | quote }}
|
||||
ports:
|
||||
- name: valkey
|
||||
containerPort: 6379
|
||||
{{- with .extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if .persistence.enabled }}
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer-infra.volumeClaim" .persistence | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,108 +0,0 @@
|
||||
imagePullSecrets: []
|
||||
|
||||
clusterDomain: cluster.local
|
||||
|
||||
env: {}
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom: []
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
probes: {}
|
||||
|
||||
updateStrategy: {}
|
||||
|
||||
topologySpreadConstraints: []
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
nats:
|
||||
image:
|
||||
repository: nats
|
||||
tag: 2.14-alpine
|
||||
pullPolicy: IfNotPresent
|
||||
replicas: 3
|
||||
config:
|
||||
clusterName: nats
|
||||
maxPayload: 1MB
|
||||
maxPending: 64MB
|
||||
maxConnections: 65536
|
||||
jetstream:
|
||||
enabled: true
|
||||
storage:
|
||||
size: 10Gi
|
||||
storageClassName: ""
|
||||
podSecurityContext:
|
||||
fsGroup: 65534
|
||||
runAsGroup: 65534
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65534
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
probes:
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /healthz
|
||||
port: monitor
|
||||
initialDelaySeconds: 10
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /healthz?js-enabled-only=true
|
||||
port: monitor
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
|
||||
valkey:
|
||||
image:
|
||||
repository: valkey/valkey
|
||||
tag: 9.1-alpine
|
||||
pullPolicy: IfNotPresent
|
||||
maxmemory: 192mb
|
||||
maxmemoryPolicy: noeviction
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 1Gi
|
||||
storageClassName: ""
|
||||
podSecurityContext:
|
||||
fsGroup: 999
|
||||
runAsGroup: 999
|
||||
runAsNonRoot: true
|
||||
runAsUser: 999
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
probes:
|
||||
liveness:
|
||||
exec:
|
||||
command:
|
||||
- valkey-cli
|
||||
- ping
|
||||
initialDelaySeconds: 10
|
||||
readiness:
|
||||
exec:
|
||||
command:
|
||||
- valkey-cli
|
||||
- ping
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-ingress
|
||||
description: Ingress routing for the public Fluxer endpoints.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,27 +0,0 @@
|
||||
{{- define "fluxer-ingress.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-ingress.labels" -}}
|
||||
app.kubernetes.io/name: {{ .Chart.Name }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
helm.sh/chart: {{ include "fluxer-ingress.chart" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-ingress.annotationKey" -}}
|
||||
{{- if or (contains "/" .key) (not .prefix) -}}
|
||||
{{- .key -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s/%s" .prefix .key -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-ingress.string" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (floor .)) -}}
|
||||
{{- . | int64 | toString -}}
|
||||
{{- else -}}
|
||||
{{- . | toString -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
@@ -1,20 +0,0 @@
|
||||
{{- with .Values.clusterIssuer }}
|
||||
{{- if .enabled }}
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: ClusterIssuer
|
||||
metadata:
|
||||
name: {{ required "clusterIssuer.name is required" .name }}
|
||||
labels:
|
||||
{{- include "fluxer-ingress.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
acme:
|
||||
email: {{ required "clusterIssuer.email is required" .email | quote }}
|
||||
privateKeySecretRef:
|
||||
name: {{ required "clusterIssuer.privateKeySecretName is required" .privateKeySecretName }}
|
||||
server: {{ required "clusterIssuer.server is required" .server }}
|
||||
solvers:
|
||||
- http01:
|
||||
ingress:
|
||||
class: {{ required "clusterIssuer.solverIngressClass is required" .solverIngressClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,58 +0,0 @@
|
||||
{{- $v := .Values }}
|
||||
{{- $presets := $v.annotationPresets | default dict }}
|
||||
{{- $issuer := $v.clusterIssuer | default dict }}
|
||||
{{- range $name, $spec := ($v.ingresses | default dict) }}
|
||||
{{- if not (kindIs "invalid" $spec) }}
|
||||
{{- $ann := deepCopy ($v.commonAnnotations | default dict) }}
|
||||
{{- range ($spec.presets | default list) }}
|
||||
{{- $ann = mergeOverwrite $ann (deepCopy (required (printf "unknown annotation preset %s" .) (index $presets .))) }}
|
||||
{{- end }}
|
||||
{{- if and $spec.tls $issuer.enabled }}
|
||||
{{- $_ := set $ann "cert-manager.io/cluster-issuer" (required "clusterIssuer.name is required" $issuer.name) }}
|
||||
{{- end }}
|
||||
{{- $ann = mergeOverwrite $ann (deepCopy ($spec.annotations | default dict)) }}
|
||||
{{- range $k, $val := $ann }}
|
||||
{{- if kindIs "invalid" $val }}
|
||||
{{- $_ := unset $ann $k }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-ingress.labels" $ | nindent 4 }}
|
||||
{{- with $ann }}
|
||||
annotations:
|
||||
{{- range $k, $val := . }}
|
||||
{{ include "fluxer-ingress.annotationKey" (dict "key" $k "prefix" $v.annotationPrefix) }}: {{ include "fluxer-ingress.string" $val | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with $spec.ingressClassName | default $v.ingressClassName }}
|
||||
ingressClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- with $spec.tls }}
|
||||
tls:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range $rule := required (printf "ingress %s needs rules" $name) $spec.rules }}
|
||||
- host: {{ required (printf "ingress %s has a rule without a host" $name) $rule.host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- range $p := $rule.paths | default (list dict) }}
|
||||
{{- $p = $p | default dict }}
|
||||
- path: {{ $p.path | default "/" | quote }}
|
||||
pathType: {{ $p.pathType | default "Prefix" }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ required (printf "ingress %s host %s needs a service" $name $rule.host) ($p.service | default $rule.service) }}
|
||||
port:
|
||||
number: {{ required (printf "ingress %s host %s needs a port or servicePort" $name $rule.host) ($p.port | default $rule.port | default $v.servicePort) | int64 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,53 +0,0 @@
|
||||
ingressClassName: nginx
|
||||
annotationPrefix: nginx.ingress.kubernetes.io
|
||||
servicePort: 8080
|
||||
|
||||
commonAnnotations: {}
|
||||
|
||||
annotationPresets:
|
||||
websocket:
|
||||
proxy-read-timeout: "3600"
|
||||
proxy-send-timeout: "3600"
|
||||
stripPrefix:
|
||||
use-regex: "true"
|
||||
rewrite-target: /$2
|
||||
|
||||
ingresses:
|
||||
fluxer:
|
||||
rules:
|
||||
- host: web.example.com
|
||||
service: app-proxy
|
||||
- host: api.example.com
|
||||
service: api
|
||||
- host: admin.example.com
|
||||
service: admin
|
||||
- host: media.example.com
|
||||
service: media-proxy
|
||||
fluxer-web-api:
|
||||
presets: [stripPrefix]
|
||||
rules:
|
||||
- host: web.example.com
|
||||
service: api
|
||||
paths:
|
||||
- path: /api(/(.*))?$
|
||||
pathType: ImplementationSpecific
|
||||
fluxer-gateway:
|
||||
presets: [websocket]
|
||||
rules:
|
||||
- host: gateway.example.com
|
||||
service: gateway
|
||||
fluxer-uploads:
|
||||
annotations:
|
||||
proxy-body-size: 100m
|
||||
proxy-request-buffering: "off"
|
||||
rules:
|
||||
- host: uploads.example.com
|
||||
service: uploads
|
||||
|
||||
clusterIssuer:
|
||||
enabled: false
|
||||
name: letsencrypt
|
||||
email: ""
|
||||
server: https://acme-v02.api.letsencrypt.org/directory
|
||||
privateKeySecretName: letsencrypt-account-key
|
||||
solverIngressClass: nginx
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-media-proxy
|
||||
description: Fluxer media proxy and upload relay workloads.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,87 +0,0 @@
|
||||
{{- define "fluxer-media-proxy.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.labels" -}}
|
||||
{{ include "fluxer-media-proxy.selectorLabels" . }}
|
||||
app.kubernetes.io/component: {{ include "fluxer-media-proxy.mode" . }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ include "fluxer-media-proxy.chart" .root }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.image" -}}
|
||||
{{- $g := .root.Values.image -}}
|
||||
{{- $i := .w.image | default dict -}}
|
||||
{{- $repo := $i.repository | default (printf "%s/%s" $g.registry ($i.name | default "fluxer-media-proxy")) -}}
|
||||
{{- $tag := $i.tag | default $g.tag -}}
|
||||
{{- if $i.digest -}}
|
||||
{{- printf "%s:%s@%s" $repo $tag $i.digest | quote -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" $repo $tag | quote -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.pick" -}}
|
||||
{{- $v := ternary (get .w .key) (get .root.Values .key) (hasKey .w .key) -}}
|
||||
{{- if $v }}
|
||||
{{- toYaml $v }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.mode" -}}
|
||||
{{- $mode := required (printf "workloads.%s.mode is required" .name) .w.mode -}}
|
||||
{{- if not (has $mode (list "mp" "static" "upload" "relay")) -}}
|
||||
{{- fail (printf "workloads.%s.mode must be mp, static, upload or relay" .name) -}}
|
||||
{{- end -}}
|
||||
{{- $mode -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.envValue" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (float64 (int64 .))) -}}
|
||||
{{- int64 . | toString -}}
|
||||
{{- else -}}
|
||||
{{- toString . -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.mergeEnv" -}}
|
||||
{{- $out := dict -}}
|
||||
{{- range $layer := . -}}
|
||||
{{- range $k, $v := ($layer | default dict) -}}
|
||||
{{- if kindIs "invalid" $v -}}
|
||||
{{- $_ := unset $out $k -}}
|
||||
{{- else -}}
|
||||
{{- $_ := set $out $k $v -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $out -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.topologySpreadConstraints" -}}
|
||||
{{- $out := list -}}
|
||||
{{- range .constraints -}}
|
||||
{{- if .labelSelector -}}
|
||||
{{- $out = append $out . -}}
|
||||
{{- else -}}
|
||||
{{- $out = append $out (merge (dict "labelSelector" (dict "matchLabels" $.selector)) .) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $out -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-media-proxy.pdb" -}}
|
||||
{{- $out := dict -}}
|
||||
{{- range $k := list "minAvailable" "maxUnavailable" -}}
|
||||
{{- if and (hasKey $ $k) (not (kindIs "invalid" (index $ $k))) -}}
|
||||
{{- $_ := set $out $k (index $ $k) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $out -}}
|
||||
{{- end }}
|
||||
@@ -1,191 +0,0 @@
|
||||
{{- range $name, $w := .Values.workloads }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "w" $w }}
|
||||
{{- $mode := include "fluxer-media-proxy.mode" $ctx }}
|
||||
{{- $sel := include "fluxer-media-proxy.selectorLabels" $ctx | fromYaml }}
|
||||
{{- $env := include "fluxer-media-proxy.mergeEnv" (list $.Values.env $w.env) | fromYaml }}
|
||||
{{- $extraEnv := concat ($.Values.extraEnv | default list) ($w.extraEnv | default list) }}
|
||||
{{- $envFrom := concat ($.Values.envFrom | default list) ($w.envFrom | default list) }}
|
||||
{{- $podAnnotations := merge (dict) ($w.podAnnotations | default dict) ($.Values.podAnnotations | default dict) }}
|
||||
{{- $probes := dict }}
|
||||
{{- range $k, $v := ($.Values.probes | default dict) }}
|
||||
{{- $_ := set $probes $k $v }}
|
||||
{{- end }}
|
||||
{{- range $k, $v := ($w.probes | default dict) }}
|
||||
{{- $_ := set $probes $k $v }}
|
||||
{{- end }}
|
||||
{{- $pick := dict "root" $ "w" $w }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-media-proxy.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- if not $w.hpa }}
|
||||
replicas: {{ ternary $w.replicas 1 (hasKey $w "replicas") | int64 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.minReadySeconds) }}
|
||||
minReadySeconds: {{ $w.minReadySeconds | int64 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- toYaml $sel | nindent 6 }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "strategy") }}
|
||||
strategy:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with $podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "fluxer-media-proxy.labels" $ctx | nindent 8 }}
|
||||
spec:
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "imagePullSecrets") }}
|
||||
imagePullSecrets:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "podSecurityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.terminationGracePeriodSeconds) }}
|
||||
terminationGracePeriodSeconds: {{ $w.terminationGracePeriodSeconds | int64 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "nodeSelector") }}
|
||||
nodeSelector:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "tolerations") }}
|
||||
tolerations:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "affinity") }}
|
||||
affinity:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "topologySpreadConstraints") | fromYamlArray }}
|
||||
topologySpreadConstraints:
|
||||
{{- include "fluxer-media-proxy.topologySpreadConstraints" (dict "constraints" . "selector" $sel) | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ $name }}
|
||||
image: {{ include "fluxer-media-proxy.image" $ctx }}
|
||||
imagePullPolicy: {{ ($w.image | default dict).pullPolicy | default $.Values.image.pullPolicy }}
|
||||
env:
|
||||
{{- if not (kindIs "invalid" $w.buildVersion) }}
|
||||
- name: BUILD_VERSION
|
||||
value: {{ include "fluxer-media-proxy.envValue" $w.buildVersion | quote }}
|
||||
{{- end }}
|
||||
- name: FLUXER_MEDIA_PROXY_MODE
|
||||
value: {{ $mode | quote }}
|
||||
{{- range $k, $v := $env }}
|
||||
- name: {{ $k }}
|
||||
value: {{ include "fluxer-media-proxy.envValue" $v | quote }}
|
||||
{{- end }}
|
||||
{{- with $extraEnv }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
{{- with $w.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- range $k := list "startup" "liveness" "readiness" }}
|
||||
{{- with get $probes $k }}
|
||||
{{ $k }}Probe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-media-proxy.pick" (set (deepCopy $pick) "key" "securityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-media-proxy.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- toYaml $sel | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- with include "fluxer-media-proxy.pdb" ($w.pdb | default dict) | fromYaml }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $name }}-pdb
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-media-proxy.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- toYaml $sel | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with $w.hpa }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-media-proxy.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ $name }}
|
||||
minReplicas: {{ required (printf "workloads.%s.hpa.minReplicas is required" $name) .minReplicas | int64 }}
|
||||
maxReplicas: {{ required (printf "workloads.%s.hpa.maxReplicas is required" $name) .maxReplicas | int64 }}
|
||||
{{- if not (kindIs "invalid" .targetCPUUtilizationPercentage) }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .targetCPUUtilizationPercentage | int64 }}
|
||||
{{- end }}
|
||||
{{- with .behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,72 +0,0 @@
|
||||
image:
|
||||
registry: ghcr.io/fluxerapp
|
||||
tag: v1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
env: {}
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: fluxer-env
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
|
||||
probes:
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
|
||||
topologySpreadConstraints: []
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
workloads:
|
||||
media-proxy:
|
||||
mode: mp
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
memory: 1Gi
|
||||
|
||||
uploads:
|
||||
mode: relay
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-push
|
||||
description: Fluxer push notification delivery service
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,71 +0,0 @@
|
||||
{{- define "fluxer-push.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-push.labels" -}}
|
||||
{{ include "fluxer-push.selectorLabels" . }}
|
||||
app.kubernetes.io/component: {{ include "fluxer-push.mode" . }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ printf "%s-%s" .root.Chart.Name .root.Chart.Version | replace "+" "_" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-push.mode" -}}
|
||||
{{- $mode := .w.mode | default "delivery" -}}
|
||||
{{- if not (has $mode (list "delivery" "relay")) -}}
|
||||
{{- fail (printf "workloads.%s.mode must be delivery or relay" .name) -}}
|
||||
{{- end -}}
|
||||
{{- $mode -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-push.port" -}}
|
||||
{{- .w.port | default (ternary 8127 8126 (eq (include "fluxer-push.mode" .) "relay")) -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-push.image" -}}
|
||||
{{- $global := .root.Values.image | default dict -}}
|
||||
{{- $img := .w.image | default dict -}}
|
||||
{{- $repo := $img.repository -}}
|
||||
{{- if not $repo -}}
|
||||
{{- $repo = printf "%s/%s" (required "image.registry is required" $global.registry) ($img.name | default "fluxer-push") -}}
|
||||
{{- end -}}
|
||||
{{- $ref := printf "%s:%s" $repo (include "fluxer-push.string" (required "image.tag is required" ($img.tag | default $global.tag))) -}}
|
||||
{{- with $img.digest }}{{ $ref = printf "%s@%s" $ref . }}{{ end -}}
|
||||
{{- $ref -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-push.string" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (floor .)) -}}
|
||||
{{- . | int64 | toString -}}
|
||||
{{- else -}}
|
||||
{{- . | toString -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-push.env" -}}
|
||||
{{- $env := deepCopy (.root.Values.env | default dict) -}}
|
||||
{{- range $k, $v := (.w.env | default dict) -}}
|
||||
{{- if kindIs "invalid" $v -}}
|
||||
{{- $_ := unset $env $k -}}
|
||||
{{- else -}}
|
||||
{{- $_ := set $env $k $v -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- if not (kindIs "invalid" .w.port) -}}
|
||||
{{- $_ := set $env "FLUXER_PUSH_SERVICE_PORT" .w.port -}}
|
||||
{{- end -}}
|
||||
{{- if not (kindIs "invalid" .w.buildVersion) }}
|
||||
- name: BUILD_VERSION
|
||||
value: {{ include "fluxer-push.string" .w.buildVersion | quote }}
|
||||
{{- end }}
|
||||
{{- range $k, $v := $env }}
|
||||
{{- if not (kindIs "invalid" $v) }}
|
||||
- name: {{ $k }}
|
||||
value: {{ include "fluxer-push.string" $v | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with concat (.root.Values.extraEnv | default list) (.w.extraEnv | default list) }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,205 +0,0 @@
|
||||
{{- range $name, $w := .Values.workloads }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "w" $w }}
|
||||
{{- $mode := include "fluxer-push.mode" $ctx }}
|
||||
{{- $port := include "fluxer-push.port" $ctx | int }}
|
||||
{{- $globalProbes := $.Values.probes | default dict }}
|
||||
{{- $workloadProbes := $w.probes | default dict }}
|
||||
{{- $probes := dict }}
|
||||
{{- range $probe := list "startup" "liveness" "readiness" }}
|
||||
{{- $_ := set $probes $probe (ternary (index $workloadProbes $probe) (index $globalProbes $probe) (hasKey $workloadProbes $probe)) }}
|
||||
{{- end }}
|
||||
{{- $annotations := mergeOverwrite (deepCopy ($.Values.podAnnotations | default dict)) (deepCopy ($w.podAnnotations | default dict)) }}
|
||||
{{- $pullSecrets := ternary $w.imagePullSecrets $.Values.imagePullSecrets (hasKey $w "imagePullSecrets") }}
|
||||
{{- $podSecurityContext := ternary $w.podSecurityContext $.Values.podSecurityContext (hasKey $w "podSecurityContext") }}
|
||||
{{- $securityContext := ternary $w.securityContext $.Values.securityContext (hasKey $w "securityContext") }}
|
||||
{{- $strategy := ternary $w.strategy $.Values.strategy (hasKey $w "strategy") }}
|
||||
{{- $tsc := ternary $w.topologySpreadConstraints $.Values.topologySpreadConstraints (hasKey $w "topologySpreadConstraints") }}
|
||||
{{- $nodeSelector := ternary $w.nodeSelector $.Values.nodeSelector (hasKey $w "nodeSelector") }}
|
||||
{{- $tolerations := ternary $w.tolerations $.Values.tolerations (hasKey $w "tolerations") }}
|
||||
{{- $affinity := ternary $w.affinity $.Values.affinity (hasKey $w "affinity") }}
|
||||
{{- $envFrom := concat ($.Values.envFrom | default list) ($w.envFrom | default list) }}
|
||||
{{- $env := include "fluxer-push.env" $ctx }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-push.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- if not $w.hpa }}
|
||||
replicas: {{ ternary $w.replicas 1 (hasKey $w "replicas") | int }}
|
||||
{{- end }}
|
||||
{{- if hasKey $w "minReadySeconds" }}
|
||||
minReadySeconds: {{ $w.minReadySeconds | int }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-push.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- with $strategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with $annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "fluxer-push.labels" $ctx | nindent 8 }}
|
||||
spec:
|
||||
{{- with $pullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if hasKey $w "terminationGracePeriodSeconds" }}
|
||||
terminationGracePeriodSeconds: {{ $w.terminationGracePeriodSeconds | int }}
|
||||
{{- end }}
|
||||
{{- with $nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $tsc }}
|
||||
topologySpreadConstraints:
|
||||
{{- range . }}
|
||||
{{- $c := deepCopy . }}
|
||||
{{- if not $c.labelSelector }}
|
||||
{{- $_ := set $c "labelSelector" (dict "matchLabels" (include "fluxer-push.selectorLabels" $ctx | fromYaml)) }}
|
||||
{{- end }}
|
||||
{{- toYaml (list $c) | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ $name }}
|
||||
image: {{ include "fluxer-push.image" $ctx | quote }}
|
||||
imagePullPolicy: {{ ($w.image | default dict).pullPolicy | default ($.Values.image | default dict).pullPolicy | default "IfNotPresent" }}
|
||||
command:
|
||||
- /usr/local/bin/fluxer-push
|
||||
{{- if eq $mode "relay" }}
|
||||
args:
|
||||
- --mode
|
||||
- relay
|
||||
{{- end }}
|
||||
{{- with trim $env }}
|
||||
env:
|
||||
{{- . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ $port }}
|
||||
protocol: TCP
|
||||
{{- with $probes.startup }}
|
||||
startupProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $probes.liveness }}
|
||||
livenessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $probes.readiness }}
|
||||
readinessProbe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-push.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer-push.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ $port }}
|
||||
protocol: TCP
|
||||
targetPort: http
|
||||
{{- with $w.pdb }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $name }}-pdb
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-push.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-push.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with $w.hpa }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-push.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ $name }}
|
||||
minReplicas: {{ required (printf "workloads.%s.hpa.minReplicas is required" $name) .minReplicas | int }}
|
||||
maxReplicas: {{ required (printf "workloads.%s.hpa.maxReplicas is required" $name) .maxReplicas | int }}
|
||||
{{- if not (kindIs "invalid" .targetCPUUtilizationPercentage) }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .targetCPUUtilizationPercentage | int }}
|
||||
{{- end }}
|
||||
{{- with .behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,65 +0,0 @@
|
||||
image:
|
||||
registry: ghcr.io/fluxerapp
|
||||
tag: v1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
env: {}
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: fluxer-env
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
|
||||
probes:
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /_healthz
|
||||
port: http
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /_healthz
|
||||
port: http
|
||||
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
|
||||
topologySpreadConstraints: []
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
workloads:
|
||||
push:
|
||||
mode: delivery
|
||||
replicas: 1
|
||||
env:
|
||||
FLUXER_INTERNAL_API_ENDPOINT: http://api:8080
|
||||
FLUXER_SVC_NATS_URL: nats://nats:4222
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-svc
|
||||
description: Fluxer internal services, each a router Deployment and a shard StatefulSet
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: v1
|
||||
@@ -1,203 +0,0 @@
|
||||
{{- define "fluxer-svc.chart" -}}
|
||||
{{ printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.labels" -}}
|
||||
{{ include "fluxer-svc.selectorLabels" . }}
|
||||
app.kubernetes.io/component: {{ .mode }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ include "fluxer-svc.chart" .root }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.envValue" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (float64 (int64 .))) -}}
|
||||
{{- int64 . | toString -}}
|
||||
{{- else -}}
|
||||
{{- toString . -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.mergeEnv" -}}
|
||||
{{- $out := dict -}}
|
||||
{{- range $layer := . -}}
|
||||
{{- range $k, $v := ($layer | default dict) -}}
|
||||
{{- if kindIs "invalid" $v -}}
|
||||
{{- $_ := unset $out $k -}}
|
||||
{{- else -}}
|
||||
{{- $_ := set $out $k $v -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $out -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.topologySpreadConstraints" -}}
|
||||
{{- $out := list -}}
|
||||
{{- range .constraints -}}
|
||||
{{- if .labelSelector -}}
|
||||
{{- $out = append $out . -}}
|
||||
{{- else -}}
|
||||
{{- $out = append $out (merge (dict "labelSelector" (dict "matchLabels" $.selector)) .) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $out -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.pdb" -}}
|
||||
{{- $out := dict -}}
|
||||
{{- range $k := list "minAvailable" "maxUnavailable" -}}
|
||||
{{- if and (hasKey $ $k) (not (kindIs "invalid" (index $ $k))) -}}
|
||||
{{- $_ := set $out $k (index $ $k) -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $out -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.config" -}}
|
||||
{{- $v := .root.Values -}}
|
||||
{{- $levels := list (index $v .mode) (index .svc .mode) -}}
|
||||
{{- $c := dict "extraEnv" ($v.extraEnv | default list) "envFrom" ($v.envFrom | default list) "podAnnotations" (deepCopy ($v.podAnnotations | default dict)) "probes" (deepCopy ($v.probes | default dict)) "image" (deepCopy (.svc.image | default dict)) -}}
|
||||
{{- range $k := list "imagePullSecrets" "podSecurityContext" "securityContext" "topologySpreadConstraints" "nodeSelector" "tolerations" "affinity" (ternary "updateStrategy" "strategy" (eq .mode "shard")) -}}
|
||||
{{- $_ := set $c $k (index $v $k) -}}
|
||||
{{- end -}}
|
||||
{{- $envLayers := list $v.env -}}
|
||||
{{- range $level := $levels -}}
|
||||
{{- range $k, $x := ($level | default dict) -}}
|
||||
{{- if eq $k "env" -}}
|
||||
{{- $envLayers = append $envLayers $x -}}
|
||||
{{- else if has $k (list "podAnnotations" "image") -}}
|
||||
{{- $_ := set $c $k (mergeOverwrite (index $c $k) (deepCopy ($x | default dict))) -}}
|
||||
{{- else if has $k (list "extraEnv" "envFrom") -}}
|
||||
{{- $_ := set $c $k (concat (index $c $k) ($x | default list)) -}}
|
||||
{{- else if eq $k "probes" -}}
|
||||
{{- range $name, $p := ($x | default dict) -}}
|
||||
{{- $_ := set $c.probes $name $p -}}
|
||||
{{- end -}}
|
||||
{{- else -}}
|
||||
{{- $_ := set $c $k $x -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- $_ := set $c "env" (include "fluxer-svc.mergeEnv" $envLayers | fromYaml) -}}
|
||||
{{- toYaml $c }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.image" -}}
|
||||
{{- $g := .root.Values.image -}}
|
||||
{{- $i := .c.image -}}
|
||||
{{- $repo := $i.repository | default (printf "%s/%s" $g.registry ($i.name | default (printf "fluxer-%s" .service))) -}}
|
||||
{{- $ref := printf "%s:%s" $repo ($i.tag | default $g.tag) -}}
|
||||
{{- with $i.digest }}{{ $ref = printf "%s@%s" $ref . }}{{ end -}}
|
||||
{{- $ref -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-svc.pod" -}}
|
||||
{{- $v := .root.Values -}}
|
||||
{{- $c := .c -}}
|
||||
metadata:
|
||||
{{- with $c.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- with $c.imagePullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with $c.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $c.terminationGracePeriodSeconds) }}
|
||||
terminationGracePeriodSeconds: {{ $c.terminationGracePeriodSeconds | int64 }}
|
||||
{{- end }}
|
||||
{{- with $c.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with $c.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with $c.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- with $c.topologySpreadConstraints }}
|
||||
topologySpreadConstraints:
|
||||
{{- include "fluxer-svc.topologySpreadConstraints" (dict "constraints" . "selector" (include "fluxer-svc.selectorLabels" $ | fromYaml)) | nindent 4 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ .mode }}
|
||||
image: {{ include "fluxer-svc.image" . | quote }}
|
||||
imagePullPolicy: {{ $c.image.pullPolicy | default $v.image.pullPolicy }}
|
||||
env:
|
||||
- name: FLUXER_SVC_MODE
|
||||
value: {{ .mode | quote }}
|
||||
- name: FLUXER_SVC_NAME
|
||||
value: {{ .service | quote }}
|
||||
- name: FLUXER_SVC_SHARD_COUNT
|
||||
value: {{ .shardCount | quote }}
|
||||
- name: FLUXER_SVC_PORT
|
||||
value: {{ include "fluxer-svc.envValue" $v.port | quote }}
|
||||
{{- if not (kindIs "invalid" $c.buildVersion) }}
|
||||
- name: BUILD_VERSION
|
||||
value: {{ include "fluxer-svc.envValue" $c.buildVersion | quote }}
|
||||
{{- end }}
|
||||
{{- if eq .mode "shard" }}
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.name
|
||||
{{- end }}
|
||||
{{- range $name, $value := $c.env }}
|
||||
- name: {{ $name }}
|
||||
value: {{ include "fluxer-svc.envValue" $value | quote }}
|
||||
{{- end }}
|
||||
{{- with $c.extraEnv }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $c.envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ $v.port }}
|
||||
protocol: TCP
|
||||
{{- with $c.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- range $name := list "startup" "liveness" "readiness" }}
|
||||
{{- with index $c.probes $name }}
|
||||
{{ $name }}Probe:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $c.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $c.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $c.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $c.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,145 +0,0 @@
|
||||
{{- range $service, $svc := .Values.services }}
|
||||
{{- if not (kindIs "invalid" $svc) }}
|
||||
{{- $svc = $svc | default dict }}
|
||||
{{- $rc := fromYaml (include "fluxer-svc.config" (dict "root" $ "svc" $svc "mode" "router")) }}
|
||||
{{- $sc := fromYaml (include "fluxer-svc.config" (dict "root" $ "svc" $svc "mode" "shard")) }}
|
||||
{{- $routerReplicas := ternary $rc.replicas 1 (hasKey $rc "replicas") | int64 }}
|
||||
{{- $shardCount := ternary $sc.replicas 1 (hasKey $sc "replicas") | int64 }}
|
||||
{{- if lt $shardCount 1 }}
|
||||
{{- fail (printf "services.%s shard replicas must be at least 1" $service) }}
|
||||
{{- end }}
|
||||
{{- $router := dict "root" $ "service" $service "svc" $svc "mode" "router" "name" $service "c" $rc "shardCount" (toString $shardCount) }}
|
||||
{{- $shard := dict "root" $ "service" $service "svc" $svc "mode" "shard" "name" (printf "%s-shard" $service) "c" $sc "shardCount" (toString $shardCount) }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ $service }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" $router | nindent 4 }}
|
||||
spec:
|
||||
{{- if not $rc.hpa }}
|
||||
replicas: {{ $routerReplicas }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $rc.minReadySeconds) }}
|
||||
minReadySeconds: {{ $rc.minReadySeconds | int64 }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-svc.selectorLabels" $router | nindent 6 }}
|
||||
{{- with $rc.strategy }}
|
||||
strategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
{{- include "fluxer-svc.pod" $router | nindent 4 }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ $service }}-shard
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" $shard | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ $shardCount }}
|
||||
{{- if not (kindIs "invalid" $sc.minReadySeconds) }}
|
||||
minReadySeconds: {{ $sc.minReadySeconds | int64 }}
|
||||
{{- end }}
|
||||
podManagementPolicy: Parallel
|
||||
serviceName: {{ $service }}-shard-headless
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-svc.selectorLabels" $shard | nindent 6 }}
|
||||
{{- with $sc.updateStrategy }}
|
||||
updateStrategy:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
{{- include "fluxer-svc.pod" $shard | nindent 4 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $service }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" $router | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer-svc.selectorLabels" $router | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ $.Values.port }}
|
||||
targetPort: {{ $.Values.port }}
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $service }}-shard-headless
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" $shard | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
clusterIP: None
|
||||
publishNotReadyAddresses: true
|
||||
selector:
|
||||
{{- include "fluxer-svc.selectorLabels" $shard | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ $.Values.port }}
|
||||
targetPort: {{ $.Values.port }}
|
||||
protocol: TCP
|
||||
{{- with $rc.hpa }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $service }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" $router | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ $service }}
|
||||
minReplicas: {{ required (printf "services.%s router hpa.minReplicas is required" $service) .minReplicas | int64 }}
|
||||
maxReplicas: {{ required (printf "services.%s router hpa.maxReplicas is required" $service) .maxReplicas | int64 }}
|
||||
{{- if not (kindIs "invalid" .targetCPUUtilizationPercentage) }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .targetCPUUtilizationPercentage | int64 }}
|
||||
{{- end }}
|
||||
{{- with .behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $ctx := list $router $shard }}
|
||||
{{- with include "fluxer-svc.pdb" ($ctx.c.pdb | default dict) | fromYaml }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $ctx.name }}-pdb
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-svc.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-svc.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,89 +0,0 @@
|
||||
image:
|
||||
registry: ghcr.io/fluxerapp
|
||||
tag: v1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
env:
|
||||
FLUXER_SVC_NATS_URL: nats://nats:4222
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: fluxer-env
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
probes:
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /_healthz
|
||||
port: http
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxSurge: 25%
|
||||
maxUnavailable: 25%
|
||||
|
||||
updateStrategy:
|
||||
type: RollingUpdate
|
||||
|
||||
topologySpreadConstraints: []
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
port: 8090
|
||||
|
||||
router:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 192Mi
|
||||
|
||||
shard:
|
||||
replicas: 2
|
||||
probes:
|
||||
startup:
|
||||
httpGet:
|
||||
path: /_healthz
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 96Mi
|
||||
limits:
|
||||
memory: 384Mi
|
||||
|
||||
services:
|
||||
gifs:
|
||||
shard:
|
||||
env:
|
||||
FLUXER_MEDIA_PROXY_PUBLIC_ENDPOINT: https://media.example.com
|
||||
messages: {}
|
||||
snowflakes: {}
|
||||
unfurl:
|
||||
shard:
|
||||
env:
|
||||
FLUXER_MEDIA_PROXY_ENDPOINT: http://media-proxy:8080
|
||||
users: {}
|
||||
@@ -1,6 +0,0 @@
|
||||
apiVersion: v2
|
||||
name: fluxer-web
|
||||
description: Fluxer web app proxy and admin dashboard.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
@@ -1,80 +0,0 @@
|
||||
{{- define "fluxer-web.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.labels" -}}
|
||||
{{ include "fluxer-web.selectorLabels" . }}
|
||||
app.kubernetes.io/component: web
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
helm.sh/chart: {{ include "fluxer-web.chart" .root }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.image" -}}
|
||||
{{- $g := .root.Values.image | default dict -}}
|
||||
{{- $i := .w.image | default dict -}}
|
||||
{{- $repo := $i.repository -}}
|
||||
{{- if not $repo -}}
|
||||
{{- $repo = printf "%s/%s" (required "image.registry is required" $g.registry) ($i.name | default (printf "fluxer-%s" .name)) -}}
|
||||
{{- end -}}
|
||||
{{- $tag := required "image.tag is required" ($i.tag | default $g.tag) -}}
|
||||
{{- if $i.digest -}}
|
||||
{{- printf "%s:%s@%s" $repo $tag $i.digest | quote -}}
|
||||
{{- else -}}
|
||||
{{- printf "%s:%s" $repo $tag | quote -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.pick" -}}
|
||||
{{- $v := ternary (get .w .key) (get .root.Values .key) (hasKey .w .key) -}}
|
||||
{{- if $v }}
|
||||
{{- toYaml $v }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.str" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (floor .)) -}}
|
||||
{{- int64 . | toString | quote -}}
|
||||
{{- else -}}
|
||||
{{- toString . | quote -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.env" -}}
|
||||
{{- $env := dict -}}
|
||||
{{- range $k, $val := .root.Values.env | default dict }}
|
||||
{{- $_ := set $env $k $val }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := .w.env | default dict }}
|
||||
{{- $_ := set $env $k $val }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := $env }}
|
||||
{{- if not (kindIs "invalid" $val) }}
|
||||
- name: {{ $k }}
|
||||
value: {{ include "fluxer-web.str" $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .w.buildVersion }}
|
||||
- name: BUILD_VERSION
|
||||
value: {{ include "fluxer-web.str" . }}
|
||||
{{- end }}
|
||||
{{- with concat (.root.Values.extraEnv | default list) (.w.extraEnv | default list) }}
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer-web.topologySpread" -}}
|
||||
{{- $tscs := ternary .w.topologySpreadConstraints .root.Values.topologySpreadConstraints (hasKey .w "topologySpreadConstraints") -}}
|
||||
{{- range $tscs }}
|
||||
{{- $c := deepCopy . }}
|
||||
{{- if not $c.labelSelector }}
|
||||
{{- $_ := set $c "labelSelector" (dict "matchLabels" (include "fluxer-web.selectorLabels" $ | fromYaml)) }}
|
||||
{{- end }}
|
||||
- {{- toYaml $c | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,172 +0,0 @@
|
||||
{{- $v := .Values }}
|
||||
{{- range $name, $w := .Values.workloads }}
|
||||
{{- if not (kindIs "invalid" $w) }}
|
||||
{{- $ctx := dict "root" $ "name" $name "w" $w }}
|
||||
{{- $envFrom := concat ($v.envFrom | default list) ($w.envFrom | default list) }}
|
||||
{{- $podAnnotations := merge (dict) ($w.podAnnotations | default dict) ($v.podAnnotations | default dict) }}
|
||||
{{- $wProbes := $w.probes | default dict }}
|
||||
{{- $gProbes := $v.probes | default dict }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-web.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- if not $w.hpa }}
|
||||
replicas: {{ if kindIs "invalid" $w.replicas }}1{{ else }}{{ int $w.replicas }}{{ end }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.minReadySeconds) }}
|
||||
minReadySeconds: {{ int $w.minReadySeconds }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-web.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "strategy") }}
|
||||
strategy:
|
||||
{{- . | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer-web.labels" $ctx | nindent 8 }}
|
||||
{{- with $podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "imagePullSecrets") }}
|
||||
imagePullSecrets:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "podSecurityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" $w.terminationGracePeriodSeconds) }}
|
||||
terminationGracePeriodSeconds: {{ int $w.terminationGracePeriodSeconds }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "nodeSelector") }}
|
||||
nodeSelector:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "affinity") }}
|
||||
affinity:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "tolerations") }}
|
||||
tolerations:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-web.topologySpread" $ctx | trim }}
|
||||
topologySpreadConstraints:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: {{ $name }}
|
||||
image: {{ include "fluxer-web.image" $ctx }}
|
||||
imagePullPolicy: {{ ($w.image | default dict).pullPolicy | default ($v.image | default dict).pullPolicy | default "IfNotPresent" }}
|
||||
{{- with include "fluxer-web.env" $ctx | trim }}
|
||||
env:
|
||||
{{- . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $envFrom }}
|
||||
envFrom:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
{{- with $w.lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- range $probe := list "startup" "liveness" "readiness" }}
|
||||
{{- with hasKey $wProbes $probe | ternary (get $wProbes $probe) (get $gProbes $probe) }}
|
||||
{{ $probe }}Probe:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer-web.pick" (dict "root" $ "w" $w "key" "securityContext") }}
|
||||
securityContext:
|
||||
{{- . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumeMounts }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- with $w.extraVolumes }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-web.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer-web.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- with $w.hpa }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $name }}
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-web.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
name: {{ $name }}
|
||||
minReplicas: {{ required (printf "%s.hpa.minReplicas is required" $name) .minReplicas }}
|
||||
maxReplicas: {{ required (printf "%s.hpa.maxReplicas is required" $name) .maxReplicas }}
|
||||
{{- with .targetCPUUtilizationPercentage }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ . }}
|
||||
{{- end }}
|
||||
{{- with .behavior }}
|
||||
behavior:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $w.pdb }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $name }}-pdb
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer-web.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer-web.selectorLabels" $ctx | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -1,78 +0,0 @@
|
||||
image:
|
||||
registry: ghcr.io/fluxerapp
|
||||
tag: v1
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
imagePullSecrets: []
|
||||
|
||||
env: {}
|
||||
|
||||
extraEnv: []
|
||||
|
||||
envFrom:
|
||||
- secretRef:
|
||||
name: fluxer-env
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
podSecurityContext:
|
||||
runAsNonRoot: true
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
|
||||
probes:
|
||||
startup:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
periodSeconds: 10
|
||||
failureThreshold: 30
|
||||
liveness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
readiness:
|
||||
httpGet:
|
||||
path: /_health
|
||||
port: http
|
||||
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
|
||||
topologySpreadConstraints: []
|
||||
|
||||
nodeSelector: {}
|
||||
|
||||
tolerations: []
|
||||
|
||||
affinity: {}
|
||||
|
||||
workloads:
|
||||
admin:
|
||||
image:
|
||||
name: fluxer-admin
|
||||
replicas: 1
|
||||
env:
|
||||
FLUXER_API_ENDPOINT: https://api.example.com
|
||||
FLUXER_ADMIN_ENDPOINT: https://admin.example.com
|
||||
FLUXER_MEDIA_ENDPOINT: https://media.example.com
|
||||
FLUXER_APP_ENDPOINT: https://web.example.com
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 96Mi
|
||||
limits:
|
||||
memory: 384Mi
|
||||
app-proxy:
|
||||
image:
|
||||
name: fluxer-app-proxy-self-hosted
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 96Mi
|
||||
limits:
|
||||
memory: 384Mi
|
||||
@@ -0,0 +1,11 @@
|
||||
.DS_Store
|
||||
.git/
|
||||
.gitignore
|
||||
*.swp
|
||||
*.bak
|
||||
*.tmp
|
||||
*.orig
|
||||
*~
|
||||
.idea/
|
||||
.vscode/
|
||||
ci/
|
||||
@@ -0,0 +1,13 @@
|
||||
apiVersion: v2
|
||||
name: fluxer
|
||||
description: A complete Fluxer instance on Kubernetes, at parity with the self-hosted Docker Compose stack.
|
||||
type: application
|
||||
version: 0.1.0
|
||||
appVersion: "v1"
|
||||
kubeVersion: ">=1.29.0-0"
|
||||
home: https://docs.fluxer.app/operator/kubernetes/
|
||||
sources:
|
||||
- https://github.com/fluxerapp/fluxer/tree/main/deploy/helm/fluxer
|
||||
keywords:
|
||||
- fluxer
|
||||
- chat
|
||||
@@ -0,0 +1 @@
|
||||
domain: chat.example.test
|
||||
@@ -0,0 +1,3 @@
|
||||
domain: chat.example.test
|
||||
secrets:
|
||||
existingSecret: fluxer-ci-secret
|
||||
@@ -0,0 +1,38 @@
|
||||
domain: chat.example.test
|
||||
postgres:
|
||||
enabled: false
|
||||
external:
|
||||
host: db.example.test
|
||||
ssl: "true"
|
||||
valkey:
|
||||
enabled: false
|
||||
nats:
|
||||
enabled: false
|
||||
external:
|
||||
url: nats://mq.example.test:4222
|
||||
meilisearch:
|
||||
enabled: false
|
||||
external:
|
||||
url: https://search.example.test
|
||||
seaweedfs:
|
||||
enabled: false
|
||||
s3:
|
||||
endpoint: https://s3.example.test
|
||||
publicEndpoint: https://cdn.example.test
|
||||
region: eu-central-1
|
||||
forcePathStyle: false
|
||||
livekit:
|
||||
enabled: false
|
||||
external:
|
||||
url: http://livekit.voice.svc:7880
|
||||
publicUrl: wss://livekit.example.test
|
||||
secrets:
|
||||
values:
|
||||
FLUXER_POSTGRES_PASSWORD: ci-postgres-password
|
||||
FLUXER_SEARCH_API_KEY: ci-search-key
|
||||
FLUXER_S3_SECRET_ACCESS_KEY: ci-s3-secret
|
||||
FLUXER_NATS_AUTH_TOKEN: ci-nats-token
|
||||
FLUXER_LIVEKIT_API_KEY: ci-livekit-key
|
||||
FLUXER_LIVEKIT_API_SECRET: ci-livekit-secret-of-at-least-32-characters
|
||||
extra:
|
||||
FLUXER_KV_URL: redis://:[email protected]:6379/0
|
||||
@@ -0,0 +1,11 @@
|
||||
domain: chat.example.test
|
||||
edge:
|
||||
expose: gateway
|
||||
gateway:
|
||||
parentRefs:
|
||||
- name: shared
|
||||
namespace: gateway-system
|
||||
timeouts:
|
||||
request: 0s
|
||||
livekit:
|
||||
expose: nodePort
|
||||
@@ -0,0 +1,10 @@
|
||||
domain: chat.example.test
|
||||
email: [email protected]
|
||||
edge:
|
||||
expose: loadBalancer
|
||||
loadBalancer:
|
||||
http3: true
|
||||
livekit:
|
||||
expose: loadBalancer
|
||||
nodeIP: 203.0.113.10
|
||||
loadBalancerIP: 203.0.113.10
|
||||
@@ -0,0 +1,15 @@
|
||||
domain: chat.example.test
|
||||
networkPolicy:
|
||||
enabled: false
|
||||
livekit:
|
||||
enabled: false
|
||||
nats:
|
||||
replicas: 3
|
||||
initImage:
|
||||
repository: registry.example.test/busybox
|
||||
digest: sha256:0000000000000000000000000000000000000000000000000000000000000000
|
||||
postgres:
|
||||
image:
|
||||
repository: registry.example.test/postgres
|
||||
tag: "16"
|
||||
runAsUser: 999
|
||||
@@ -0,0 +1,13 @@
|
||||
domain: chat.example.test
|
||||
networkPolicy:
|
||||
ingressNamespaceSelector:
|
||||
matchLabels:
|
||||
kubernetes.io/metadata.name: ingress-nginx
|
||||
edge:
|
||||
ingress:
|
||||
className: nginx
|
||||
livekit:
|
||||
nodeSelector:
|
||||
kubernetes.io/hostname: voice-1
|
||||
nodeCIDRs:
|
||||
- 10.0.0.12/32
|
||||
@@ -0,0 +1,64 @@
|
||||
{
|
||||
servers {
|
||||
trusted_proxies static {$FLUXER_EDGE_TRUSTED_PROXIES:private_ranges}
|
||||
trusted_proxies_strict
|
||||
}
|
||||
{$FLUXER_EDGE_GLOBAL_OPTIONS}
|
||||
}
|
||||
|
||||
{$FLUXER_EDGE_SITE_ADDRESS} {
|
||||
encode {$FLUXER_EDGE_ENCODE:zstd gzip}
|
||||
|
||||
handle /_health {
|
||||
respond "OK" 200
|
||||
}
|
||||
|
||||
handle_path /api/* {
|
||||
reverse_proxy api:8080
|
||||
}
|
||||
|
||||
handle /gateway {
|
||||
rewrite * /
|
||||
reverse_proxy gateway:8080
|
||||
}
|
||||
|
||||
handle_path /gateway/* {
|
||||
reverse_proxy gateway:8080
|
||||
}
|
||||
|
||||
handle_path /media/* {
|
||||
reverse_proxy media-proxy:8080
|
||||
}
|
||||
|
||||
handle_path /livekit/* {
|
||||
reverse_proxy livekit:7880
|
||||
}
|
||||
|
||||
handle {$FLUXER_ADMIN_BASE_PATH:/admin} {
|
||||
rewrite * /
|
||||
reverse_proxy admin:8080
|
||||
}
|
||||
|
||||
handle_path {$FLUXER_ADMIN_BASE_PATH:/admin}/* {
|
||||
reverse_proxy admin:8080
|
||||
}
|
||||
|
||||
@staticAssets path /web/* /emoji/* /libs/* /avatars/* /badges/* /desktop/*
|
||||
handle @staticAssets {
|
||||
reverse_proxy static-proxy:8080
|
||||
}
|
||||
|
||||
handle /.well-known/fluxer {
|
||||
reverse_proxy api:8080
|
||||
}
|
||||
|
||||
handle {
|
||||
reverse_proxy app-proxy:8080
|
||||
}
|
||||
}
|
||||
|
||||
:8088 {
|
||||
handle /.well-known/fluxer {
|
||||
reverse_proxy api:8080
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
trap 'exit 0' TERM INT
|
||||
buckets="$FLUXER_S3_BUCKET_CDN $FLUXER_S3_BUCKET_UPLOADS $FLUXER_S3_BUCKET_REPORTS $FLUXER_S3_BUCKET_HARVESTS"
|
||||
missing="$buckets"
|
||||
for attempt in $(seq 1 "$FLUXER_SEAWEEDFS_INIT_ATTEMPTS"); do
|
||||
if ! nc -z 127.0.0.1 9333 2>/dev/null; then
|
||||
sleep 2
|
||||
continue
|
||||
fi
|
||||
listed=$(echo "s3.bucket.list" | timeout 10 weed shell -master=127.0.0.1:9333 2>&1)
|
||||
missing=""
|
||||
for b in $buckets; do
|
||||
echo "$listed" | grep -q "^[[:space:]]*$b[[:space:]]" || missing="${missing:+$missing }$b"
|
||||
done
|
||||
if [ -z "$missing" ]; then
|
||||
if ! echo "s3.configure -user=fluxer -access_key=$FLUXER_S3_ACCESS_KEY -secret_key=$FLUXER_S3_SECRET_KEY -actions=Admin,Read,Write,List,Tagging -apply" | timeout 10 weed shell -master=127.0.0.1:9333 >/dev/null 2>&1; then
|
||||
echo "seaweedfs-init could not configure the S3 identity" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "buckets ready"
|
||||
touch /tmp/fluxer-buckets-ready
|
||||
while :; do
|
||||
sleep 86400 &
|
||||
wait $!
|
||||
done
|
||||
fi
|
||||
for b in $missing; do
|
||||
echo "s3.bucket.create -name $b" | timeout 10 weed shell -master=127.0.0.1:9333 >/dev/null 2>&1
|
||||
done
|
||||
sleep 2
|
||||
done
|
||||
echo "seaweedfs-init could not verify buckets: $missing" >&2
|
||||
exit 1
|
||||
@@ -0,0 +1,68 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- $v := .Values }}
|
||||
{{- $o := include "fluxer.origin" . }}
|
||||
Fluxer is installing in namespace {{ .Release.Namespace }}. Run one release per namespace.
|
||||
|
||||
Open {{ $o }} once every pod is ready:
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} get pods
|
||||
|
||||
The admin panel is at {{ $o }}{{ $v.adminBasePath }}.
|
||||
|
||||
Register the first account and finish the setup wizard in the same sitting.
|
||||
Until the wizard is finished, any account that registers can change the
|
||||
instance configuration.
|
||||
{{- if eq $v.edge.expose "loadBalancer" }}
|
||||
|
||||
Point DNS for {{ $v.domain }} at the external address of the edge-public Service:
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} get service edge-public
|
||||
{{- else if eq $v.edge.expose "none" }}
|
||||
|
||||
Nothing exposes the instance yet. Send your proxy or tunnel to the Service edge
|
||||
on port 8080, with the Host header {{ $v.domain }}.
|
||||
{{- else }}
|
||||
|
||||
Point DNS for {{ $v.domain }} at your {{ ternary "ingress controller" "gateway" (eq $v.edge.expose "ingress") }}. Its Service needs
|
||||
externalTrafficPolicy Local or the PROXY protocol, or every client shares one IP
|
||||
and registration hits its per-IP limit.
|
||||
{{- end }}
|
||||
{{- if $v.livekit.external.url }}
|
||||
|
||||
Voice uses your LiveKit server at {{ $v.livekit.external.publicUrl }}. Point its webhook at
|
||||
{{ $o }}/api/webhooks/livekit, signed with the key in FLUXER_LIVEKIT_API_KEY.
|
||||
{{- end }}
|
||||
{{- if $v.livekit.enabled }}
|
||||
|
||||
Voice media does not pass through the edge. Open these ports to the internet:
|
||||
{{- if eq $v.livekit.expose "hostNetwork" }}
|
||||
{{ $v.livekit.tcpPort }}/tcp and {{ $v.livekit.udpPort }}/udp on the node that runs the livekit pod.
|
||||
hostNetwork needs a namespace that allows privileged pods. Keep 7880 closed.
|
||||
{{- else if eq $v.livekit.expose "nodePort" }}
|
||||
{{ $v.livekit.nodePorts.tcp }}/tcp and {{ $v.livekit.nodePorts.udp }}/udp on the node that runs the livekit pod.
|
||||
{{- else }}
|
||||
{{ $v.livekit.tcpPort }}/tcp and {{ $v.livekit.udpPort }}/udp on the load balancer of the Service livekit-rtc,
|
||||
whose public IP must be {{ $v.livekit.nodeIP }}.
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
Back up the Secret {{ include "fluxer.secretName" . }}{{ if $v.postgres.enabled }}, the database in postgres-0{{ end }}{{ if $v.seaweedfs.enabled }} and the uploads on the volume data-seaweedfs-0{{ end }}.
|
||||
{{- if $v.secrets.existingSecret }}
|
||||
After editing the Secret {{ $v.secrets.existingSecret }}, restart the release:
|
||||
|
||||
kubectl -n {{ .Release.Namespace }} rollout restart deployment,statefulset -l app.kubernetes.io/instance={{ .Release.Name }}
|
||||
{{- end }}
|
||||
{{- if and $v.secrets.generate (not $v.secrets.existingSecret) }}
|
||||
|
||||
Argo CD and helm template cannot read the existing Secret and would generate
|
||||
new secrets on every render. Under them, set secrets.generate=false and use
|
||||
secrets.existingSecret or give every key in secrets.values.
|
||||
{{- end }}
|
||||
|
||||
To move to the latest v1 images, pull the repository and upgrade with your values file:
|
||||
|
||||
helm upgrade {{ .Release.Name }} <chart> -n {{ .Release.Namespace }} -f <your values file> --set-string image.revision=$(date +%s)
|
||||
|
||||
Leave out --reuse-values, which keeps the defaults of the old chart version.
|
||||
|
||||
Documentation: https://docs.fluxer.app/operator/kubernetes/
|
||||
@@ -0,0 +1,109 @@
|
||||
{{- define "fluxer.s3Endpoint" -}}
|
||||
{{- .Values.s3.endpoint | default (ternary "http://seaweedfs:8333" "" .Values.seaweedfs.enabled) }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.configData" -}}
|
||||
{{- $v := .Values }}
|
||||
{{- $o := include "fluxer.origin" . }}
|
||||
{{- $hostOrigin := include "fluxer.hostOrigin" . }}
|
||||
{{- $media := printf "%s/media" $o }}
|
||||
{{- $s3 := include "fluxer.s3Endpoint" . }}
|
||||
{{- $c := dict }}
|
||||
{{- $_ := set $c "FLUXER_ENV" "production" }}
|
||||
{{- $_ := set $c "FLUXER_SELF_HOSTED" "true" }}
|
||||
{{- $_ := set $c "FLUXER_DATABASE_BACKEND" "postgres" }}
|
||||
{{- $_ := set $c "FLUXER_TRUST_CLIENT_IP_HEADER" "true" }}
|
||||
{{- $_ := set $c "FLUXER_BASE_DOMAIN" $v.domain }}
|
||||
{{- $_ := set $c "FLUXER_PUBLIC_SCHEME" $v.scheme }}
|
||||
{{- $_ := set $c "FLUXER_PUBLIC_PORT" (include "fluxer.string" $v.port) }}
|
||||
{{- $_ := set $c "FLUXER_PUBLIC_ORIGIN" (trimSuffix "/" ($v.publicOrigin | default "")) }}
|
||||
{{- $_ := set $c "FLUXER_APP_ENDPOINT" $o }}
|
||||
{{- $_ := set $c "FLUXER_MARKETING_ENDPOINT" $o }}
|
||||
{{- $_ := set $c "FLUXER_MEDIA_ENDPOINT" $media }}
|
||||
{{- $_ := set $c "FLUXER_MEDIA_PROXY_PUBLIC_ENDPOINT" $media }}
|
||||
{{- $_ := set $c "FLUXER_MEDIA_PROXY_UPLOAD_RELAY_ENDPOINT" $media }}
|
||||
{{- $_ := set $c "FLUXER_GATEWAY_MEDIA_PROXY_ENDPOINT" $media }}
|
||||
{{- $_ := set $c "FLUXER_ADMIN_ENDPOINT" (printf "%s%s" $o $v.adminBasePath) }}
|
||||
{{- $_ := set $c "FLUXER_GATEWAY_STATIC_CDN_ENDPOINT" $o }}
|
||||
{{- $_ := set $c "FLUXER_MEDIA_PROXY_CORS_ALLOWED_ORIGINS" $hostOrigin }}
|
||||
{{- $_ := set $c "FLUXER_PASSKEY_RP_ID" $v.domain }}
|
||||
{{- $_ := set $c "FLUXER_PASSKEY_ADDITIONAL_ALLOWED_ORIGINS" $o }}
|
||||
{{- if $v.postgres.enabled }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_HOST" "postgres" }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_PORT" "5432" }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_DATABASE" $v.postgres.database }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_USERNAME" $v.postgres.username }}
|
||||
{{- else }}
|
||||
{{- with $v.postgres.external }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_HOST" (.host | default "") }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_PORT" (include "fluxer.string" (.port | default "")) }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_DATABASE" (.database | default "") }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_USERNAME" (.username | default "") }}
|
||||
{{- $_ := set $c "FLUXER_POSTGRES_SSL" (include "fluxer.string" (.ssl | default "")) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if not $v.valkey.enabled }}
|
||||
{{- $_ := set $c "FLUXER_KV_URL" ($v.valkey.external.url | default "") }}
|
||||
{{- end }}
|
||||
{{- $nats := ternary "nats://nats:4222" ($v.nats.external.url | default "") $v.nats.enabled }}
|
||||
{{- $_ := set $c "FLUXER_NATS_URL" $nats }}
|
||||
{{- $_ := set $c "FLUXER_NATS_JETSTREAM_URL" $nats }}
|
||||
{{- $_ := set $c "FLUXER_SVC_NATS_URL" $nats }}
|
||||
{{- $_ := set $c "FLUXER_SEARCH_ENGINE" "meilisearch" }}
|
||||
{{- $_ := set $c "FLUXER_SEARCH_URL" (ternary "http://meilisearch:7700" ($v.meilisearch.external.url | default "") $v.meilisearch.enabled) }}
|
||||
{{- $_ := set $c "FLUXER_S3_ENDPOINT" $s3 }}
|
||||
{{- $_ := set $c "FLUXER_S3_PUBLIC_ENDPOINT" ($v.s3.publicEndpoint | default $s3) }}
|
||||
{{- $_ := set $c "FLUXER_S3_REGION" $v.s3.region }}
|
||||
{{- $_ := set $c "FLUXER_S3_FORCE_PATH_STYLE" (toString $v.s3.forcePathStyle) }}
|
||||
{{- $_ := set $c "FLUXER_S3_BUCKET_CDN" $v.s3.buckets.cdn }}
|
||||
{{- $_ := set $c "FLUXER_S3_BUCKET_UPLOADS" $v.s3.buckets.uploads }}
|
||||
{{- $_ := set $c "FLUXER_S3_BUCKET_REPORTS" $v.s3.buckets.reports }}
|
||||
{{- $_ := set $c "FLUXER_S3_BUCKET_HARVESTS" $v.s3.buckets.harvests }}
|
||||
{{- $livekit := include "fluxer.livekitMode" . }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_ENABLED" (toString (ne $livekit "off")) }}
|
||||
{{- if eq $livekit "bundled" }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_INTERNAL_URL" "http://livekit:7880" }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_DEFAULT_REGION" $v.livekit.defaultRegion }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_URL" (printf "%s/livekit" $hostOrigin) }}
|
||||
{{- else if eq $livekit "external" }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_INTERNAL_URL" $v.livekit.external.url }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_DEFAULT_REGION" $v.livekit.defaultRegion }}
|
||||
{{- $_ := set $c "FLUXER_LIVEKIT_URL" $v.livekit.external.publicUrl }}
|
||||
{{- end }}
|
||||
{{- $_ := set $c "FLUXER_API_PRESIGNED_HARVEST_DOWNLOADS_ENABLED" "false" }}
|
||||
{{- $_ := set $c "FLUXER_EMAIL_FROM_EMAIL" "noreply@localhost" }}
|
||||
{{- $_ := set $c "FLUXER_VAPID_EMAIL" ($v.email | default (printf "admin@%s" $v.domain)) }}
|
||||
{{- $_ := set $c "FLUXER_INTERNAL_API_ENDPOINT" "http://api:8080" }}
|
||||
{{- $_ := set $c "FLUXER_INTERNAL_MEDIA_PROXY_ENDPOINT" "http://media-proxy:8080" }}
|
||||
{{- range $k, $val := $v.env | default dict }}
|
||||
{{- $_ := set $c $k (include "fluxer.string" ($val | default "")) }}
|
||||
{{- end }}
|
||||
{{- $out := dict }}
|
||||
{{- range $k, $val := $c }}
|
||||
{{- if $val }}
|
||||
{{- $_ := set $out $k $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- toYaml $out }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.appProxyConfigData" -}}
|
||||
{{- $v := .Values }}
|
||||
{{- $s3 := include "fluxer.s3Endpoint" . }}
|
||||
{{- $c := dict }}
|
||||
{{- $_ := set $c "FLUXER_APP_PROXY_PORT" "8080" }}
|
||||
{{- $_ := set $c "DISCOVERY_UPSTREAM_URL" "http://api:8080/.well-known/fluxer" }}
|
||||
{{- $_ := set $c "FLUXER_S3_PUBLIC_ENDPOINT" ($v.s3.publicEndpoint | default $s3) }}
|
||||
{{- $_ := set $c "FLUXER_S3_BUCKET_UPLOADS" $v.s3.buckets.uploads }}
|
||||
{{- $_ := set $c "FLUXER_MEDIA_ENDPOINT" (printf "%s/media" (include "fluxer.origin" .)) }}
|
||||
{{- range $k, $val := $v.appProxy.config | default dict }}
|
||||
{{- $_ := set $c $k (include "fluxer.string" ($val | default "")) }}
|
||||
{{- end }}
|
||||
{{- $out := dict }}
|
||||
{{- range $k, $val := $c }}
|
||||
{{- if $val }}
|
||||
{{- $_ := set $out $k $val }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- toYaml $out }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,374 @@
|
||||
{{- define "fluxer.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" -}}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ .name }}
|
||||
app.kubernetes.io/instance: {{ .root.Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.podLabels" -}}
|
||||
{{ include "fluxer.selectorLabels" . }}
|
||||
{{- with .component }}
|
||||
app.kubernetes.io/component: {{ . }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/part-of: fluxer
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.labels" -}}
|
||||
{{ include "fluxer.podLabels" . }}
|
||||
app.kubernetes.io/managed-by: {{ .root.Release.Service }}
|
||||
app.kubernetes.io/version: {{ .root.Chart.AppVersion | quote }}
|
||||
helm.sh/chart: {{ include "fluxer.chart" .root }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.string" -}}
|
||||
{{- if and (kindIs "float64" .) (eq . (float64 (int64 .))) }}
|
||||
{{- int64 . | toString }}
|
||||
{{- else }}
|
||||
{{- toString . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.origin" -}}
|
||||
{{- $v := .Values }}
|
||||
{{- if $v.publicOrigin }}
|
||||
{{- trimSuffix "/" $v.publicOrigin }}
|
||||
{{- else }}
|
||||
{{- $default := ternary 443 80 (eq $v.scheme "https") }}
|
||||
{{- if eq (int $v.port) $default }}
|
||||
{{- printf "%s://%s" $v.scheme $v.domain }}
|
||||
{{- else }}
|
||||
{{- printf "%s://%s:%d" $v.scheme $v.domain (int $v.port) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.hostOrigin" -}}
|
||||
{{- $v := .Values }}
|
||||
{{- if $v.publicOrigin }}
|
||||
{{- trimSuffix "/" $v.publicOrigin }}
|
||||
{{- else }}
|
||||
{{- printf "%s://%s:%d" $v.scheme $v.domain (int $v.port) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.secretName" -}}
|
||||
{{- .Values.secrets.existingSecret | default "fluxer-env" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.thirdPartyImage" -}}
|
||||
{{- $ref := printf "%s:%s" .repository (include "fluxer.string" .tag) }}
|
||||
{{- with .digest }}
|
||||
{{- $ref = printf "%s@%s" $ref . }}
|
||||
{{- end }}
|
||||
{{- $ref | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.image" -}}
|
||||
{{- $v := .root.Values.image }}
|
||||
{{- $img := (.w | default dict).image | default dict }}
|
||||
{{- $registry := $img.registry | default $v.registry }}
|
||||
{{- $tag := $img.tag | default (get ($v.tags | default dict) .image) | default $v.tag }}
|
||||
{{- $ref := printf "%s/%s:%s" $registry .image (include "fluxer.string" $tag) }}
|
||||
{{- with $img.digest | default (get ($v.digests | default dict) .image) }}
|
||||
{{- $ref = printf "%s@%s" $ref . }}
|
||||
{{- end }}
|
||||
{{- $ref | quote }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.pullPolicy" -}}
|
||||
{{- (((.w | default dict).image | default dict).pullPolicy) | default .root.Values.image.pullPolicy }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.pullSecrets" -}}
|
||||
{{- with .Values.image.pullSecrets }}
|
||||
imagePullSecrets:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.podSecurityContext" -}}
|
||||
runAsNonRoot: true
|
||||
{{- with .uid }}
|
||||
runAsUser: {{ . }}
|
||||
runAsGroup: {{ $.gid | default . }}
|
||||
fsGroup: {{ $.gid | default . }}
|
||||
fsGroupChangePolicy: OnRootMismatch
|
||||
{{- end }}
|
||||
seccompProfile:
|
||||
type: RuntimeDefault
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.containerSecurityContext" -}}
|
||||
allowPrivilegeEscalation: false
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.scheduling" -}}
|
||||
{{- $w := .w | default dict }}
|
||||
{{- with $w.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with $w.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- with $w.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- $spread := list }}
|
||||
{{- range $w.topologySpreadConstraints }}
|
||||
{{- $c := deepCopy . }}
|
||||
{{- if not (hasKey $c "labelSelector") }}
|
||||
{{- $_ := set $c "labelSelector" (dict "matchLabels" (include "fluxer.selectorLabels" $ | fromYaml)) }}
|
||||
{{- end }}
|
||||
{{- $spread = append $spread $c }}
|
||||
{{- end }}
|
||||
{{- with $spread }}
|
||||
topologySpreadConstraints:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.pvc" -}}
|
||||
- metadata:
|
||||
name: data
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- with .storageClassName }}
|
||||
storageClassName: {{ . }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .size }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.vapidPair" -}}
|
||||
{{- $der := genPrivateKey "ecdsa" | replace "-----BEGIN EC PRIVATE KEY-----" "" | replace "-----END EC PRIVATE KEY-----" "" | nospace | b64dec -}}
|
||||
private: {{ substr 7 39 $der | b64enc | replace "+" "-" | replace "/" "_" | trimAll "=" }}
|
||||
public: {{ substr 56 121 $der | b64enc | replace "+" "-" | replace "/" "_" | trimAll "=" }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.livekitMode" -}}
|
||||
{{- if .Values.livekit.enabled }}bundled{{ else if .Values.livekit.external.url }}external{{ else }}off{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.noGenerateKeys" -}}
|
||||
{{- $keys := list }}
|
||||
{{- $extra := .Values.secrets.extra | default dict }}
|
||||
{{- if and (not .Values.postgres.enabled) (not (get $extra "FLUXER_POSTGRES_URL")) }}
|
||||
{{- $keys = append $keys "FLUXER_POSTGRES_PASSWORD" }}
|
||||
{{- end }}
|
||||
{{- if not .Values.meilisearch.enabled }}
|
||||
{{- $keys = append $keys "FLUXER_SEARCH_API_KEY" }}
|
||||
{{- end }}
|
||||
{{- if not .Values.seaweedfs.enabled }}
|
||||
{{- $keys = append $keys "FLUXER_S3_SECRET_ACCESS_KEY" }}
|
||||
{{- end }}
|
||||
{{- if eq (include "fluxer.livekitMode" .) "external" }}
|
||||
{{- $keys = append $keys "FLUXER_LIVEKIT_API_SECRET" }}
|
||||
{{- end }}
|
||||
{{- toJson $keys }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.requiredSecretKeys" -}}
|
||||
{{- $keys := list }}
|
||||
{{- $extra := .Values.secrets.extra | default dict }}
|
||||
{{- range $k, $_ := .Values.secrets.values }}
|
||||
{{- if and (eq $k "FLUXER_POSTGRES_PASSWORD") (get $extra "FLUXER_POSTGRES_URL") }}
|
||||
{{- else if and (hasPrefix "FLUXER_LIVEKIT_" $k) (eq (include "fluxer.livekitMode" $) "off") }}
|
||||
{{- else if and (eq $k "FLUXER_VALKEY_PASSWORD") (not $.Values.valkey.enabled) }}
|
||||
{{- else if and (eq $k "FLUXER_NATS_AUTH_TOKEN") (not $.Values.nats.enabled) }}
|
||||
{{- else }}
|
||||
{{- $keys = append $keys $k }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- toJson $keys }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.resolveSecrets" -}}
|
||||
{{- $v := .Values }}
|
||||
{{- $existing := dict }}
|
||||
{{- $found := lookup "v1" "Secret" .Release.Namespace (include "fluxer.secretName" .) }}
|
||||
{{- range $k, $val := ($found.data | default dict) }}
|
||||
{{- $_ := set $existing $k (b64dec $val) }}
|
||||
{{- end }}
|
||||
{{- $out := dict }}
|
||||
{{- if $v.secrets.existingSecret }}
|
||||
{{- $out = $existing }}
|
||||
{{- else }}
|
||||
{{- $noGenerate := include "fluxer.noGenerateKeys" . | fromJsonArray }}
|
||||
{{- $explicit := $v.secrets.values | default dict }}
|
||||
{{- $vapidPublic := include "fluxer.string" (get $explicit "FLUXER_VAPID_PUBLIC_KEY" | default "") }}
|
||||
{{- $vapidPrivate := include "fluxer.string" (get $explicit "FLUXER_VAPID_PRIVATE_KEY" | default "") }}
|
||||
{{- if and $vapidPublic $vapidPrivate }}
|
||||
{{- else if or $vapidPublic $vapidPrivate }}
|
||||
{{- fail "secrets.values.FLUXER_VAPID_PUBLIC_KEY and secrets.values.FLUXER_VAPID_PRIVATE_KEY must be set together, or both left empty to generate a pair" }}
|
||||
{{- else if and (get $existing "FLUXER_VAPID_PUBLIC_KEY") (get $existing "FLUXER_VAPID_PRIVATE_KEY") }}
|
||||
{{- $vapidPublic = get $existing "FLUXER_VAPID_PUBLIC_KEY" }}
|
||||
{{- $vapidPrivate = get $existing "FLUXER_VAPID_PRIVATE_KEY" }}
|
||||
{{- else if $v.secrets.generate }}
|
||||
{{- $pair := include "fluxer.vapidPair" . | fromYaml }}
|
||||
{{- $vapidPublic = $pair.public }}
|
||||
{{- $vapidPrivate = $pair.private }}
|
||||
{{- else }}
|
||||
{{- fail "secrets.values.FLUXER_VAPID_PUBLIC_KEY and secrets.values.FLUXER_VAPID_PRIVATE_KEY are empty and secrets.generate is false" }}
|
||||
{{- end }}
|
||||
{{- $_ := set $out "FLUXER_VAPID_PUBLIC_KEY" $vapidPublic }}
|
||||
{{- $_ := set $out "FLUXER_VAPID_PRIVATE_KEY" $vapidPrivate }}
|
||||
{{- $required := include "fluxer.requiredSecretKeys" . | fromJsonArray }}
|
||||
{{- $outsideToken := include "fluxer.string" (get $explicit "FLUXER_NATS_AUTH_TOKEN" | default "") }}
|
||||
{{- if and $outsideToken (not $v.nats.enabled) }}
|
||||
{{- $_ := set $out "FLUXER_NATS_AUTH_TOKEN" $outsideToken }}
|
||||
{{- end }}
|
||||
{{- range $k := $required }}
|
||||
{{- if not (hasPrefix "FLUXER_VAPID_" $k) }}
|
||||
{{- $given := include "fluxer.string" (get $explicit $k | default "") }}
|
||||
{{- if $given }}
|
||||
{{- $_ := set $out $k $given }}
|
||||
{{- else if has $k $noGenerate }}
|
||||
{{- fail (printf "secrets.values.%s is required when the matching service is not bundled" $k) }}
|
||||
{{- else if get $existing $k }}
|
||||
{{- $_ := set $out $k (get $existing $k) }}
|
||||
{{- else if $v.secrets.generate }}
|
||||
{{- if eq $k "FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64" }}
|
||||
{{- $_ := set $out $k (randBytes 32) }}
|
||||
{{- else }}
|
||||
{{- $_ := set $out $k (randAlphaNum 64) }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- fail (printf "secrets.values.%s is empty and secrets.generate is false" $k) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := $v.secrets.extra | default dict }}
|
||||
{{- $s := include "fluxer.string" ($val | default "") }}
|
||||
{{- if $s }}
|
||||
{{- $_ := set $out $k $s }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- toJson $out }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.secretData" -}}
|
||||
{{- if not (hasKey .Values "fluxerResolvedSecrets") }}
|
||||
{{- $_ := set .Values "fluxerResolvedSecrets" (include "fluxer.resolveSecrets" . | fromJson) }}
|
||||
{{- end }}
|
||||
{{- toJson (get .Values "fluxerResolvedSecrets") }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.secretEnv" -}}
|
||||
- name: {{ .name }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "fluxer.secretName" .root }}
|
||||
key: {{ .key }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.instanceChecksum" -}}
|
||||
{{- $parts := list (include "fluxer.configData" .) (include "fluxer.appProxyConfigData" .) (toJson .Values.secrets.values) (toJson (.Values.secrets.extra | default dict)) (include "fluxer.string" .Values.image.revision) (include "fluxer.secretData" .) }}
|
||||
{{- join "\n" $parts | sha256sum }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.envList" -}}
|
||||
{{- $w := .w | default dict }}
|
||||
{{- $own := $w.env | default dict }}
|
||||
{{- $base := .env | default list }}
|
||||
{{- $names := list }}
|
||||
{{- range $base }}
|
||||
{{- $names = append $names .name }}
|
||||
{{- end }}
|
||||
{{- $out := list }}
|
||||
{{- range $base }}
|
||||
{{- if hasKey $own .name }}
|
||||
{{- $val := get $own .name }}
|
||||
{{- if not (kindIs "invalid" $val) }}
|
||||
{{- $out = append $out (dict "name" .name "value" (include "fluxer.string" $val)) }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- $out = append $out . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $k := keys $own | sortAlpha }}
|
||||
{{- $val := get $own $k }}
|
||||
{{- if and (not (has $k $names)) (not (kindIs "invalid" $val)) }}
|
||||
{{- $out = append $out (dict "name" $k "value" (include "fluxer.string" $val)) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $out = concat $out ($w.extraEnv | default list) }}
|
||||
{{- with $out }}
|
||||
{{- toYaml . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.probes" -}}
|
||||
{{- $own := (.w | default dict).probes | default dict }}
|
||||
{{- range $probe := list "startup" "liveness" "readiness" }}
|
||||
{{- $p := get ($.probes | default dict) $probe }}
|
||||
{{- if hasKey $own $probe }}
|
||||
{{- $p = get $own $probe }}
|
||||
{{- end }}
|
||||
{{- with $p }}
|
||||
{{ $probe }}Probe:
|
||||
{{- toYaml . | nindent 2 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.waitFor" -}}
|
||||
{{- with .waitFor }}
|
||||
initContainers:
|
||||
- name: wait-for-dependencies
|
||||
image: {{ include "fluxer.thirdPartyImage" $.root.Values.initImage }}
|
||||
imagePullPolicy: {{ $.root.Values.initImage.pullPolicy }}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- {{ printf "for t in %s; do until nc -z -w 2 ${t%%:*} ${t##*:}; do echo waiting for $t; sleep 2; done; done" (join " " .) | quote }}
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 16Mi
|
||||
limits:
|
||||
memory: 32Mi
|
||||
securityContext:
|
||||
runAsUser: 65532
|
||||
runAsGroup: 65532
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.appWaitFor" -}}
|
||||
{{- $out := list }}
|
||||
{{- if and .usesNats .root.Values.nats.enabled }}
|
||||
{{- $out = append $out "nats:4222" }}
|
||||
{{- end }}
|
||||
{{- if and .usesPostgres .root.Values.postgres.enabled }}
|
||||
{{- $out = append $out "postgres:5432" }}
|
||||
{{- end }}
|
||||
{{- if and .usesS3 .root.Values.seaweedfs.enabled }}
|
||||
{{- $out = append $out "seaweedfs:8333" }}
|
||||
{{- end }}
|
||||
{{- if and .usesKv .root.Values.valkey.enabled }}
|
||||
{{- $out = append $out "valkey:6379" }}
|
||||
{{- end }}
|
||||
{{- if .usesSvc }}
|
||||
{{- range $name := list "gifs" "messages" "snowflakes" "unfurl" "users" }}
|
||||
{{- $svc := get $.root.Values.svc $name | default dict }}
|
||||
{{- if gt (int (include "fluxer.replicas" (dict "w" ($svc.router | default dict)))) 0 }}
|
||||
{{- $out = append $out (printf "%s:8090" $name) }}
|
||||
{{- end }}
|
||||
{{- if gt (int (include "fluxer.replicas" (dict "w" ($svc.shard | default dict)))) 0 }}
|
||||
{{- $out = append $out (printf "%s-shard:8090" $name) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- toJson $out }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,245 @@
|
||||
{{- define "fluxer.validate" -}}
|
||||
{{- if not (hasKey .Values "fluxerValidated") }}
|
||||
{{- $_ := set .Values "fluxerValidated" true }}
|
||||
{{- $v := .Values }}
|
||||
{{- if not (regexMatch "^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$" ($v.domain | default "")) }}
|
||||
{{- fail "domain must be set to the lowercase public hostname of the instance, for example --set domain=chat.example.com" }}
|
||||
{{- end }}
|
||||
{{- if not (has $v.scheme (list "http" "https")) }}
|
||||
{{- fail "scheme must be http or https" }}
|
||||
{{- end }}
|
||||
{{- if and $v.publicOrigin (not (regexMatch "^https?://[^/]+$" (trimSuffix "/" $v.publicOrigin))) }}
|
||||
{{- fail "publicOrigin must be a scheme, host and optional port, for example https://chat.example.com" }}
|
||||
{{- end }}
|
||||
{{- if not (regexMatch "^/[^/].*[^/]$|^/[^/]$" $v.adminBasePath) }}
|
||||
{{- fail "adminBasePath must start with a slash and must not end with one, for example /admin" }}
|
||||
{{- end }}
|
||||
{{- $extra := $v.secrets.extra | default dict }}
|
||||
{{- if and (not $v.postgres.enabled) (not $v.postgres.external.host) (not (get $extra "FLUXER_POSTGRES_URL")) (not $v.secrets.existingSecret) }}
|
||||
{{- fail "postgres.enabled is false, so set postgres.external.host or secrets.extra.FLUXER_POSTGRES_URL" }}
|
||||
{{- end }}
|
||||
{{- if and (not $v.valkey.enabled) (not $v.valkey.external.url) (not (get $extra "FLUXER_KV_URL")) (not $v.secrets.existingSecret) }}
|
||||
{{- fail "valkey.enabled is false, so set valkey.external.url or secrets.extra.FLUXER_KV_URL" }}
|
||||
{{- end }}
|
||||
{{- if and (not $v.nats.enabled) (not $v.nats.external.url) }}
|
||||
{{- fail "nats.enabled is false, so set nats.external.url" }}
|
||||
{{- end }}
|
||||
{{- if and (not $v.meilisearch.enabled) (not $v.meilisearch.external.url) }}
|
||||
{{- fail "meilisearch.enabled is false, so set meilisearch.external.url" }}
|
||||
{{- end }}
|
||||
{{- if and (not $v.seaweedfs.enabled) (not $v.s3.endpoint) }}
|
||||
{{- fail "seaweedfs.enabled is false, so set s3.endpoint to your S3 store" }}
|
||||
{{- end }}
|
||||
{{- if gt (int $v.nats.replicas) 1 }}
|
||||
{{- if lt (int $v.nats.replicas) 3 }}
|
||||
{{- fail "nats.replicas must be 1, or 3 or more for a JetStream cluster" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if gt (int (include "fluxer.replicas" (dict "w" $v.worker))) 1 }}
|
||||
{{- fail "worker.replicas must be 1, because the worker runs the cron scheduler" }}
|
||||
{{- end }}
|
||||
{{- if not (has $v.livekit.expose (list "hostNetwork" "loadBalancer" "nodePort")) }}
|
||||
{{- fail "livekit.expose must be hostNetwork, loadBalancer or nodePort" }}
|
||||
{{- end }}
|
||||
{{- if and $v.livekit.enabled $v.livekit.external.url }}
|
||||
{{- fail "livekit.external.url names a LiveKit server of your own, so set livekit.enabled to false" }}
|
||||
{{- end }}
|
||||
{{- if and $v.livekit.external.url (not (regexMatch "^(wss?|https?)://[^/]+" ($v.livekit.external.publicUrl | default ""))) }}
|
||||
{{- fail "livekit.external.url is set, so set livekit.external.publicUrl to the address browsers use to reach that LiveKit server, for example wss://livekit.example.com" }}
|
||||
{{- end }}
|
||||
{{- if and $v.livekit.enabled (eq $v.livekit.expose "loadBalancer") (not $v.livekit.nodeIP) }}
|
||||
{{- fail "livekit.expose is loadBalancer, so reserve a public address before installing, set livekit.nodeIP to it, and pin the Service livekit-rtc to it with livekit.loadBalancerIP or livekit.serviceAnnotations. Use hostNetwork or nodePort where a load balancer cannot serve TCP and UDP on one address" }}
|
||||
{{- end }}
|
||||
{{- if not (has $v.edge.expose (list "ingress" "gateway" "loadBalancer" "none")) }}
|
||||
{{- fail "edge.expose must be ingress, gateway, loadBalancer or none" }}
|
||||
{{- end }}
|
||||
{{- if not (has $v.edge.ingress.tls.mode (list "certManager" "existingSecret" "none")) }}
|
||||
{{- fail "edge.ingress.tls.mode must be certManager, existingSecret or none" }}
|
||||
{{- end }}
|
||||
{{- if and (eq $v.edge.expose "gateway") (not $v.edge.gateway.parentRefs) }}
|
||||
{{- fail "edge.expose is gateway, so set edge.gateway.parentRefs to the Gateway the route attaches to" }}
|
||||
{{- end }}
|
||||
{{- if and (eq $v.edge.expose "loadBalancer") (ne $v.scheme "https") }}
|
||||
{{- fail "edge.expose loadBalancer serves HTTPS itself, so scheme must be https" }}
|
||||
{{- end }}
|
||||
{{- if and $v.networkPolicy.enabled $v.networkPolicy.ingressNamespaceSelector $v.livekit.enabled (eq $v.livekit.expose "hostNetwork") (not $v.livekit.nodeCIDRs) }}
|
||||
{{- fail "networkPolicy.ingressNamespaceSelector limits who reaches the edge, and LiveKit on the host network sends its webhook to the edge from a node address. Set livekit.nodeCIDRs to the address of the LiveKit node, for example 10.0.0.12/32" }}
|
||||
{{- end }}
|
||||
|
||||
{{- $placeholder := "(?i)change[_-]?me" }}
|
||||
{{- $secretName := "_(PASSWORD|SECRET|TOKEN|COOKIE|KEY|KEYS|KEY_BASE|SECRETS?_BASE64)$" }}
|
||||
{{- $credentialUrl := "://[^/@ ]*:[^/@ ]*@" }}
|
||||
{{- $plain := dict "env" ($v.env | default dict) "appProxy.config" ($v.appProxy.config | default dict) "edge.env" ($v.edge.env | default dict) }}
|
||||
{{- range $name := list "api" "worker" "gateway" "mediaProxy" "push" "admin" "appProxy" "staticProxy" }}
|
||||
{{- $_ := set $plain (printf "%s.env" $name) ((get $v $name).env | default dict) }}
|
||||
{{- end }}
|
||||
{{- range $name, $svc := $v.svc }}
|
||||
{{- range $part := list "router" "shard" }}
|
||||
{{- $_ := set $plain (printf "svc.%s.%s.env" $name $part) ((get ($svc | default dict) $part | default dict).env | default dict) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $where, $map := $plain }}
|
||||
{{- range $k, $val := $map }}
|
||||
{{- $s := include "fluxer.string" ($val | default "") }}
|
||||
{{- if regexMatch $placeholder $s }}
|
||||
{{- fail (printf "%s.%s is a placeholder. Remove it or set a real value" $where $k) }}
|
||||
{{- end }}
|
||||
{{- if or (hasKey $v.secrets.values $k) (regexMatch $secretName $k) }}
|
||||
{{- fail (printf "%s.%s is a secret and would be stored in plain text. Set it in secrets.extra instead, or reference a Secret of your own from extraEnv" $where $k) }}
|
||||
{{- end }}
|
||||
{{- if regexMatch $credentialUrl $s }}
|
||||
{{- fail (printf "%s.%s is a URL that holds a password and would be stored in plain text. Set it in secrets.extra instead" $where $k) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := $v.secrets.values }}
|
||||
{{- if regexMatch $placeholder (include "fluxer.string" ($val | default "")) }}
|
||||
{{- fail (printf "secrets.values.%s is a placeholder. Leave it empty to generate a value, or set a real one" $k) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- range $k, $val := $extra }}
|
||||
{{- if regexMatch $placeholder (include "fluxer.string" ($val | default "")) }}
|
||||
{{- fail (printf "secrets.extra.%s is a placeholder. Remove it or set a real value" $k) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- $connected := false }}
|
||||
{{- if $v.clusterChecks }}
|
||||
{{- $connected = or (lookup "v1" "Namespace" "" .Release.Namespace) (lookup "v1" "Namespace" "" "kube-system") | not | not }}
|
||||
{{- end }}
|
||||
{{- $data := include "fluxer.secretData" . | fromJson }}
|
||||
{{- $secret := include "fluxer.secretName" . }}
|
||||
{{- if $v.secrets.existingSecret }}
|
||||
{{- if and $connected (not $data) }}
|
||||
{{- fail (printf "secrets.existingSecret names the Secret %s, which does not exist in namespace %s. Create it first with every key listed under secrets.values" $secret .Release.Namespace) }}
|
||||
{{- end }}
|
||||
{{- if $data }}
|
||||
{{- $missing := list }}
|
||||
{{- range $k := include "fluxer.requiredSecretKeys" . | fromJsonArray }}
|
||||
{{- if not (get $data $k) }}
|
||||
{{- $missing = append $missing $k }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $missing }}
|
||||
{{- fail (printf "Secret %s is missing these keys: %s" $secret (join ", " .)) }}
|
||||
{{- end }}
|
||||
{{- $config := include "fluxer.configData" . | fromYaml }}
|
||||
{{- if $v.valkey.enabled }}
|
||||
{{- $_ := set $config "FLUXER_KV_URL" "the bundled Valkey" }}
|
||||
{{- end }}
|
||||
{{- $shadowed := list }}
|
||||
{{- range $k := keys $config | sortAlpha }}
|
||||
{{- if and (hasKey $data $k) (ne (get $data $k) (get $config $k)) }}
|
||||
{{- $shadowed = append $shadowed $k }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $shadowed }}
|
||||
{{- fail (printf "Secret %s holds settings the chart sets itself, and the two disagree: %s. Remove them from the Secret. To keep an outside service, turn the bundled one off, as the External services section of the Kubernetes page describes" $secret (join ", " .)) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $data }}
|
||||
{{- range $k, $val := $data }}
|
||||
{{- if regexMatch $placeholder $val }}
|
||||
{{- fail (printf "%s in the Secret %s is a placeholder. Set a real value" $k $secret) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with get $data "FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64" }}
|
||||
{{- if or (not (regexMatch "^[A-Za-z0-9+/]+={0,2}$" .)) (lt (len (b64dec .)) 32) }}
|
||||
{{- fail "FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64 must be standard base64 of at least 32 bytes, for example the output of openssl rand -base64 32" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $long := list "FLUXER_SUDO_MODE_SECRET" "FLUXER_CONNECTION_INITIATION_SECRET" "FLUXER_PROFILE_PSEUDONYM_SECRET" "FLUXER_GATEWAY_RPC_AUTH_TOKEN" "FLUXER_ERLANG_COOKIE" "FLUXER_MEDIA_PROXY_SECRET_KEY" "FLUXER_ADMIN_SECRET_KEY_BASE" "FLUXER_ADMIN_OAUTH_CLIENT_SECRET" }}
|
||||
{{- if ne (include "fluxer.livekitMode" .) "off" }}
|
||||
{{- $long = append $long "FLUXER_LIVEKIT_API_SECRET" }}
|
||||
{{- end }}
|
||||
{{- if $v.valkey.enabled }}
|
||||
{{- $long = append $long "FLUXER_VALKEY_PASSWORD" }}
|
||||
{{- end }}
|
||||
{{- if $v.nats.enabled }}
|
||||
{{- $long = append $long "FLUXER_NATS_AUTH_TOKEN" }}
|
||||
{{- end }}
|
||||
{{- range $k := $long }}
|
||||
{{- if and (hasKey $data $k) (lt (len (get $data $k)) 32) }}
|
||||
{{- fail (printf "%s must be at least 32 characters, for example the output of openssl rand -hex 32" $k) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and $v.meilisearch.enabled (hasKey $data "FLUXER_SEARCH_API_KEY") (lt (len (get $data "FLUXER_SEARCH_API_KEY")) 16) }}
|
||||
{{- fail "FLUXER_SEARCH_API_KEY must be at least 16 characters, or the bundled Meilisearch refuses to start" }}
|
||||
{{- end }}
|
||||
{{- if eq (get $data "FLUXER_POSTGRES_PASSWORD" | default "") "fluxer" }}
|
||||
{{- fail "FLUXER_POSTGRES_PASSWORD must not be fluxer, which the services refuse in production" }}
|
||||
{{- end }}
|
||||
{{- $plainOnly := list }}
|
||||
{{- if $v.seaweedfs.enabled }}
|
||||
{{- $plainOnly = concat $plainOnly (list "FLUXER_S3_ACCESS_KEY_ID" "FLUXER_S3_SECRET_ACCESS_KEY") }}
|
||||
{{- end }}
|
||||
{{- if $v.valkey.enabled }}
|
||||
{{- $plainOnly = append $plainOnly "FLUXER_VALKEY_PASSWORD" }}
|
||||
{{- end }}
|
||||
{{- if $v.nats.enabled }}
|
||||
{{- $plainOnly = append $plainOnly "FLUXER_NATS_AUTH_TOKEN" }}
|
||||
{{- end }}
|
||||
{{- range $k := $plainOnly }}
|
||||
{{- if and (hasKey $data $k) (not (regexMatch "^[A-Za-z0-9]+$" (get $data $k))) }}
|
||||
{{- fail (printf "%s must contain letters and digits only, because the bundled service takes it on a command line or in a URL" $k) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $pub := get $data "FLUXER_VAPID_PUBLIC_KEY" | default "" }}
|
||||
{{- $priv := get $data "FLUXER_VAPID_PRIVATE_KEY" | default "" }}
|
||||
{{- if or $pub $priv }}
|
||||
{{- if or (not (regexMatch "^[A-Za-z0-9_-]{87}$" $pub)) (not (regexMatch "^[A-Za-z0-9_-]{43}$" $priv)) }}
|
||||
{{- fail "FLUXER_VAPID_PUBLIC_KEY and FLUXER_VAPID_PRIVATE_KEY must be an unpadded base64url P-256 pair of 87 and 43 characters" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if $connected }}
|
||||
{{- if and (eq $v.edge.expose "ingress") (eq $v.edge.ingress.tls.mode "certManager") (not (.Capabilities.APIVersions.Has "cert-manager.io/v1")) }}
|
||||
{{- fail "edge.ingress.tls.mode is certManager, but cert-manager is not installed. Install cert-manager, or set edge.ingress.tls.mode to existingSecret or none, or set edge.expose to loadBalancer so the edge obtains its own certificate" }}
|
||||
{{- end }}
|
||||
{{- if and (eq $v.edge.expose "gateway") (not (.Capabilities.APIVersions.Has "gateway.networking.k8s.io/v1")) }}
|
||||
{{- fail "edge.expose is gateway, but the Gateway API is not installed in the cluster" }}
|
||||
{{- end }}
|
||||
{{- $emptyClass := and (eq $v.edge.expose "loadBalancer") (not $v.edge.loadBalancer.persistence.storageClassName) }}
|
||||
{{- range $c := list $v.postgres $v.valkey $v.nats $v.meilisearch $v.seaweedfs }}
|
||||
{{- if and $c.enabled (not $c.persistence.storageClassName) }}
|
||||
{{- $emptyClass = true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if $emptyClass }}
|
||||
{{- $default := false }}
|
||||
{{- range (lookup "storage.k8s.io/v1" "StorageClass" "" "").items | default list }}
|
||||
{{- if eq (get (.metadata.annotations | default dict) "storageclass.kubernetes.io/is-default-class") "true" }}
|
||||
{{- $default = true }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if not $default }}
|
||||
{{- fail "The cluster has no default StorageClass, so the volumes would never bind. Install a storage provisioner and mark its class as default, or set persistence.storageClassName on postgres, valkey, nats, meilisearch and seaweedfs" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and (eq $v.edge.expose "ingress") (not $v.edge.ingress.className) }}
|
||||
{{- $classes := (lookup "networking.k8s.io/v1" "IngressClass" "" "").items | default list }}
|
||||
{{- if not $classes }}
|
||||
{{- fail "The cluster has no IngressClass, so nothing would serve the Ingress. Install an ingress controller, or set edge.expose to loadBalancer, gateway or none. Set clusterChecks to false if your controller serves an Ingress without a class" }}
|
||||
{{- end }}
|
||||
{{- $defaults := list }}
|
||||
{{- range $classes }}
|
||||
{{- if eq (get (.metadata.annotations | default dict) "ingressclass.kubernetes.io/is-default-class") "true" }}
|
||||
{{- $defaults = append $defaults .metadata.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if not $defaults }}
|
||||
{{- $names := list }}
|
||||
{{- range $classes }}
|
||||
{{- $names = append $names .metadata.name }}
|
||||
{{- end }}
|
||||
{{- fail (printf "The cluster has no default IngressClass. Set edge.ingress.className to one of: %s" (join ", " $names)) }}
|
||||
{{- end }}
|
||||
{{- if gt (len $defaults) 1 }}
|
||||
{{- fail (printf "The cluster marks more than one IngressClass as default (%s), so the Ingress may land on the wrong controller. Set edge.ingress.className" (join ", " $defaults)) }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,188 @@
|
||||
{{- define "fluxer.replicas" -}}
|
||||
{{- $w := .w | default dict }}
|
||||
{{- if kindIs "invalid" $w.replicas }}1{{ else }}{{ $w.replicas | int }}{{ end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.appPod" -}}
|
||||
{{- $root := .root }}
|
||||
{{- $w := .w | default dict }}
|
||||
{{- $readsSecret := and (not .noEnvFrom) (not .configMapOnly) }}
|
||||
{{- $env := .env | default list }}
|
||||
{{- if and $readsSecret $root.Values.valkey.enabled }}
|
||||
{{- $env = prepend $env (dict "name" "FLUXER_KV_URL" "value" "redis://:$(FLUXER_VALKEY_PASSWORD)@valkey:6379/0") }}
|
||||
{{- end }}
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" . | nindent 4 }}
|
||||
annotations:
|
||||
checksum/instance: {{ include "fluxer.instanceChecksum" $root }}
|
||||
{{- with $w.podAnnotations }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" $root | nindent 2 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict) | nindent 4 }}
|
||||
{{- include "fluxer.scheduling" . | nindent 2 }}
|
||||
{{- with $w.terminationGracePeriodSeconds }}
|
||||
terminationGracePeriodSeconds: {{ . }}
|
||||
{{- end }}
|
||||
{{- include "fluxer.waitFor" . | nindent 2 }}
|
||||
containers:
|
||||
- name: {{ .containerName | default .name }}
|
||||
image: {{ include "fluxer.image" . }}
|
||||
imagePullPolicy: {{ include "fluxer.pullPolicy" . }}
|
||||
{{- with .command }}
|
||||
command:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with include "fluxer.envList" (dict "w" $w "env" $env) }}
|
||||
env:
|
||||
{{- . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if not .noEnvFrom }}
|
||||
envFrom:
|
||||
{{- if .configMapOnly }}
|
||||
- configMapRef:
|
||||
name: {{ .configMapOnly }}
|
||||
{{- else }}
|
||||
- configMapRef:
|
||||
name: fluxer-config
|
||||
- secretRef:
|
||||
name: {{ include "fluxer.secretName" $root }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .port }}
|
||||
protocol: TCP
|
||||
{{- range .extraPorts }}
|
||||
- name: {{ .name }}
|
||||
containerPort: {{ .port }}
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- with include "fluxer.probes" . | trim }}
|
||||
{{- . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- with .lifecycle }}
|
||||
lifecycle:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with $w.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 8 }}
|
||||
{{- with concat (.volumeMounts | default list) ($w.extraVolumeMounts | default list) }}
|
||||
volumeMounts:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with concat (.volumes | default list) ($w.extraVolumes | default list) }}
|
||||
volumes:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.app" -}}
|
||||
{{- $root := .root }}
|
||||
{{- $w := .w | default dict }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: {{ .kind | default "Deployment" }}
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ $root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if not (and $w.hpa $w.hpa.maxReplicas) }}
|
||||
replicas: {{ include "fluxer.replicas" . }}
|
||||
{{- end }}
|
||||
revisionHistoryLimit: 3
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" . | nindent 6 }}
|
||||
{{- if eq (.kind | default "Deployment") "StatefulSet" }}
|
||||
serviceName: {{ .serviceName }}
|
||||
podManagementPolicy: Parallel
|
||||
{{- else if .strategy }}
|
||||
strategy:
|
||||
{{- toYaml .strategy | nindent 4 }}
|
||||
{{- end }}
|
||||
template:
|
||||
{{- include "fluxer.appPod" . | nindent 4 }}
|
||||
{{- if not .noService }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ .name }}
|
||||
namespace: {{ $root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" . | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
{{- if .headless }}
|
||||
clusterIP: None
|
||||
publishNotReadyAddresses: true
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" . | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .servicePort | default .port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- end }}
|
||||
{{- with $w.pdb }}
|
||||
{{- if or (not (kindIs "invalid" .minAvailable)) (not (kindIs "invalid" .maxUnavailable)) }}
|
||||
---
|
||||
apiVersion: policy/v1
|
||||
kind: PodDisruptionBudget
|
||||
metadata:
|
||||
name: {{ $.name }}
|
||||
namespace: {{ $root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
{{- if not (kindIs "invalid" .minAvailable) }}
|
||||
minAvailable: {{ .minAvailable }}
|
||||
{{- end }}
|
||||
{{- if not (kindIs "invalid" .maxUnavailable) }}
|
||||
maxUnavailable: {{ .maxUnavailable }}
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with $w.hpa }}
|
||||
{{- if .maxReplicas }}
|
||||
---
|
||||
apiVersion: autoscaling/v2
|
||||
kind: HorizontalPodAutoscaler
|
||||
metadata:
|
||||
name: {{ $.name }}
|
||||
namespace: {{ $root.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ | nindent 4 }}
|
||||
spec:
|
||||
scaleTargetRef:
|
||||
apiVersion: apps/v1
|
||||
kind: {{ $.kind | default "Deployment" }}
|
||||
name: {{ $.name }}
|
||||
minReplicas: {{ .minReplicas | default 1 }}
|
||||
maxReplicas: {{ .maxReplicas }}
|
||||
metrics:
|
||||
- type: Resource
|
||||
resource:
|
||||
name: cpu
|
||||
target:
|
||||
type: Utilization
|
||||
averageUtilization: {{ .targetCPUUtilizationPercentage | default 80 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,90 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- $v := .Values }}
|
||||
{{- $o := include "fluxer.origin" . }}
|
||||
{{- $http := dict "port" "http" }}
|
||||
{{- $start := dict "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 30 }}
|
||||
{{- $check := dict "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 3 }}
|
||||
{{- $health := merge (dict "path" "/_health") $http }}
|
||||
{{- $healthProbes := dict "startup" (merge (dict "httpGet" $health) $start) "liveness" (merge (dict "httpGet" $health) $check) "readiness" (merge (dict "httpGet" $health) $check) }}
|
||||
{{- $nodeEnv := list (dict "name" "NODE_ENV" "value" "production") (dict "name" "NODE_OPTIONS" "value" "--enable-source-maps") (dict "name" "NODE_EXTRA_CA_CERTS" "value" "/etc/ssl/certs/ca-certificates.crt") (dict "name" "FLUXER_POSTGRES_MAX_CONNECTIONS" "value" "25") }}
|
||||
|
||||
{{- include "fluxer.app" (dict "root" . "name" "api" "component" "api" "w" $v.api "image" "fluxer-api" "port" 8080
|
||||
"env" (concat (list (dict "name" "FLUXER_API_PORT" "value" "8080") (dict "name" "FLUXER_API_PRESIGNED_ATTACHMENT_UPLOADS_ENABLED" "value" "true")) $nodeEnv)
|
||||
"probes" $healthProbes
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" . "usesNats" true "usesPostgres" true "usesS3" true "usesKv" true "usesSvc" true) | fromJsonArray)) }}
|
||||
|
||||
{{- $heartbeat := dict "exec" (dict "command" (list "node" "-e" "const age=Date.now()-require('node:fs').statSync('/tmp/fluxer-worker-heartbeat').mtimeMs;if(age>30000){console.error('worker heartbeat is '+Math.round(age)+'ms old');process.exit(1)}")) "initialDelaySeconds" 90 "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 3 }}
|
||||
{{- include "fluxer.app" (dict "root" . "name" "worker" "component" "worker" "w" $v.worker "image" "fluxer-api" "port" 8080 "noService" true
|
||||
"command" (list "node" "dist/WorkerEntrypoint.js")
|
||||
"env" (concat (list (dict "name" "FLUXER_API_WORKER_MODE" "value" "all_lanes") (dict "name" "FLUXER_API_WORKER_ENABLE_CRON_SCHEDULER" "value" "true")) $nodeEnv)
|
||||
"probes" (dict "liveness" $heartbeat)
|
||||
"strategy" (dict "type" "Recreate")
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" . "usesNats" true "usesPostgres" true "usesS3" true "usesKv" true "usesSvc" true) | fromJsonArray)) }}
|
||||
|
||||
{{- $gatewayEnv := list
|
||||
(dict "name" "FLUXER_GATEWAY_PORT" "value" "8080")
|
||||
(dict "name" "FLUXER_GATEWAY_ROLE" "value" "all")
|
||||
(dict "name" "POD_IP" "valueFrom" (dict "fieldRef" (dict "apiVersion" "v1" "fieldPath" "status.podIP")))
|
||||
(dict "name" "FLUXER_ERLANG_NODE_NAME" "value" "fluxer_gateway@$(POD_IP)")
|
||||
(dict "name" "FLUXER_ERLANG_DIST_PORT" "value" "8081")
|
||||
(dict "name" "FLUXER_GATEWAY_CLUSTER_ENABLED" "value" "true")
|
||||
(dict "name" "FLUXER_GATEWAY_CLUSTER_DISCOVERY_DNS_NAME" "value" (printf "gateway-headless.%s.svc.%s" .Release.Namespace $v.clusterDomain))
|
||||
(dict "name" "FLUXER_GATEWAY_CLUSTER_DISCOVERY_NODE_BASENAME" "value" "fluxer_gateway") }}
|
||||
{{- $gatewayReady := dict "exec" (dict "command" (list "curl" "-fsS" "-o" "/dev/null" "--max-time" "4" "http://127.0.0.1:8080/_health/ready")) "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 3 }}
|
||||
{{- $gatewayCtx := dict "root" . "name" "gateway" "component" "gateway" "w" $v.gateway "image" "fluxer-gateway" "port" 8080
|
||||
"extraPorts" (list (dict "name" "epmd" "port" 4369) (dict "name" "erl-dist" "port" 8081))
|
||||
"env" $gatewayEnv
|
||||
"probes" (dict "startup" (merge (dict "httpGet" $health) $start) "liveness" (merge (dict "httpGet" $health) $check) "readiness" $gatewayReady)
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" . "usesNats" true) | fromJsonArray)
|
||||
"lifecycle" (dict "preStop" (dict "exec" (dict "command" (list "/bin/sh" "-c" "curl -fsS -o /dev/null --max-time 2 http://127.0.0.1:8080/_health/drain; sleep 5")))) }}
|
||||
{{- include "fluxer.app" $gatewayCtx }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: gateway-headless
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $gatewayCtx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
clusterIP: None
|
||||
publishNotReadyAddresses: true
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $gatewayCtx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
- name: epmd
|
||||
port: 4369
|
||||
targetPort: epmd
|
||||
protocol: TCP
|
||||
- name: erl-dist
|
||||
port: 8081
|
||||
targetPort: erl-dist
|
||||
protocol: TCP
|
||||
|
||||
{{- include "fluxer.app" (dict "root" . "name" "media-proxy" "component" "media" "w" $v.mediaProxy "image" "fluxer-media-proxy" "port" 8080
|
||||
"env" (list (dict "name" "FLUXER_MEDIA_PROXY_PORT" "value" "8080") (dict "name" "FLUXER_MEDIA_PROXY_MODE" "value" "upload") (dict "name" "FLUXER_MEDIA_PROXY_STORAGE_BACKEND" "value" "s3") (dict "name" "FLUXER_S3_READ_SIGNED" "value" "true"))
|
||||
"probes" $healthProbes
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" . "usesNats" true "usesS3" true) | fromJsonArray)) }}
|
||||
|
||||
{{- $pushCheck := dict "exec" (dict "command" (list "/usr/local/bin/fluxer-push" "healthcheck")) }}
|
||||
{{- include "fluxer.app" (dict "root" . "name" "push" "component" "push" "w" $v.push "image" "fluxer-push" "port" 8126
|
||||
"env" (list (dict "name" "FLUXER_PUSH_SERVICE_PORT" "value" "8126"))
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" . "usesNats" true) | fromJsonArray)
|
||||
"probes" (dict "startup" (merge (deepCopy $pushCheck) (dict "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 12)) "liveness" (merge (deepCopy $pushCheck) $check) "readiness" (merge (deepCopy $pushCheck) $check))) }}
|
||||
|
||||
{{- include "fluxer.app" (dict "root" . "name" "admin" "component" "admin" "w" $v.admin "image" "fluxer-admin" "port" 8080
|
||||
"env" (list (dict "name" "FLUXER_ADMIN_PORT" "value" "8080") (dict "name" "FLUXER_ADMIN_BASE_PATH" "value" $v.adminBasePath) (dict "name" "FLUXER_API_ENDPOINT" "value" "http://api:8080") (dict "name" "FLUXER_STATIC_CDN_ENDPOINT" "value" $o))
|
||||
"probes" $healthProbes) }}
|
||||
|
||||
{{- $ready := merge (dict "path" "/_ready") $http }}
|
||||
{{- include "fluxer.app" (dict "root" . "name" "app-proxy" "component" "web" "w" $v.appProxy "image" "fluxer-app-proxy-self-hosted" "port" 8080 "configMapOnly" "fluxer-app-proxy"
|
||||
"probes" (dict "startup" (merge (dict "httpGet" $health) $start) "liveness" (merge (dict "httpGet" $health) $check) "readiness" (merge (dict "httpGet" $ready) $check))) }}
|
||||
|
||||
{{- $avatar := merge (dict "path" "/avatars/0.png") $http }}
|
||||
{{- include "fluxer.app" (dict "root" . "name" "static-proxy" "component" "web" "w" $v.staticProxy "image" "fluxer-static" "port" 8080 "noEnvFrom" true
|
||||
"probes" (dict "startup" (merge (dict "httpGet" $avatar) $start) "liveness" (merge (dict "httpGet" $avatar) $check) "readiness" (merge (dict "httpGet" $avatar) $check))) }}
|
||||
@@ -0,0 +1,20 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: fluxer-config
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer-config" "component" "config") | nindent 4 }}
|
||||
data:
|
||||
{{- include "fluxer.configData" . | nindent 2 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: fluxer-app-proxy
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer-app-proxy" "component" "config") | nindent 4 }}
|
||||
data:
|
||||
{{- include "fluxer.appProxyConfigData" . | nindent 2 }}
|
||||
@@ -0,0 +1,296 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- $v := .Values }}
|
||||
{{- $e := $v.edge }}
|
||||
{{- $ctx := dict "root" . "name" "edge" "component" "edge" "w" $e }}
|
||||
{{- $lb := eq $e.expose "loadBalancer" }}
|
||||
{{- $caddyfile := .Files.Get "files/Caddyfile" }}
|
||||
{{- $globalOptions := ternary (printf "email %s" $v.email) "" (and $lb (ne $v.email "")) }}
|
||||
{{- $siteAddress := ternary (printf "https://%s, :8080" $v.domain) ":8080" $lb }}
|
||||
{{- $trusted := ternary "127.0.0.1/32" "private_ranges" $lb }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: edge-caddyfile
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
data:
|
||||
Caddyfile: {{ $caddyfile | quote }}
|
||||
{{- if $lb }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: PersistentVolumeClaim
|
||||
metadata:
|
||||
name: edge-data
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/resource-policy: keep
|
||||
spec:
|
||||
accessModes:
|
||||
- ReadWriteOnce
|
||||
{{- with $e.loadBalancer.persistence.storageClassName }}
|
||||
storageClassName: {{ . }}
|
||||
{{- end }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ $e.loadBalancer.persistence.size }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: edge
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ ternary 1 ($e.replicas | int) $lb }}
|
||||
revisionHistoryLimit: 3
|
||||
{{- if $lb }}
|
||||
strategy:
|
||||
type: Recreate
|
||||
{{- end }}
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
annotations:
|
||||
checksum/config: {{ printf "%s\n%s\n%s\n%s" $caddyfile $siteAddress $globalOptions (toJson (list $e.env $e.extraEnv)) | sha256sum }}
|
||||
{{- with $e.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" . | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 65532) | nindent 8 }}
|
||||
{{- if $lb }}
|
||||
sysctls:
|
||||
- name: net.ipv4.ip_unprivileged_port_start
|
||||
value: "0"
|
||||
{{- end }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
containers:
|
||||
- name: edge
|
||||
image: {{ include "fluxer.thirdPartyImage" $e.image }}
|
||||
imagePullPolicy: {{ $e.image.pullPolicy }}
|
||||
{{- $edgeEnv := list (dict "name" "FLUXER_EDGE_SITE_ADDRESS" "value" $siteAddress) (dict "name" "FLUXER_EDGE_TRUSTED_PROXIES" "value" $trusted) (dict "name" "FLUXER_EDGE_GLOBAL_OPTIONS" "value" $globalOptions) (dict "name" "FLUXER_ADMIN_BASE_PATH" "value" $v.adminBasePath) }}
|
||||
env:
|
||||
{{- include "fluxer.envList" (dict "w" $e "env" $edgeEnv) | nindent 12 }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
protocol: TCP
|
||||
{{- if $lb }}
|
||||
- name: public-http
|
||||
containerPort: 80
|
||||
protocol: TCP
|
||||
- name: public-https
|
||||
containerPort: 443
|
||||
protocol: TCP
|
||||
- name: public-quic
|
||||
containerPort: 443
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
startupProbe:
|
||||
exec:
|
||||
command: ["wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
|
||||
periodSeconds: 5
|
||||
failureThreshold: 24
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["wget", "-q", "-O", "/dev/null", "http://127.0.0.1:2019/config/"]
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
{{- with $e.resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop:
|
||||
- ALL
|
||||
add:
|
||||
- NET_BIND_SERVICE
|
||||
volumeMounts:
|
||||
- name: caddyfile
|
||||
mountPath: /etc/caddy
|
||||
readOnly: true
|
||||
- name: config
|
||||
mountPath: /config
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: caddyfile
|
||||
configMap:
|
||||
name: edge-caddyfile
|
||||
- name: config
|
||||
emptyDir: {}
|
||||
- name: data
|
||||
{{- if $lb }}
|
||||
persistentVolumeClaim:
|
||||
claimName: edge-data
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: edge
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 8080
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
{{- if $lb }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: edge-public
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
{{- with $e.loadBalancer.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: LoadBalancer
|
||||
externalTrafficPolicy: Local
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 80
|
||||
targetPort: public-http
|
||||
protocol: TCP
|
||||
- name: https
|
||||
port: 443
|
||||
targetPort: public-https
|
||||
protocol: TCP
|
||||
{{- if $e.loadBalancer.http3 }}
|
||||
- name: quic
|
||||
port: 443
|
||||
targetPort: public-quic
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq $e.expose "ingress" }}
|
||||
{{- $tls := $e.ingress.tls }}
|
||||
{{- $annotations := dict
|
||||
"nginx.ingress.kubernetes.io/proxy-body-size" "512m"
|
||||
"nginx.ingress.kubernetes.io/proxy-read-timeout" "3600"
|
||||
"nginx.ingress.kubernetes.io/proxy-send-timeout" "3600" }}
|
||||
{{- if eq $tls.mode "certManager" }}
|
||||
{{- $_ := set $annotations "cert-manager.io/issuer" "fluxer-acme" }}
|
||||
---
|
||||
apiVersion: cert-manager.io/v1
|
||||
kind: Issuer
|
||||
metadata:
|
||||
name: fluxer-acme
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
acme:
|
||||
server: {{ $tls.acmeServer }}
|
||||
{{- with $v.email }}
|
||||
email: {{ . }}
|
||||
{{- end }}
|
||||
privateKeySecretRef:
|
||||
name: fluxer-acme-account
|
||||
solvers:
|
||||
- http01:
|
||||
{{- with $e.ingress.className }}
|
||||
ingress:
|
||||
ingressClassName: {{ . }}
|
||||
{{- else }}
|
||||
ingress: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- $annotations = merge (deepCopy ($e.ingress.annotations | default dict)) $annotations }}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: fluxer
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
{{- with $annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
{{- with $e.ingress.className }}
|
||||
ingressClassName: {{ . }}
|
||||
{{- end }}
|
||||
{{- if ne $tls.mode "none" }}
|
||||
tls:
|
||||
- hosts:
|
||||
- {{ $v.domain }}
|
||||
secretName: {{ $tls.secretName }}
|
||||
{{- end }}
|
||||
rules:
|
||||
- host: {{ $v.domain }}
|
||||
http:
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: edge
|
||||
port:
|
||||
name: http
|
||||
{{- end }}
|
||||
{{- if eq $e.expose "gateway" }}
|
||||
---
|
||||
apiVersion: gateway.networking.k8s.io/v1
|
||||
kind: HTTPRoute
|
||||
metadata:
|
||||
name: fluxer
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
parentRefs:
|
||||
{{- toYaml $e.gateway.parentRefs | nindent 4 }}
|
||||
hostnames:
|
||||
- {{ $v.domain }}
|
||||
rules:
|
||||
- matches:
|
||||
- path:
|
||||
type: PathPrefix
|
||||
value: /
|
||||
backendRefs:
|
||||
- name: edge
|
||||
port: 8080
|
||||
{{- with $e.gateway.timeouts }}
|
||||
timeouts:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,156 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- with .Values.livekit }}
|
||||
{{- if .enabled }}
|
||||
{{- $ctx := dict "root" $ "name" "livekit" "component" "voice" "w" . }}
|
||||
{{- $tcp := .tcpPort | int }}
|
||||
{{- $udp := .udpPort | int }}
|
||||
{{- if eq .expose "nodePort" }}
|
||||
{{- $tcp = .nodePorts.tcp | int }}
|
||||
{{- $udp = .nodePorts.udp | int }}
|
||||
{{- end }}
|
||||
{{- $useExternal := and .useExternalIP (ne .expose "loadBalancer") }}
|
||||
{{- $secrets := include "fluxer.secretData" $ | fromJson }}
|
||||
{{- $config := dict
|
||||
"port" 7880
|
||||
"log_level" .logLevel
|
||||
"rtc" (dict "tcp_port" $tcp "udp_port" $udp "use_external_ip" $useExternal "node_ip" (.nodeIP | default "") "stun_servers" .stunServers) }}
|
||||
{{- $config = mergeOverwrite $config (deepCopy (.extraConfig | default dict)) }}
|
||||
{{- $configYaml := toYaml $config }}
|
||||
{{- $root := dict "path" "/" "port" "http" }}
|
||||
{{- $webhook := ternary "http://edge:8080/api/webhooks/livekit" "http://api:8080/webhooks/livekit" (eq .expose "hostNetwork") }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: livekit
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 7880
|
||||
targetPort: 7880
|
||||
protocol: TCP
|
||||
{{- if ne .expose "hostNetwork" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: livekit-rtc
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
{{- with .serviceAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
type: {{ ternary "LoadBalancer" "NodePort" (eq .expose "loadBalancer") }}
|
||||
externalTrafficPolicy: Local
|
||||
{{- if and (eq .expose "loadBalancer") .loadBalancerIP }}
|
||||
loadBalancerIP: {{ .loadBalancerIP }}
|
||||
{{- end }}
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: rtc-tcp
|
||||
port: {{ $tcp }}
|
||||
targetPort: rtc-tcp
|
||||
protocol: TCP
|
||||
{{- if eq .expose "nodePort" }}
|
||||
nodePort: {{ $tcp }}
|
||||
{{- end }}
|
||||
- name: rtc-udp
|
||||
port: {{ $udp }}
|
||||
targetPort: rtc-udp
|
||||
protocol: UDP
|
||||
{{- if eq .expose "nodePort" }}
|
||||
nodePort: {{ $udp }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: livekit
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
revisionHistoryLimit: 3
|
||||
strategy:
|
||||
type: Recreate
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
annotations:
|
||||
checksum/config: {{ list $configYaml $webhook (get $secrets "FLUXER_LIVEKIT_API_KEY" | default "") (get $secrets "FLUXER_LIVEKIT_API_SECRET" | default "") | toJson | sha256sum }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- if eq .expose "hostNetwork" }}
|
||||
hostNetwork: true
|
||||
dnsPolicy: ClusterFirstWithHostNet
|
||||
{{- end }}
|
||||
{{- include "fluxer.pullSecrets" $ | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 65532) | nindent 8 }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
containers:
|
||||
- name: livekit
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- |
|
||||
export LIVEKIT_KEYS="${LIVEKIT_API_KEY}: ${LIVEKIT_API_SECRET}"
|
||||
export LIVEKIT_CONFIG="$(printf '%s\nwebhook:\n api_key: %s\n urls:\n - %s\n' "$LIVEKIT_CONFIG" "$LIVEKIT_API_KEY" "$LIVEKIT_WEBHOOK_URL")"
|
||||
exec /livekit-server
|
||||
env:
|
||||
- name: LIVEKIT_CONFIG
|
||||
value: {{ $configYaml | quote }}
|
||||
- name: LIVEKIT_WEBHOOK_URL
|
||||
value: {{ $webhook }}
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "LIVEKIT_API_KEY" "key" "FLUXER_LIVEKIT_API_KEY") | nindent 12 }}
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "LIVEKIT_API_SECRET" "key" "FLUXER_LIVEKIT_API_SECRET") | nindent 12 }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 7880
|
||||
protocol: TCP
|
||||
- name: rtc-tcp
|
||||
containerPort: {{ $tcp }}
|
||||
protocol: TCP
|
||||
- name: rtc-udp
|
||||
containerPort: {{ $udp }}
|
||||
protocol: UDP
|
||||
startupProbe:
|
||||
httpGet: {{ toJson $root }}
|
||||
periodSeconds: 5
|
||||
failureThreshold: 60
|
||||
livenessProbe:
|
||||
httpGet: {{ toJson $root }}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
readinessProbe:
|
||||
httpGet: {{ toJson $root }}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
{{- with .resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,97 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- with .Values.meilisearch }}
|
||||
{{- if .enabled }}
|
||||
{{- $ctx := dict "root" $ "name" "meilisearch" "component" "search" "w" . }}
|
||||
{{- $health := dict "path" "/health" "port" "http" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: meilisearch
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: http
|
||||
port: 7700
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: meilisearch
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: meilisearch
|
||||
podManagementPolicy: Parallel
|
||||
persistentVolumeClaimRetentionPolicy:
|
||||
whenDeleted: Retain
|
||||
whenScaled: Retain
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" $ | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 65532) | nindent 8 }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
containers:
|
||||
- name: meilisearch
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
env:
|
||||
- name: MEILI_ENV
|
||||
value: production
|
||||
- name: MEILI_NO_ANALYTICS
|
||||
value: "true"
|
||||
- name: MEILI_UPGRADE_DB
|
||||
value: "true"
|
||||
- name: MEILI_MAX_INDEXING_MEMORY
|
||||
value: {{ .maxIndexingMemory | quote }}
|
||||
- name: MEILI_MAX_INDEXING_THREADS
|
||||
value: {{ include "fluxer.string" .maxIndexingThreads | quote }}
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "MEILI_MASTER_KEY" "key" "FLUXER_SEARCH_API_KEY") | nindent 12 }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 7700
|
||||
protocol: TCP
|
||||
startupProbe:
|
||||
httpGet: {{ toJson $health }}
|
||||
periodSeconds: 5
|
||||
failureThreshold: 120
|
||||
livenessProbe:
|
||||
httpGet: {{ toJson $health }}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
readinessProbe:
|
||||
httpGet: {{ toJson $health }}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
{{- with .resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /meili_data
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer.pvc" .persistence | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,169 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- with .Values.nats }}
|
||||
{{- if .enabled }}
|
||||
{{- $ctx := dict "root" $ "name" "nats" "component" "messaging" "w" . }}
|
||||
{{- $replicas := .replicas | int }}
|
||||
{{- $conf := include "fluxer.natsConf" (dict "root" $ "replicas" $replicas) }}
|
||||
{{- $secrets := include "fluxer.secretData" $ | fromJson }}
|
||||
{{- $healthz := dict "exec" (dict "command" (list "wget" "-q" "-O" "/dev/null" "http://127.0.0.1:8222/healthz")) }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: nats-config
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
data:
|
||||
nats.conf: {{ $conf | quote }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nats
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: client
|
||||
port: 4222
|
||||
targetPort: client
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: nats-headless
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
clusterIP: None
|
||||
publishNotReadyAddresses: true
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: client
|
||||
port: 4222
|
||||
targetPort: client
|
||||
protocol: TCP
|
||||
- name: cluster
|
||||
port: 6222
|
||||
targetPort: cluster
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: nats
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: {{ $replicas }}
|
||||
serviceName: nats-headless
|
||||
podManagementPolicy: Parallel
|
||||
persistentVolumeClaimRetentionPolicy:
|
||||
whenDeleted: Retain
|
||||
whenScaled: Retain
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
annotations:
|
||||
checksum/config: {{ printf "%s\n%s" $conf (get $secrets "FLUXER_NATS_AUTH_TOKEN" | default "") | sha256sum }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" $ | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 65534) | nindent 8 }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
containers:
|
||||
- name: nats
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- sed "s/__FLUXER_NATS_AUTH_TOKEN__/$FLUXER_NATS_AUTH_TOKEN/g" /etc/nats/nats.conf > /run/nats/nats.conf && exec nats-server --config /run/nats/nats.conf
|
||||
env:
|
||||
- name: POD_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
apiVersion: v1
|
||||
fieldPath: metadata.name
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "FLUXER_NATS_AUTH_TOKEN" "key" "FLUXER_NATS_AUTH_TOKEN") | nindent 12 }}
|
||||
ports:
|
||||
- name: client
|
||||
containerPort: 4222
|
||||
protocol: TCP
|
||||
- name: cluster
|
||||
containerPort: 6222
|
||||
protocol: TCP
|
||||
startupProbe:
|
||||
{{- toYaml (merge (dict "periodSeconds" 5 "timeoutSeconds" 5 "failureThreshold" 60) $healthz) | nindent 12 }}
|
||||
livenessProbe:
|
||||
{{- toYaml (merge (dict "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 6) $healthz) | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml (merge (dict "periodSeconds" 10 "timeoutSeconds" 5) $healthz) | nindent 12 }}
|
||||
{{- with .resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: config
|
||||
mountPath: /etc/nats
|
||||
readOnly: true
|
||||
- name: rendered
|
||||
mountPath: /run/nats
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: config
|
||||
configMap:
|
||||
name: nats-config
|
||||
- name: rendered
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer.pvc" .persistence | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "fluxer.natsConf" -}}
|
||||
server_name: $POD_NAME
|
||||
listen: 0.0.0.0:4222
|
||||
http: 127.0.0.1:8222
|
||||
authorization {
|
||||
token: "__FLUXER_NATS_AUTH_TOKEN__"
|
||||
}
|
||||
jetstream {
|
||||
store_dir: /data
|
||||
}
|
||||
{{- if gt .replicas 1 }}
|
||||
cluster {
|
||||
name: fluxer
|
||||
listen: 0.0.0.0:6222
|
||||
authorization {
|
||||
user: fluxer
|
||||
password: "__FLUXER_NATS_AUTH_TOKEN__"
|
||||
}
|
||||
routes: [
|
||||
{{- range $i := until .replicas }}
|
||||
nats://fluxer:__FLUXER_NATS_AUTH_TOKEN__@nats-{{ $i }}.nats-headless.{{ $.root.Release.Namespace }}.svc.{{ $.root.Values.clusterDomain }}:6222
|
||||
{{- end }}
|
||||
]
|
||||
}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,83 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- if .Values.networkPolicy.enabled }}
|
||||
{{- $v := .Values }}
|
||||
{{- $release := dict "app.kubernetes.io/instance" .Release.Name }}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: fluxer
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer" "component" "network") | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- toYaml $release | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- from:
|
||||
- podSelector:
|
||||
matchLabels:
|
||||
{{- toYaml $release | nindent 14 }}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: fluxer-edge
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer-edge" "component" "network") | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" (dict "root" . "name" "edge") | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- ports:
|
||||
- port: 8080
|
||||
protocol: TCP
|
||||
{{- with $v.networkPolicy.ingressNamespaceSelector }}
|
||||
from:
|
||||
- namespaceSelector:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- if and $v.livekit.enabled (eq $v.livekit.expose "hostNetwork") }}
|
||||
{{- range $v.livekit.nodeCIDRs }}
|
||||
- ipBlock:
|
||||
cidr: {{ . }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if eq $v.edge.expose "loadBalancer" }}
|
||||
- ports:
|
||||
- port: 80
|
||||
protocol: TCP
|
||||
- port: 443
|
||||
protocol: TCP
|
||||
- port: 443
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
{{- if and $v.livekit.enabled (ne $v.livekit.expose "hostNetwork") }}
|
||||
---
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: NetworkPolicy
|
||||
metadata:
|
||||
name: fluxer-livekit
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer-livekit" "component" "network") | nindent 4 }}
|
||||
spec:
|
||||
podSelector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" (dict "root" . "name" "livekit") | nindent 6 }}
|
||||
policyTypes:
|
||||
- Ingress
|
||||
ingress:
|
||||
- ports:
|
||||
- port: {{ ternary $v.livekit.nodePorts.tcp $v.livekit.tcpPort (eq $v.livekit.expose "nodePort") }}
|
||||
protocol: TCP
|
||||
- port: {{ ternary $v.livekit.nodePorts.udp $v.livekit.udpPort (eq $v.livekit.expose "nodePort") }}
|
||||
protocol: UDP
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,147 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- with .Values.postgres }}
|
||||
{{- if .enabled }}
|
||||
{{- $ctx := dict "root" $ "name" "postgres" "component" "database" "w" . }}
|
||||
{{- $args := list }}
|
||||
{{- range $k := keys .parameters | sortAlpha }}
|
||||
{{- $args = concat $args (list "-c" (printf "%s=%s" $k (include "fluxer.string" (get $.Values.postgres.parameters $k)))) }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: postgres
|
||||
port: 5432
|
||||
targetPort: postgres
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: postgres
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: postgres
|
||||
podManagementPolicy: Parallel
|
||||
persistentVolumeClaimRetentionPolicy:
|
||||
whenDeleted: Retain
|
||||
whenScaled: Retain
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
annotations:
|
||||
checksum/config: {{ toJson $args | sha256sum }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
terminationGracePeriodSeconds: 60
|
||||
{{- include "fluxer.pullSecrets" $ | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" (.runAsUser | int)) | nindent 8 }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
initContainers:
|
||||
- name: version-guard
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
want=$(postgres --version | sed -E 's/[^0-9]*([0-9]+).*/\1/')
|
||||
if [ -s "$PGDATA/PG_VERSION" ]; then
|
||||
have=$(cat "$PGDATA/PG_VERSION")
|
||||
if [ "$have" != "$want" ]; then
|
||||
echo "The data directory was created by Postgres $have and this image runs Postgres $want. Set postgres.image.tag back to the $have image, or dump the database and restore it into a fresh volume. See the Kubernetes page of the operator docs." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
env:
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 16Mi
|
||||
limits:
|
||||
memory: 64Mi
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
containers:
|
||||
- name: postgres
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
args:
|
||||
{{- toYaml $args | nindent 12 }}
|
||||
env:
|
||||
- name: PGDATA
|
||||
value: /var/lib/postgresql/data/pgdata
|
||||
- name: POSTGRES_DB
|
||||
value: {{ .database | quote }}
|
||||
- name: POSTGRES_USER
|
||||
value: {{ .username | quote }}
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "POSTGRES_PASSWORD" "key" "FLUXER_POSTGRES_PASSWORD") | nindent 12 }}
|
||||
ports:
|
||||
- name: postgres
|
||||
containerPort: 5432
|
||||
protocol: TCP
|
||||
startupProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", "pg_isready -U \"$POSTGRES_USER\" -d \"$POSTGRES_DB\""]
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 30
|
||||
livenessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", "pg_isready -U \"$POSTGRES_USER\" -d \"$POSTGRES_DB\""]
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["sh", "-c", "pg_isready -U \"$POSTGRES_USER\" -d \"$POSTGRES_DB\""]
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
{{- with .resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /var/lib/postgresql/data
|
||||
- name: shm
|
||||
mountPath: /dev/shm
|
||||
- name: run
|
||||
mountPath: /var/run/postgresql
|
||||
volumes:
|
||||
- name: shm
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
sizeLimit: {{ .shmSize }}
|
||||
- name: run
|
||||
emptyDir: {}
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer.pvc" .persistence | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,136 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- with .Values.seaweedfs }}
|
||||
{{- if .enabled }}
|
||||
{{- $ctx := dict "root" $ "name" "seaweedfs" "component" "storage" "w" . }}
|
||||
{{- $healthz := dict "path" "/healthz" "port" "s3" }}
|
||||
{{- $secrets := include "fluxer.secretData" $ | fromJson }}
|
||||
{{- $init := $.Files.Get "files/seaweedfs-init.sh" }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: seaweedfs
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: s3
|
||||
port: 8333
|
||||
targetPort: s3
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: seaweedfs
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: seaweedfs
|
||||
podManagementPolicy: Parallel
|
||||
persistentVolumeClaimRetentionPolicy:
|
||||
whenDeleted: Retain
|
||||
whenScaled: Retain
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
annotations:
|
||||
checksum/init: {{ list $init (get $secrets "FLUXER_S3_ACCESS_KEY_ID" | default "") (get $secrets "FLUXER_S3_SECRET_ACCESS_KEY" | default "") $.Values.s3.buckets | toJson | sha256sum }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" $ | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 1000) | nindent 8 }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
containers:
|
||||
- name: seaweedfs
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
args:
|
||||
- server
|
||||
- -s3
|
||||
- -dir=/data
|
||||
- -master.telemetry=false
|
||||
- -ip=127.0.0.1
|
||||
- -ip.bind=127.0.0.1
|
||||
- -s3.ip.bind=0.0.0.0
|
||||
env:
|
||||
- name: GOMEMLIMIT
|
||||
value: {{ .gomemlimit | quote }}
|
||||
- name: WEED_MASTER_VOLUME_GROWTH_COPY_1
|
||||
value: {{ include "fluxer.string" .volumeGrowth | quote }}
|
||||
ports:
|
||||
- name: s3
|
||||
containerPort: 8333
|
||||
protocol: TCP
|
||||
startupProbe:
|
||||
httpGet: {{ toJson $healthz }}
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 24
|
||||
livenessProbe:
|
||||
httpGet: {{ toJson $healthz }}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 6
|
||||
readinessProbe:
|
||||
httpGet: {{ toJson $healthz }}
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
{{- with .resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
- name: seaweedfs-init
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
command:
|
||||
- /bin/sh
|
||||
- -c
|
||||
- {{ $init | quote }}
|
||||
env:
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "FLUXER_S3_ACCESS_KEY" "key" "FLUXER_S3_ACCESS_KEY_ID") | nindent 12 }}
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "FLUXER_S3_SECRET_KEY" "key" "FLUXER_S3_SECRET_ACCESS_KEY") | nindent 12 }}
|
||||
- name: FLUXER_S3_BUCKET_CDN
|
||||
value: {{ $.Values.s3.buckets.cdn | quote }}
|
||||
- name: FLUXER_S3_BUCKET_UPLOADS
|
||||
value: {{ $.Values.s3.buckets.uploads | quote }}
|
||||
- name: FLUXER_S3_BUCKET_REPORTS
|
||||
value: {{ $.Values.s3.buckets.reports | quote }}
|
||||
- name: FLUXER_S3_BUCKET_HARVESTS
|
||||
value: {{ $.Values.s3.buckets.harvests | quote }}
|
||||
- name: FLUXER_SEAWEEDFS_INIT_ATTEMPTS
|
||||
value: {{ include "fluxer.string" .initAttempts | quote }}
|
||||
readinessProbe:
|
||||
exec:
|
||||
command: ["test", "-f", "/tmp/fluxer-buckets-ready"]
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
memory: 128Mi
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer.pvc" .persistence | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,17 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- if not .Values.secrets.existingSecret }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: fluxer-env
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer-env" "component" "config") | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/resource-policy: keep
|
||||
type: Opaque
|
||||
data:
|
||||
{{- range $k, $val := include "fluxer.secretData" . | fromJson }}
|
||||
{{ $k }}: {{ $val | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,31 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- $healthz := dict "path" "/_healthz" "port" "http" }}
|
||||
{{- $health := dict "path" "/_health" "port" "http" }}
|
||||
{{- $probes := dict
|
||||
"startup" (dict "httpGet" $healthz "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 12)
|
||||
"liveness" (dict "httpGet" $healthz "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 3)
|
||||
"readiness" (dict "httpGet" $health "periodSeconds" 10 "timeoutSeconds" 5 "failureThreshold" 3) }}
|
||||
{{- range $name := list "gifs" "messages" "snowflakes" "unfurl" "users" }}
|
||||
{{- $svc := get $.Values.svc $name | default dict }}
|
||||
{{- $router := $svc.router | default dict }}
|
||||
{{- $shard := $svc.shard | default dict }}
|
||||
{{- $count := include "fluxer.replicas" (dict "w" $shard) }}
|
||||
{{- $common := list (dict "name" "FLUXER_SVC_NAME" "value" $name) (dict "name" "FLUXER_SVC_PORT" "value" "8090") (dict "name" "FLUXER_SVC_SHARD_COUNT" "value" $count) }}
|
||||
{{- $shardEnv := concat $common (list (dict "name" "FLUXER_SVC_MODE" "value" "shard") (dict "name" "FLUXER_SVC_SHARD_ID" "valueFrom" (dict "fieldRef" (dict "apiVersion" "v1" "fieldPath" "metadata.labels['apps.kubernetes.io/pod-index']"))) (dict "name" "POD_NAME" "valueFrom" (dict "fieldRef" (dict "apiVersion" "v1" "fieldPath" "metadata.name")))) }}
|
||||
{{- $usesPostgres := has $name (list "users" "messages") }}
|
||||
{{- if $usesPostgres }}
|
||||
{{- $shardEnv = append $shardEnv (dict "name" "FLUXER_POSTGRES_MAX_CONNECTIONS" "value" "20") }}
|
||||
{{- end }}
|
||||
{{- if eq $name "unfurl" }}
|
||||
{{- $shardEnv = append $shardEnv (dict "name" "FLUXER_MEDIA_PROXY_ENDPOINT" "value" "http://media-proxy:8080") }}
|
||||
{{- end }}
|
||||
{{- include "fluxer.app" (dict "root" $ "name" $name "component" "svc" "w" $router "image" (printf "fluxer-%s" $name) "port" 8090 "containerName" "router"
|
||||
"env" (append $common (dict "name" "FLUXER_SVC_MODE" "value" "router"))
|
||||
"probes" $probes
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" $ "usesNats" true) | fromJsonArray)) }}
|
||||
{{- include "fluxer.app" (dict "root" $ "name" (printf "%s-shard" $name) "component" "svc" "w" $shard "image" (printf "fluxer-%s" $name) "port" 8090 "containerName" "shard"
|
||||
"kind" "StatefulSet" "serviceName" (printf "%s-shard" $name) "headless" true
|
||||
"env" $shardEnv
|
||||
"probes" $probes
|
||||
"waitFor" (include "fluxer.appWaitFor" (dict "root" $ "usesNats" true "usesPostgres" $usesPostgres) | fromJsonArray)) }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,46 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: fluxer-test-edge
|
||||
namespace: {{ .Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" (dict "root" . "name" "fluxer-test" "component" "test") | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: test
|
||||
helm.sh/hook-delete-policy: before-hook-creation,hook-succeeded
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" . | nindent 2 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 65532) | nindent 4 }}
|
||||
containers:
|
||||
- name: check
|
||||
image: {{ include "fluxer.thirdPartyImage" .Values.edge.image }}
|
||||
imagePullPolicy: {{ .Values.edge.image.pullPolicy }}
|
||||
command:
|
||||
- sh
|
||||
- -c
|
||||
- |
|
||||
for i in $(seq 1 30); do
|
||||
if wget -q -O /dev/null http://edge:8080/_health && wget -q -O - --header "Host: $DOMAIN" http://edge:8080/.well-known/fluxer > /tmp/discovery && grep -q "$DOMAIN" /tmp/discovery; then
|
||||
echo "edge and discovery answer for $DOMAIN"
|
||||
exit 0
|
||||
fi
|
||||
sleep 2
|
||||
done
|
||||
echo "edge or discovery did not answer for $DOMAIN within 60 seconds" >&2
|
||||
exit 1
|
||||
env:
|
||||
- name: DOMAIN
|
||||
value: {{ .Values.domain | quote }}
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 16Mi
|
||||
limits:
|
||||
memory: 64Mi
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 8 }}
|
||||
@@ -0,0 +1,84 @@
|
||||
{{- include "fluxer.validate" . }}
|
||||
{{- with .Values.valkey }}
|
||||
{{- if .enabled }}
|
||||
{{- $ctx := dict "root" $ "name" "valkey" "component" "cache" "w" . }}
|
||||
{{- $args := list "valkey-server" "--appendonly" "yes" "--appendfsync" .appendfsync "--dir" "/data" "--maxmemory" .maxmemory "--maxmemory-policy" .maxmemoryPolicy "--requirepass" "$(REDISCLI_AUTH)" }}
|
||||
{{- $ping := dict "exec" (dict "command" (list "sh" "-c" "valkey-cli ping | grep -q PONG")) "periodSeconds" 10 "timeoutSeconds" 5 }}
|
||||
{{- $secrets := include "fluxer.secretData" $ | fromJson }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: valkey
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
selector:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 4 }}
|
||||
ports:
|
||||
- name: redis
|
||||
port: 6379
|
||||
targetPort: redis
|
||||
protocol: TCP
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: valkey
|
||||
namespace: {{ $.Release.Namespace }}
|
||||
labels:
|
||||
{{- include "fluxer.labels" $ctx | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: valkey
|
||||
podManagementPolicy: Parallel
|
||||
persistentVolumeClaimRetentionPolicy:
|
||||
whenDeleted: Retain
|
||||
whenScaled: Retain
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "fluxer.selectorLabels" $ctx | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "fluxer.podLabels" $ctx | nindent 8 }}
|
||||
annotations:
|
||||
checksum/config: {{ printf "%s\n%s" (toJson $args) (get $secrets "FLUXER_VALKEY_PASSWORD" | default "") | sha256sum }}
|
||||
spec:
|
||||
automountServiceAccountToken: false
|
||||
enableServiceLinks: false
|
||||
{{- include "fluxer.pullSecrets" $ | nindent 6 }}
|
||||
securityContext:
|
||||
{{- include "fluxer.podSecurityContext" (dict "uid" 999 "gid" 1000) | nindent 8 }}
|
||||
{{- include "fluxer.scheduling" $ctx | nindent 6 }}
|
||||
containers:
|
||||
- name: valkey
|
||||
image: {{ include "fluxer.thirdPartyImage" .image }}
|
||||
imagePullPolicy: {{ .image.pullPolicy }}
|
||||
command:
|
||||
{{- toYaml $args | nindent 12 }}
|
||||
env:
|
||||
{{- include "fluxer.secretEnv" (dict "root" $ "name" "REDISCLI_AUTH" "key" "FLUXER_VALKEY_PASSWORD") | nindent 12 }}
|
||||
ports:
|
||||
- name: redis
|
||||
containerPort: 6379
|
||||
protocol: TCP
|
||||
livenessProbe:
|
||||
{{- toYaml (merge (dict "failureThreshold" 6 "initialDelaySeconds" 10) $ping) | nindent 12 }}
|
||||
readinessProbe:
|
||||
{{- toYaml (merge (dict "failureThreshold" 3) $ping) | nindent 12 }}
|
||||
{{- with .resources }}
|
||||
resources:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
securityContext:
|
||||
{{- include "fluxer.containerSecurityContext" . | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumeClaimTemplates:
|
||||
{{- include "fluxer.pvc" .persistence | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,706 @@
|
||||
# The public hostname of the instance, lowercase, for example chat.example.com.
|
||||
# Required. Point DNS for it at your ingress controller or at the edge load balancer.
|
||||
domain: ""
|
||||
|
||||
# The scheme browsers use to reach the instance.
|
||||
scheme: https
|
||||
|
||||
# The port browsers use to reach the instance.
|
||||
port: 443
|
||||
|
||||
# The origin browsers see, with no trailing slash. Set it only when browsers
|
||||
# reach the instance on an origin that domain, scheme and port do not describe.
|
||||
# It wins over those three in every derived URL.
|
||||
publicOrigin: ""
|
||||
|
||||
# The path the admin panel is served under, with a leading slash and no
|
||||
# trailing slash.
|
||||
adminBasePath: /admin
|
||||
|
||||
# A contact address. It becomes FLUXER_VAPID_EMAIL for web push and the ACME
|
||||
# account email. Empty uses admin@<domain> for web push and no ACME email.
|
||||
email: ""
|
||||
|
||||
# The cluster DNS suffix, used in the gateway discovery name.
|
||||
clusterDomain: cluster.local
|
||||
|
||||
# Look up namespaces, StorageClasses, IngressClasses and installed APIs before
|
||||
# installing, to fail early on a cluster that cannot run the release. Set false
|
||||
# when your account cannot read those cluster-scoped objects.
|
||||
clusterChecks: true
|
||||
|
||||
image:
|
||||
# The registry and owner the Fluxer images come from.
|
||||
registry: ghcr.io/fluxerapp
|
||||
# The tag for every Fluxer image. v1 moves with each release.
|
||||
tag: v1
|
||||
# Always pulls the moving tag whenever a pod starts, including a pod that
|
||||
# restarts by itself. Pin with digests for rollouts you control.
|
||||
pullPolicy: Always
|
||||
# Per-image tag overrides, keyed by image name, for example fluxer-api: 2026.1012.120000.
|
||||
tags: {}
|
||||
# Per-image digests, keyed by image name, for example fluxer-api: sha256:0123.
|
||||
# A digest pins the image whatever the tag.
|
||||
digests: {}
|
||||
# Image pull secrets for every pod, as a list of {name: <secret>}.
|
||||
pullSecrets: []
|
||||
# Any new value restarts every Fluxer pod, which pulls the moving tag again.
|
||||
# Add --set-string image.revision=$(date +%s) to a helm upgrade that passes
|
||||
# your values file to move to the latest v1.
|
||||
revision: ""
|
||||
|
||||
# The image of the init container that waits for the backing services.
|
||||
initImage:
|
||||
repository: busybox
|
||||
tag: "1.37"
|
||||
# A digest pins the image whatever the tag.
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
secrets:
|
||||
# The name of a Secret you manage yourself. The chart then renders no Secret
|
||||
# and never changes this one. It needs every key listed under values below.
|
||||
# After editing it, run kubectl rollout restart for the deployments and
|
||||
# statefulsets of the release.
|
||||
existingSecret: ""
|
||||
# Generate every empty key below on first install and keep it on upgrade.
|
||||
# Set false under Argo CD or helm template, which cannot read the existing
|
||||
# Secret, and give every key here or use existingSecret.
|
||||
generate: true
|
||||
# Keys of the fluxer-env Secret. Empty means generate once, then keep.
|
||||
# Generated values are never rotated by an upgrade. Back up the Secret.
|
||||
values:
|
||||
# Password of the bundled Postgres role. Changing it after the first install
|
||||
# does not change the stored role password.
|
||||
FLUXER_POSTGRES_PASSWORD: ""
|
||||
# Meilisearch master key.
|
||||
FLUXER_SEARCH_API_KEY: ""
|
||||
# S3 access key id. The bundled store installs it on every upgrade.
|
||||
FLUXER_S3_ACCESS_KEY_ID: fluxer
|
||||
# S3 secret key. Letters and digits only for the bundled store.
|
||||
FLUXER_S3_SECRET_ACCESS_KEY: ""
|
||||
# Signs sudo mode tokens.
|
||||
FLUXER_SUDO_MODE_SECRET: ""
|
||||
# Signs connection initiation tokens.
|
||||
FLUXER_CONNECTION_INITIATION_SECRET: ""
|
||||
# Derives hidden profile names. Changing it renames every hidden profile.
|
||||
FLUXER_PROFILE_PSEUDONYM_SECRET: ""
|
||||
# Authenticates RPC between the gateway, push and the api.
|
||||
FLUXER_GATEWAY_RPC_AUTH_TOKEN: ""
|
||||
# Password of the bundled Valkey. Letters and digits only.
|
||||
FLUXER_VALKEY_PASSWORD: ""
|
||||
# Token of the bundled NATS, letters and digits only. With an outside NATS,
|
||||
# its token if it has one.
|
||||
FLUXER_NATS_AUTH_TOKEN: ""
|
||||
# Erlang distribution cookie of the gateway.
|
||||
FLUXER_ERLANG_COOKIE: ""
|
||||
# Signs media proxy URLs.
|
||||
FLUXER_MEDIA_PROXY_SECRET_KEY: ""
|
||||
# Standard base64 of at least 32 random bytes. Signs upload relay tokens.
|
||||
FLUXER_MEDIA_PROXY_UPLOAD_RELAY_SECRET_BASE64: ""
|
||||
# Signs admin panel sessions.
|
||||
FLUXER_ADMIN_SECRET_KEY_BASE: ""
|
||||
# Client secret of the built-in admin OAuth application.
|
||||
FLUXER_ADMIN_OAUTH_CLIENT_SECRET: ""
|
||||
# LiveKit API key.
|
||||
FLUXER_LIVEKIT_API_KEY: fluxer
|
||||
# LiveKit API secret, at least 32 characters.
|
||||
FLUXER_LIVEKIT_API_SECRET: ""
|
||||
# Web push key pair, base64url. Set both or neither.
|
||||
FLUXER_VAPID_PUBLIC_KEY: ""
|
||||
FLUXER_VAPID_PRIVATE_KEY: ""
|
||||
# Optional secret-bearing settings, added to the Secret as given. The keys are
|
||||
# the variable names on the configuration page of the operator docs.
|
||||
extra: {}
|
||||
# A full Postgres URL. Wins over the host, port, database and password.
|
||||
# FLUXER_POSTGRES_URL: postgres://fluxer:[email protected]:5432/fluxer
|
||||
# PEM text of the CA that signed the Postgres server certificate.
|
||||
# FLUXER_POSTGRES_SSL_CA: ""
|
||||
# The URL of an outside key-value store that holds a password.
|
||||
# FLUXER_KV_URL: redis://:[email protected]:6379/0
|
||||
# The password of an outside search server.
|
||||
# FLUXER_SEARCH_PASSWORD: ""
|
||||
# A temporary S3 session token.
|
||||
# FLUXER_S3_SESSION_TOKEN: ""
|
||||
# Comma-separated base64 secrets that sign attachment URLs.
|
||||
# FLUXER_MEDIA_PROXY_ATTACHMENT_URL_SECRETS_BASE64: ""
|
||||
# SMTP password for outgoing email.
|
||||
# FLUXER_EMAIL_SMTP_PASSWORD: ""
|
||||
# Secret that authenticates email provider webhooks.
|
||||
# FLUXER_EMAIL_WEBHOOK_SECRET: ""
|
||||
# Stripe secret key.
|
||||
# FLUXER_STRIPE_SECRET_KEY: ""
|
||||
# Stripe webhook signing secret.
|
||||
# FLUXER_STRIPE_WEBHOOK_SECRET: ""
|
||||
# Key of the donation proxy.
|
||||
# FLUXER_API_DONATION_PROXY_KEY: ""
|
||||
# Bearer token of the HTTP cache purge endpoint.
|
||||
# FLUXER_CACHE_PURGE_HTTP_TOKEN: ""
|
||||
# Klipy GIF API key.
|
||||
# FLUXER_KLIPY_API_KEY: ""
|
||||
# YouTube Data API key.
|
||||
# FLUXER_YOUTUBE_API_KEY: ""
|
||||
# Bluesky OAuth signing keys.
|
||||
# FLUXER_AUTH_BLUESKY_KEYS: ""
|
||||
# APNs private key for iOS push.
|
||||
# FLUXER_PUSH_APNS_PRIVATE_KEY: ""
|
||||
# FCM private key for Android push.
|
||||
# FLUXER_PUSH_FCM_PRIVATE_KEY: ""
|
||||
|
||||
# Extra non-secret settings for every Fluxer service, as NAME: value. The names
|
||||
# and meanings are on the configuration page of the operator docs. An empty
|
||||
# value is left out. The chart refuses a secret here. Secrets belong in
|
||||
# secrets.extra.
|
||||
env: {}
|
||||
|
||||
postgres:
|
||||
# Run Postgres in the release. Set false to use your own server.
|
||||
enabled: true
|
||||
image:
|
||||
repository: postgres
|
||||
# A new major needs a dump and restore. The pod refuses a data directory
|
||||
# from another major.
|
||||
tag: 16-alpine
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
# The user and group id of the postgres user in the image. 70 in the Alpine
|
||||
# images, 999 in the Debian ones.
|
||||
runAsUser: 70
|
||||
# Your own server, used when enabled is false. Its password goes in
|
||||
# secrets.values.FLUXER_POSTGRES_PASSWORD, or a URL in secrets.extra.FLUXER_POSTGRES_URL.
|
||||
# The database and the role have to exist already.
|
||||
external:
|
||||
host: ""
|
||||
port: 5432
|
||||
database: fluxer
|
||||
username: fluxer
|
||||
# true or false. Empty keeps the service default.
|
||||
ssl: ""
|
||||
# The database and role the bundled server creates.
|
||||
database: fluxer
|
||||
username: fluxer
|
||||
# Server settings, passed as -c name=value.
|
||||
parameters:
|
||||
max_connections: "150"
|
||||
shared_buffers: 512MB
|
||||
effective_cache_size: 2GB
|
||||
work_mem: 8MB
|
||||
maintenance_work_mem: 256MB
|
||||
autovacuum_work_mem: 128MB
|
||||
random_page_cost: "1.1"
|
||||
effective_io_concurrency: "200"
|
||||
default_statistics_target: "200"
|
||||
jit: "off"
|
||||
min_wal_size: 512MB
|
||||
max_wal_size: 2GB
|
||||
checkpoint_completion_target: "0.9"
|
||||
wal_buffers: 16MB
|
||||
wal_compression: zstd
|
||||
bgwriter_delay: 50ms
|
||||
bgwriter_lru_maxpages: "1000"
|
||||
autovacuum_vacuum_scale_factor: "0.05"
|
||||
autovacuum_analyze_scale_factor: "0.02"
|
||||
autovacuum_vacuum_cost_limit: "2000"
|
||||
track_io_timing: "on"
|
||||
shared_preload_libraries: pg_stat_statements
|
||||
# Size of the in-memory /dev/shm. Parallel vacuum needs it.
|
||||
shmSize: 1Gi
|
||||
# The size and the class are fixed once the volume exists. To grow a volume
|
||||
# later, edit the PersistentVolumeClaim, not this value.
|
||||
persistence:
|
||||
size: 20Gi
|
||||
# Empty uses the cluster default StorageClass.
|
||||
storageClassName: ""
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 1Gi
|
||||
limits:
|
||||
memory: 5Gi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
valkey:
|
||||
# Run Valkey in the release. Set false and give external.url to use your own.
|
||||
enabled: true
|
||||
image:
|
||||
repository: valkey/valkey
|
||||
tag: 9.1-alpine
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
external:
|
||||
# A URL without a password. One with a password goes in secrets.extra.FLUXER_KV_URL.
|
||||
url: ""
|
||||
maxmemory: 192mb
|
||||
maxmemoryPolicy: noeviction
|
||||
appendfsync: everysec
|
||||
persistence:
|
||||
size: 1Gi
|
||||
storageClassName: ""
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
nats:
|
||||
# Run NATS with JetStream in the release. Set false and give external.url to use your own.
|
||||
enabled: true
|
||||
image:
|
||||
repository: nats
|
||||
tag: 2.14-alpine
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
external:
|
||||
# Its token, if any, goes in secrets.values.FLUXER_NATS_AUTH_TOKEN.
|
||||
url: ""
|
||||
# 1, or 3 or more for a JetStream cluster.
|
||||
replicas: 1
|
||||
persistence:
|
||||
size: 10Gi
|
||||
storageClassName: ""
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
meilisearch:
|
||||
# Run Meilisearch in the release. Set false and give external.url to use your own.
|
||||
enabled: true
|
||||
image:
|
||||
repository: getmeili/meilisearch
|
||||
tag: v1.53
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
external:
|
||||
# Its key goes in secrets.values.FLUXER_SEARCH_API_KEY.
|
||||
url: ""
|
||||
maxIndexingMemory: 256mb
|
||||
maxIndexingThreads: 2
|
||||
persistence:
|
||||
size: 10Gi
|
||||
storageClassName: ""
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
memory: 1536Mi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
seaweedfs:
|
||||
# Run SeaweedFS as the S3 store and create the buckets. Only its S3 port
|
||||
# listens outside the pod. Set false and give s3.endpoint to use your own
|
||||
# store, with the buckets already created.
|
||||
enabled: true
|
||||
image:
|
||||
repository: chrislusf/seaweedfs
|
||||
tag: "4.47"
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
# Volumes grown per bucket. 1 keeps the store usable on small disks.
|
||||
volumeGrowth: 1
|
||||
gomemlimit: 1536MiB
|
||||
# Tries, 2 seconds apart, the bucket setup makes before it starts over.
|
||||
initAttempts: 60
|
||||
persistence:
|
||||
size: 20Gi
|
||||
storageClassName: ""
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
memory: 2Gi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
s3:
|
||||
# The S3 endpoint the services use. Empty uses the bundled SeaweedFS.
|
||||
endpoint: ""
|
||||
# The S3 endpoint browsers use for direct uploads. Empty uses endpoint.
|
||||
publicEndpoint: ""
|
||||
region: us-east-1
|
||||
forcePathStyle: true
|
||||
buckets:
|
||||
cdn: fluxer
|
||||
uploads: fluxer-uploads
|
||||
reports: fluxer-reports
|
||||
harvests: fluxer-harvests
|
||||
|
||||
livekit:
|
||||
# Run LiveKit for voice and video. false with no external.url turns voice off.
|
||||
enabled: true
|
||||
# A LiveKit server of your own, used when enabled is false. Its key and
|
||||
# secret go in secrets.values.FLUXER_LIVEKIT_API_KEY and FLUXER_LIVEKIT_API_SECRET.
|
||||
# Point its webhook at <origin>/api/webhooks/livekit, signed with the same key.
|
||||
external:
|
||||
# The address the api uses to reach it, for example http://livekit.voice.svc:7880.
|
||||
url: ""
|
||||
# The address browsers use to reach it, for example wss://livekit.example.com.
|
||||
publicUrl: ""
|
||||
image:
|
||||
repository: livekit/livekit-server
|
||||
tag: v1.12.0
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
# How clients reach the media ports. hostNetwork binds them on the node and
|
||||
# needs a privileged namespace. loadBalancer and nodePort use the Service
|
||||
# livekit-rtc, which serves TCP and UDP on one address.
|
||||
expose: hostNetwork
|
||||
# The public IP LiveKit advertises. Required for loadBalancer, where it is the
|
||||
# address of the load balancer. Empty finds it over STUN.
|
||||
nodeIP: ""
|
||||
# The address the loadBalancer Service asks for. Reserve it with your
|
||||
# provider first. Some providers take it from an annotation instead.
|
||||
loadBalancerIP: ""
|
||||
# Find the public IP over STUN.
|
||||
useExternalIP: true
|
||||
tcpPort: 7881
|
||||
udpPort: 7882
|
||||
# The node ports in nodePort mode. LiveKit advertises these too.
|
||||
nodePorts:
|
||||
tcp: 30881
|
||||
udp: 30882
|
||||
stunServers:
|
||||
- stun.l.google.com:19302
|
||||
- stun1.l.google.com:19302
|
||||
logLevel: info
|
||||
# More LiveKit configuration, merged over the chart's, for example
|
||||
# {rtc: {ips: {includes: [10.0.0.0/8]}}} to advertise only the node network.
|
||||
extraConfig: {}
|
||||
# The voice region seeded on every api start, as JSON.
|
||||
defaultRegion: '{"id":"default","name":"Default","emoji":"🌍","latitude":0,"longitude":0}'
|
||||
# Node addresses allowed to reach the edge in hostNetwork mode, for the
|
||||
# LiveKit webhook. Needed only with networkPolicy.ingressNamespaceSelector.
|
||||
# Keep it as narrow as the LiveKit node, for example 10.0.0.12/32 together
|
||||
# with nodeSelector.
|
||||
nodeCIDRs: []
|
||||
# Annotations for the Service livekit-rtc.
|
||||
serviceAnnotations: {}
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
# Every Fluxer workload below takes the same keys:
|
||||
# replicas, image (registry, tag, digest, pullPolicy), resources, env (NAME: value),
|
||||
# extraEnv (a list of Kubernetes env entries), probes (startup, liveness or
|
||||
# readiness, each replacing the default probe whole), podAnnotations,
|
||||
# nodeSelector, tolerations, affinity, topologySpreadConstraints, pdb
|
||||
# (minAvailable or maxUnavailable), hpa (minReplicas, maxReplicas,
|
||||
# targetCPUUtilizationPercentage), extraVolumes and extraVolumeMounts.
|
||||
|
||||
api:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 768Mi
|
||||
limits:
|
||||
memory: 2560Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
worker:
|
||||
# Must stay 1. The worker runs the cron scheduler.
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 768Mi
|
||||
limits:
|
||||
memory: 2560Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
gateway:
|
||||
replicas: 1
|
||||
terminationGracePeriodSeconds: 30
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
memory: 1Gi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
mediaProxy:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 50m
|
||||
memory: 128Mi
|
||||
limits:
|
||||
memory: 512Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
push:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
admin:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
appProxy:
|
||||
replicas: 1
|
||||
# Settings for app-proxy only: branding, CSP extras, the index upstream,
|
||||
# same-origin hosts and manifest scope, as NAME: value. For example
|
||||
# FLUXER_APP_PRODUCT_NAME, FLUXER_CSP_EXTRA_CONNECT_SRC or RUST_LOG.
|
||||
config: {}
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
staticProxy:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests:
|
||||
cpu: 10m
|
||||
memory: 32Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
env: {}
|
||||
extraEnv: []
|
||||
probes: {}
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
topologySpreadConstraints: []
|
||||
pdb: {}
|
||||
hpa: {}
|
||||
extraVolumes: []
|
||||
extraVolumeMounts: []
|
||||
|
||||
# The internal services. Each runs a router Deployment and a shard StatefulSet.
|
||||
# router and shard take the workload keys above. shard.replicas sets the shard count.
|
||||
svc:
|
||||
gifs:
|
||||
router:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 10m, memory: 32Mi}
|
||||
limits: {memory: 128Mi}
|
||||
shard:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 20m, memory: 64Mi}
|
||||
limits: {memory: 256Mi}
|
||||
messages:
|
||||
router:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 10m, memory: 32Mi}
|
||||
limits: {memory: 128Mi}
|
||||
shard:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 20m, memory: 64Mi}
|
||||
limits: {memory: 256Mi}
|
||||
snowflakes:
|
||||
router:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 10m, memory: 32Mi}
|
||||
limits: {memory: 128Mi}
|
||||
shard:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 20m, memory: 64Mi}
|
||||
limits: {memory: 256Mi}
|
||||
unfurl:
|
||||
router:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 10m, memory: 32Mi}
|
||||
limits: {memory: 128Mi}
|
||||
shard:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 20m, memory: 64Mi}
|
||||
limits: {memory: 256Mi}
|
||||
users:
|
||||
router:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 10m, memory: 32Mi}
|
||||
limits: {memory: 128Mi}
|
||||
shard:
|
||||
replicas: 1
|
||||
resources:
|
||||
requests: {cpu: 20m, memory: 64Mi}
|
||||
limits: {memory: 256Mi}
|
||||
|
||||
edge:
|
||||
image:
|
||||
repository: caddy
|
||||
tag: 2.11-alpine
|
||||
digest: ""
|
||||
pullPolicy: IfNotPresent
|
||||
# How traffic reaches the edge. ingress puts an Ingress in front of it,
|
||||
# gateway an HTTPRoute, loadBalancer a LoadBalancer Service with its own TLS,
|
||||
# and none leaves only the ClusterIP Service edge on port 8080.
|
||||
expose: ingress
|
||||
ingress:
|
||||
# The IngressClass. Empty uses the cluster default.
|
||||
className: ""
|
||||
# Extra annotations. The chart always adds the ingress-nginx body size and
|
||||
# timeout annotations, which other controllers ignore.
|
||||
annotations: {}
|
||||
tls:
|
||||
# certManager issues a certificate through a namespaced ACME Issuer.
|
||||
# existingSecret uses secretName. none serves plain HTTP behind the controller.
|
||||
mode: certManager
|
||||
secretName: fluxer-tls
|
||||
acmeServer: https://acme-v02.api.letsencrypt.org/directory
|
||||
gateway:
|
||||
# The Gateway the HTTPRoute attaches to, as Gateway API parentRefs.
|
||||
parentRefs: []
|
||||
# HTTPRoute timeouts, for example {request: 0s}. Envoy-based gateways cut
|
||||
# requests at 15 seconds without it.
|
||||
timeouts: {}
|
||||
loadBalancer:
|
||||
# Also publish UDP 443 for HTTP/3. Some clouds cannot mix TCP and UDP on one Service.
|
||||
http3: false
|
||||
annotations: {}
|
||||
# Size of the volume that keeps the certificates.
|
||||
persistence:
|
||||
size: 1Gi
|
||||
storageClassName: ""
|
||||
replicas: 1
|
||||
# Edge settings as NAME: value, overriding the chart's, for example
|
||||
# FLUXER_EDGE_GLOBAL_OPTIONS or FLUXER_EDGE_ENCODE.
|
||||
env: {}
|
||||
extraEnv: []
|
||||
resources:
|
||||
requests:
|
||||
cpu: 20m
|
||||
memory: 64Mi
|
||||
limits:
|
||||
memory: 256Mi
|
||||
podAnnotations: {}
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
networkPolicy:
|
||||
# Admit traffic to the release pods only from the release itself, to the edge
|
||||
# from anywhere, and to the LiveKit media ports. Network plugins without
|
||||
# NetworkPolicy support ignore it. Add a NetworkPolicy of your own to let
|
||||
# another namespace in, for example a metrics scraper.
|
||||
enabled: true
|
||||
# Namespaces allowed to reach the edge on port 8080, as a namespaceSelector,
|
||||
# for example {matchLabels: {kubernetes.io/metadata.name: ingress-nginx}}.
|
||||
# Empty allows any source.
|
||||
ingressNamespaceSelector: {}
|
||||
@@ -404,6 +404,10 @@ FLUXER_DISCOVERY_ENABLED=true
|
||||
# The compression the edge offers, as Caddy encode arguments.
|
||||
#FLUXER_EDGE_ENCODE=zstd gzip
|
||||
|
||||
# Extra Caddy global options, one line, added to the global block of the edge
|
||||
# Caddyfile. Empty adds nothing. Example: email [email protected]
|
||||
#FLUXER_EDGE_GLOBAL_OPTIONS=
|
||||
|
||||
# Images of the bundled services, for a mirror or another tag. A new Postgres
|
||||
# major needs a dump and restore, as the upgrade guide describes.
|
||||
#FLUXER_CADDY_IMAGE=caddy:2.11-alpine
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
trusted_proxies static {$FLUXER_EDGE_TRUSTED_PROXIES:private_ranges}
|
||||
trusted_proxies_strict
|
||||
}
|
||||
{$FLUXER_EDGE_GLOBAL_OPTIONS}
|
||||
}
|
||||
|
||||
{$FLUXER_EDGE_SITE_ADDRESS} {
|
||||
|
||||
@@ -231,6 +231,7 @@ services:
|
||||
FLUXER_EDGE_SITE_ADDRESS: ${FLUXER_EDGE_SITE_ADDRESS:-${FLUXER_CADDY_SITE_ADDRESS:-${FLUXER_PUBLIC_SCHEME:-https}://${FLUXER_DOMAIN:?set FLUXER_DOMAIN in .env}}}
|
||||
FLUXER_EDGE_TRUSTED_PROXIES: ${FLUXER_EDGE_TRUSTED_PROXIES:-private_ranges}
|
||||
FLUXER_EDGE_ENCODE: ${FLUXER_EDGE_ENCODE:-zstd gzip}
|
||||
FLUXER_EDGE_GLOBAL_OPTIONS: ${FLUXER_EDGE_GLOBAL_OPTIONS:-}
|
||||
FLUXER_ADMIN_BASE_PATH: ${FLUXER_ADMIN_BASE_PATH:-/admin}
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
|
||||
Reference in new issue
Block a user