Files
2026-07-13 13:32:57 +08:00

494 lines
22 KiB
YAML

{{- if .Values.webapp.serviceAccount.create }}
apiVersion: v1
kind: ServiceAccount
metadata:
name: {{ include "trigger-v4.webappServiceAccountName" . }}
labels:
{{- $component := "webapp" }}
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
{{- with .Values.webapp.serviceAccount.annotations }}
annotations:
{{- toYaml . | nindent 4 }}
{{- end }}
{{- end }}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: {{ include "trigger-v4.fullname" . }}-webapp-token-syncer
labels:
{{- $component := "webapp" }}
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
rules:
- apiGroups: [""]
resources: ["secrets"]
verbs: ["create", "get", "update", "patch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: {{ include "trigger-v4.fullname" . }}-webapp-token-syncer
labels:
{{- $component := "webapp" }}
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
subjects:
- kind: ServiceAccount
name: {{ include "trigger-v4.webappServiceAccountName" . }}
namespace: {{ .Release.Namespace }}
roleRef:
kind: Role
name: {{ include "trigger-v4.fullname" . }}-webapp-token-syncer
apiGroup: rbac.authorization.k8s.io
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: {{ include "trigger-v4.fullname" . }}-webapp
labels:
{{- $component := "webapp" }}
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
spec:
replicas: {{ .Values.webapp.replicaCount }}
selector:
matchLabels:
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 6 }}
template:
metadata:
annotations:
kubectl.kubernetes.io/default-container: webapp
{{- with .Values.webapp.podAnnotations }}
{{- toYaml . | nindent 8 }}
{{- end }}
labels:
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 8 }}
spec:
serviceAccountName: {{ include "trigger-v4.webappServiceAccountName" . }}
{{- with .Values.global.imagePullSecrets }}
imagePullSecrets:
{{- toYaml . | nindent 8 }}
{{- end }}
securityContext:
fsGroup: 1000
{{- with .Values.webapp.podSecurityContext }}
{{- toYaml . | nindent 8 }}
{{- end }}
initContainers:
- name: volume-permissions
image: {{ include "trigger-v4.webapp.volumePermissions.image" . }}
imagePullPolicy: {{ .Values.webapp.volumePermissions.image.pullPolicy }}
command: ['sh', '-c', 'mkdir -p /home/node/shared']
securityContext:
runAsUser: 1000
volumeMounts:
- name: shared
mountPath: /home/node/shared
containers:
- name: token-syncer
image: {{ include "trigger-v4.webapp.tokenSyncer.image" . }}
imagePullPolicy: {{ .Values.webapp.tokenSyncer.image.pullPolicy }}
securityContext:
runAsUser: 1000
runAsNonRoot: true
command:
- /bin/bash
- -c
- |
TOKEN_FILE="/home/node/shared/worker_token"
SECRET_NAME="{{ include "trigger-v4.fullname" . }}-worker-token"
NAMESPACE="{{ .Release.Namespace }}"
echo "Token syncer starting..."
echo "Monitoring: $TOKEN_FILE"
echo "Target secret: $SECRET_NAME"
while true; do
if [ -f "$TOKEN_FILE" ]; then
TOKEN=$(cat "$TOKEN_FILE")
if [ ! -z "$TOKEN" ]; then
echo "Token file found, creating/updating secret..."
# Create or update the secret
kubectl create secret generic "$SECRET_NAME" \
--from-literal=token="$TOKEN" \
--namespace="$NAMESPACE" \
--dry-run=client -o yaml | kubectl apply -f -
if [ $? -eq 0 ]; then
echo "Secret successfully created/updated"
# Continue monitoring for updates
sleep 30
else
echo "Failed to create/update secret, retrying in 5s..."
sleep 5
fi
else
echo "Token file exists but is empty, waiting..."
sleep 2
fi
else
echo "Waiting for token file..."
sleep 2
fi
done
volumeMounts:
- name: shared
mountPath: /home/node/shared
- name: webapp
securityContext:
{{- toYaml .Values.webapp.securityContext | nindent 12 }}
image: {{ include "trigger-v4.image" . }}
imagePullPolicy: {{ .Values.webapp.image.pullPolicy }}
command:
- ./scripts/entrypoint.sh
ports:
- name: http
containerPort: {{ .Values.webapp.service.targetPort }}
protocol: TCP
{{- if .Values.webapp.livenessProbe.enabled }}
livenessProbe:
httpGet:
path: /healthcheck
port: http
initialDelaySeconds: {{ .Values.webapp.livenessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.webapp.livenessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.webapp.livenessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.webapp.livenessProbe.failureThreshold }}
successThreshold: {{ .Values.webapp.livenessProbe.successThreshold }}
{{- end }}
{{- if .Values.webapp.readinessProbe.enabled }}
readinessProbe:
httpGet:
path: /healthcheck
port: http
initialDelaySeconds: {{ .Values.webapp.readinessProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.webapp.readinessProbe.periodSeconds }}
timeoutSeconds: {{ .Values.webapp.readinessProbe.timeoutSeconds }}
failureThreshold: {{ .Values.webapp.readinessProbe.failureThreshold }}
successThreshold: {{ .Values.webapp.readinessProbe.successThreshold }}
{{- end }}
{{- if .Values.webapp.startupProbe.enabled }}
startupProbe:
httpGet:
path: /healthcheck
port: http
initialDelaySeconds: {{ .Values.webapp.startupProbe.initialDelaySeconds }}
periodSeconds: {{ .Values.webapp.startupProbe.periodSeconds }}
timeoutSeconds: {{ .Values.webapp.startupProbe.timeoutSeconds }}
failureThreshold: {{ .Values.webapp.startupProbe.failureThreshold }}
successThreshold: {{ .Values.webapp.startupProbe.successThreshold }}
{{- end }}
resources:
{{- toYaml .Values.webapp.resources | nindent 12 }}
env:
- name: APP_ORIGIN
value: {{ .Values.webapp.appOrigin | quote }}
- name: LOGIN_ORIGIN
value: {{ .Values.webapp.loginOrigin | quote }}
- name: API_ORIGIN
value: {{ .Values.webapp.apiOrigin | quote }}
- name: ELECTRIC_ORIGIN
value: {{ include "trigger-v4.electric.url" . | quote }}
{{- if include "trigger-v4.s2.enabled" . }}
# Realtime streams v2, backed by S2 (bundled s2-lite or an external endpoint)
- name: REALTIME_STREAMS_DEFAULT_VERSION
value: {{ .Values.s2.defaultStreamVersion | quote }}
- name: REALTIME_STREAMS_S2_ENDPOINT
value: {{ include "trigger-v4.s2.url" . | quote }}
- name: REALTIME_STREAMS_S2_BASIN
value: {{ .Values.s2.basin | quote }}
- name: REALTIME_STREAMS_S2_SKIP_ACCESS_TOKENS
value: {{ .Values.s2.skipAccessTokens | quote }}
{{- if and .Values.s2.external.endpoint .Values.s2.external.existingSecret }}
- name: REALTIME_STREAMS_S2_ACCESS_TOKEN
valueFrom:
secretKeyRef:
name: {{ .Values.s2.external.existingSecret }}
key: {{ .Values.s2.external.existingSecretAccessTokenKey }}
{{- else if .Values.s2.external.accessToken }}
- name: REALTIME_STREAMS_S2_ACCESS_TOKEN
value: {{ .Values.s2.external.accessToken | quote }}
{{- end }}
{{- end }}
{{- if include "trigger-v4.postgres.useSecretUrl" . }}
- name: DATABASE_URL
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.postgres.external.secretName" . }}
key: {{ include "trigger-v4.postgres.external.databaseUrlKey" . }}
- name: DIRECT_URL
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.postgres.external.secretName" . }}
key: {{ include "trigger-v4.postgres.external.directUrlKey" . }}
{{- else }}
- name: DATABASE_URL
value: {{ include "trigger-v4.postgres.connectionString" . | quote }}
- name: DIRECT_URL
value: {{ include "trigger-v4.postgres.directUrl" . | quote }}
{{- end }}
{{- if and (include "trigger-v4.webapp.connectivityCheckEnabled" .) (include "trigger-v4.postgres.host" .) }}
- name: DATABASE_HOST
value: {{ include "trigger-v4.postgres.host" . | quote }}
{{- end }}
- name: REDIS_HOST
value: {{ include "trigger-v4.redis.host" . | quote }}
- name: REDIS_PORT
value: {{ include "trigger-v4.redis.port" . | quote }}
{{- if and .Values.redis.external.host .Values.redis.external.existingSecret }}
- name: REDIS_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.redis.external.secretName" . }}
key: {{ include "trigger-v4.redis.external.passwordKey" . }}
{{- else if include "trigger-v4.redis.password" . }}
- name: REDIS_PASSWORD
value: {{ include "trigger-v4.redis.password" . | quote }}
{{- end }}
- name: REDIS_TLS_DISABLED
value: {{ include "trigger-v4.redis.tlsDisabled" . | quote }}
- name: APP_LOG_LEVEL
value: {{ .Values.webapp.logLevel | quote }}
- name: DEV_OTEL_EXPORTER_OTLP_ENDPOINT
value: "{{ .Values.webapp.appOrigin }}/otel"
- name: DEPLOY_REGISTRY_HOST
value: {{ include "trigger-v4.registry.host" . | quote }}
- name: DEPLOY_REGISTRY_NAMESPACE
value: {{ .Values.registry.repositoryNamespace | quote }}
- name: OBJECT_STORE_BASE_URL
value: {{ include "trigger-v4.s3.url" . | quote }}
- name: GRACEFUL_SHUTDOWN_TIMEOUT
value: {{ .Values.webapp.gracefulShutdownTimeout | quote }}
{{- if .Values.webapp.bootstrap.enabled }}
- name: TRIGGER_BOOTSTRAP_ENABLED
value: "1"
- name: TRIGGER_BOOTSTRAP_WORKER_GROUP_NAME
value: {{ .Values.webapp.bootstrap.workerGroupName | quote }}
- name: TRIGGER_BOOTSTRAP_WORKER_TOKEN_PATH
value: {{ .Values.webapp.bootstrap.workerTokenPath | quote }}
{{- end }}
{{- if .Values.webapp.limits.taskPayloadOffloadThreshold }}
- name: TASK_PAYLOAD_OFFLOAD_THRESHOLD
value: {{ .Values.webapp.limits.taskPayloadOffloadThreshold | quote }}
{{- end }}
{{- if .Values.webapp.limits.taskPayloadMaximumSize }}
- name: TASK_PAYLOAD_MAXIMUM_SIZE
value: {{ .Values.webapp.limits.taskPayloadMaximumSize | quote }}
{{- end }}
{{- if .Values.webapp.limits.batchTaskPayloadMaximumSize }}
- name: BATCH_TASK_PAYLOAD_MAXIMUM_SIZE
value: {{ .Values.webapp.limits.batchTaskPayloadMaximumSize | quote }}
{{- end }}
{{- if .Values.webapp.limits.taskRunMetadataMaximumSize }}
- name: TASK_RUN_METADATA_MAXIMUM_SIZE
value: {{ .Values.webapp.limits.taskRunMetadataMaximumSize | quote }}
{{- end }}
{{- if .Values.webapp.limits.defaultEnvExecutionConcurrencyLimit }}
- name: DEFAULT_ENV_EXECUTION_CONCURRENCY_LIMIT
value: {{ .Values.webapp.limits.defaultEnvExecutionConcurrencyLimit | quote }}
{{- end }}
{{- if .Values.webapp.limits.defaultOrgExecutionConcurrencyLimit }}
- name: DEFAULT_ORG_EXECUTION_CONCURRENCY_LIMIT
value: {{ .Values.webapp.limits.defaultOrgExecutionConcurrencyLimit | quote }}
{{- end }}
{{- if or .Values.secrets.enabled .Values.secrets.existingSecret }}
- name: SESSION_SECRET
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: SESSION_SECRET
- name: MAGIC_LINK_SECRET
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: MAGIC_LINK_SECRET
- name: ENCRYPTION_KEY
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: ENCRYPTION_KEY
- name: MANAGED_WORKER_SECRET
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: MANAGED_WORKER_SECRET
{{- if .Values.s3.deploy }}
{{- if .Values.s3.auth.existingSecret }}
- name: OBJECT_STORE_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.s3.auth.secretName" . }}
key: {{ include "trigger-v4.s3.auth.accessKeyIdKey" . }}
- name: OBJECT_STORE_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.s3.auth.secretName" . }}
key: {{ include "trigger-v4.s3.auth.secretAccessKeyKey" . }}
{{- else }}
- name: OBJECT_STORE_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: s3-auth-access-key-id
- name: OBJECT_STORE_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: s3-auth-secret-access-key
{{- end }}
{{- else }}
{{- if .Values.s3.external.existingSecret }}
- name: OBJECT_STORE_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.s3.external.secretName" . }}
key: {{ include "trigger-v4.s3.external.accessKeyIdKey" . }}
- name: OBJECT_STORE_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.s3.external.secretName" . }}
key: {{ include "trigger-v4.s3.external.secretAccessKeyKey" . }}
{{- else if .Values.s3.external.accessKeyId }}
- name: OBJECT_STORE_ACCESS_KEY_ID
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: s3-access-key-id
- name: OBJECT_STORE_SECRET_ACCESS_KEY
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.secretsName" . }}
key: s3-secret-access-key
{{- end }}
{{- end }}
{{- end }}
{{- if .Values.webapp.observability }}
{{- if .Values.webapp.observability.tracing.exporterUrl }}
- name: INTERNAL_OTEL_TRACE_EXPORTER_URL
value: {{ .Values.webapp.observability.tracing.exporterUrl | quote }}
{{- end }}
{{- if .Values.webapp.observability.tracing.exporterAuthHeaders }}
- name: INTERNAL_OTEL_TRACE_EXPORTER_AUTH_HEADERS
value: {{ .Values.webapp.observability.tracing.exporterAuthHeaders | quote }}
{{- end }}
- name: INTERNAL_OTEL_TRACE_LOGGING_ENABLED
value: {{ .Values.webapp.observability.tracing.loggingEnabled | quote }}
- name: INTERNAL_OTEL_TRACE_SAMPLING_RATE
value: {{ .Values.webapp.observability.tracing.samplingRate | quote }}
- name: INTERNAL_OTEL_TRACE_INSTRUMENT_PRISMA_ENABLED
value: {{ .Values.webapp.observability.tracing.instrumentPrismaEnabled | quote }}
- name: INTERNAL_OTEL_TRACE_DISABLED
value: {{ .Values.webapp.observability.tracing.disabled | quote }}
{{- if .Values.webapp.observability.logging.exporterUrl }}
- name: INTERNAL_OTEL_LOG_EXPORTER_URL
value: {{ .Values.webapp.observability.logging.exporterUrl | quote }}
{{- end }}
{{- if .Values.webapp.observability.metrics.exporterUrl }}
- name: INTERNAL_OTEL_METRIC_EXPORTER_URL
value: {{ .Values.webapp.observability.metrics.exporterUrl | quote }}
{{- end }}
{{- if .Values.webapp.observability.metrics.exporterAuthHeaders }}
- name: INTERNAL_OTEL_METRIC_EXPORTER_AUTH_HEADERS
value: {{ .Values.webapp.observability.metrics.exporterAuthHeaders | quote }}
{{- end }}
- name: INTERNAL_OTEL_METRIC_EXPORTER_ENABLED
value: {{ .Values.webapp.observability.metrics.exporterEnabled | quote }}
- name: INTERNAL_OTEL_METRIC_EXPORTER_INTERVAL_MS
value: {{ .Values.webapp.observability.metrics.exporterIntervalMs | quote }}
{{- end }}
{{- if and .Values.clickhouse.external.host .Values.clickhouse.external.existingSecret }}
- name: CLICKHOUSE_PASSWORD
valueFrom:
secretKeyRef:
name: {{ include "trigger-v4.clickhouse.external.secretName" . }}
key: {{ include "trigger-v4.clickhouse.external.passwordKey" . }}
{{- end }}
- name: CLICKHOUSE_URL
value: {{ include "trigger-v4.clickhouse.url" . | quote }}
- name: CLICKHOUSE_LOG_LEVEL
value: {{ .Values.webapp.clickhouse.logLevel | quote }}
- name: RUN_REPLICATION_ENABLED
value: "1"
- name: RUN_REPLICATION_CLICKHOUSE_URL
value: {{ include "trigger-v4.clickhouse.replication.url" . | quote }}
- name: RUN_REPLICATION_LOG_LEVEL
value: {{ .Values.webapp.runReplication.logLevel | quote }}
{{- if not .Values.telemetry.enabled }}
- name: TRIGGER_TELEMETRY_DISABLED
value: "1"
{{- end }}
{{- with .Values.webapp.extraEnvVars }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumeMounts:
- name: shared
mountPath: /home/node/shared
{{- with .Values.webapp.extraVolumeMounts }}
{{- toYaml . | nindent 12 }}
{{- end }}
volumes:
- name: shared
{{- if .Values.persistence.shared.enabled }}
persistentVolumeClaim:
claimName: {{ include "trigger-v4.fullname" . }}-shared
{{- else }}
emptyDir: {}
{{- end }}
{{- with .Values.webapp.extraVolumes }}
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webapp.nodeSelector }}
nodeSelector:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webapp.affinity }}
affinity:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webapp.tolerations }}
tolerations:
{{- toYaml . | nindent 8 }}
{{- end }}
{{- with .Values.webapp.topologySpreadConstraints }}
topologySpreadConstraints:
{{- tpl (toYaml .) $ | nindent 8 }}
{{- end }}
---
apiVersion: v1
kind: Service
metadata:
name: {{ include "trigger-v4.fullname" . }}-webapp
labels:
{{- $component := "webapp" }}
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
spec:
type: {{ .Values.webapp.service.type }}
ports:
- port: {{ .Values.webapp.service.port }}
targetPort: http
protocol: TCP
name: http
selector:
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
---
{{- if .Values.persistence.shared.enabled }}
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: {{ include "trigger-v4.fullname" . }}-shared
{{- if .Values.persistence.shared.retain }}
annotations:
"helm.sh/resource-policy": keep
{{- end }}
labels:
{{- include "trigger-v4.labels" . | nindent 4 }}
spec:
accessModes:
- {{ .Values.persistence.shared.accessMode }}
resources:
requests:
storage: {{ .Values.persistence.shared.size }}
{{- $storageClass := .Values.persistence.shared.storageClass | default .Values.global.storageClass }}
{{- if $storageClass }}
storageClassName: {{ $storageClass | quote }}
{{- end }}
{{- end }}