chore: import upstream snapshot with attribution
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
values-*.yaml
|
||||
!values-production-example.yaml
|
||||
*.tgz
|
||||
/charts
|
||||
@@ -0,0 +1,17 @@
|
||||
# Exclude version control
|
||||
.git/
|
||||
.gitignore
|
||||
.helmignore
|
||||
|
||||
# Exclude OS files
|
||||
.DS_Store
|
||||
|
||||
# Exclude CI/CD and scripts
|
||||
.github/
|
||||
scripts/
|
||||
|
||||
# Exclude package files
|
||||
*.tgz
|
||||
|
||||
# Exclude additional values files
|
||||
values-*.yaml
|
||||
@@ -0,0 +1,15 @@
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 16.7.14
|
||||
- name: redis
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 21.2.6
|
||||
- name: clickhouse
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 9.4.4
|
||||
- name: minio
|
||||
repository: oci://registry-1.docker.io/bitnamicharts
|
||||
version: 17.0.9
|
||||
digest: sha256:e1b572ab8eca0cc376311398c27b1734d8a598095fccc81dd9c32b2c8b9c1149
|
||||
generated: "2026-05-05T10:31:58.493590751+01:00"
|
||||
@@ -0,0 +1,37 @@
|
||||
apiVersion: v2
|
||||
name: trigger
|
||||
description: The official Trigger.dev Helm chart
|
||||
type: application
|
||||
version: 4.5.3
|
||||
appVersion: v4.5.3
|
||||
home: https://trigger.dev
|
||||
sources:
|
||||
- https://github.com/triggerdotdev/trigger.dev
|
||||
keywords:
|
||||
- trigger
|
||||
- workflow
|
||||
- background-jobs
|
||||
- job-scheduler
|
||||
- task-queue
|
||||
- automation
|
||||
annotations:
|
||||
category: Development
|
||||
dependencies:
|
||||
- name: postgresql
|
||||
version: "16.7.14"
|
||||
repository: "oci://registry-1.docker.io/bitnamicharts"
|
||||
condition: postgres.deploy
|
||||
alias: postgres
|
||||
- name: redis
|
||||
version: "21.2.6"
|
||||
repository: "oci://registry-1.docker.io/bitnamicharts"
|
||||
condition: redis.deploy
|
||||
- name: clickhouse
|
||||
version: "9.4.4"
|
||||
repository: "oci://registry-1.docker.io/bitnamicharts"
|
||||
condition: clickhouse.deploy
|
||||
- name: minio
|
||||
version: "17.0.9"
|
||||
repository: "oci://registry-1.docker.io/bitnamicharts"
|
||||
condition: s3.deploy
|
||||
alias: s3
|
||||
@@ -0,0 +1,739 @@
|
||||
# Trigger.dev v4 Helm Chart
|
||||
|
||||
This Helm chart deploys Trigger.dev v4 self-hosting stack to Kubernetes.
|
||||
|
||||
## Quick Start
|
||||
|
||||
### Prerequisites
|
||||
|
||||
```bash
|
||||
# Build Helm dependencies (required for Bitnami charts)
|
||||
helm dependency build
|
||||
|
||||
# Extract dependency charts for local template testing
|
||||
for file in ./charts/*.tgz; do echo "Extracting $file"; tar -xzf "$file" -C ./charts; done
|
||||
|
||||
# Alternative: Use --dependency-update flag for template testing
|
||||
helm template trigger . --dependency-update
|
||||
```
|
||||
|
||||
### Installation
|
||||
|
||||
```bash
|
||||
# Deploy with default values (testing/development only)
|
||||
helm install trigger .
|
||||
|
||||
# Deploy to specific namespace
|
||||
helm install trigger . -n trigger --create-namespace
|
||||
|
||||
# Deploy with custom values for production
|
||||
helm install trigger . -f values-production.yaml -n trigger --create-namespace
|
||||
```
|
||||
|
||||
### Upgrading
|
||||
|
||||
```bash
|
||||
# Upgrade existing release
|
||||
helm upgrade trigger .
|
||||
|
||||
# Upgrade with new values
|
||||
helm upgrade trigger . -f values-production.yaml
|
||||
```
|
||||
|
||||
### Access the dashboard
|
||||
|
||||
```bash
|
||||
kubectl port-forward svc/trigger-webapp 3040:3030 --address 0.0.0.0
|
||||
```
|
||||
|
||||
Dashboard: http://localhost:3040/
|
||||
|
||||
### Deploying your tasks
|
||||
|
||||
```bash
|
||||
# The --push arg is required when testing locally
|
||||
npx trigger.dev@latest deploy --push
|
||||
```
|
||||
|
||||
## ⚠️ Security Requirements
|
||||
|
||||
### Secrets Configuration
|
||||
|
||||
**IMPORTANT**: The default secrets are for **TESTING ONLY** and must be changed for production.
|
||||
|
||||
#### Required Secrets
|
||||
|
||||
All secrets must be exactly **32 hexadecimal characters** (16 bytes):
|
||||
|
||||
- `sessionSecret` - User authentication sessions
|
||||
- `magicLinkSecret` - Passwordless login tokens
|
||||
- `encryptionKey` - Sensitive data encryption
|
||||
- `managedWorkerSecret` - Worker authentication
|
||||
|
||||
#### Generate Production Secrets
|
||||
|
||||
```bash
|
||||
for i in {1..4}; do openssl rand -hex 16; done
|
||||
```
|
||||
|
||||
#### Configure Production Secrets
|
||||
|
||||
```yaml
|
||||
# values-production.yaml
|
||||
secrets:
|
||||
sessionSecret: "your-generated-secret-1"
|
||||
magicLinkSecret: "your-generated-secret-2"
|
||||
encryptionKey: "your-generated-secret-3"
|
||||
managedWorkerSecret: "your-generated-secret-4"
|
||||
objectStore:
|
||||
accessKeyId: "your-s3-access-key"
|
||||
secretAccessKey: "your-s3-secret-key"
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
This chart deploys the following components:
|
||||
|
||||
### Core Services
|
||||
- **Webapp** - Main Trigger.dev application (port 3030)
|
||||
- **PostgreSQL** - Primary database with logical replication
|
||||
- **Redis** - Cache and job queue
|
||||
- **Electric** - Real-time sync service (ElectricSQL)
|
||||
|
||||
### Worker Services
|
||||
- **Supervisor** - Kubernetes worker orchestrator for executing runs
|
||||
|
||||
### Supporting Services
|
||||
- **ClickHouse** - Analytics database
|
||||
- **MinIO** - S3-compatible object storage
|
||||
- **Registry** - Private Docker registry for deployed code (EXPERIMENTAL - disabled by default)
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic Configuration
|
||||
|
||||
```yaml
|
||||
webapp:
|
||||
# Application URLs
|
||||
appOrigin: "https://trigger.example.com"
|
||||
loginOrigin: "https://trigger.example.com"
|
||||
apiOrigin: "https://trigger.example.com"
|
||||
|
||||
# Bootstrap mode (auto-creates worker group)
|
||||
bootstrap:
|
||||
enabled: true # Enable for combined setups
|
||||
workerGroupName: "bootstrap"
|
||||
```
|
||||
|
||||
### External Services
|
||||
|
||||
Use external managed services instead of bundled components:
|
||||
|
||||
```yaml
|
||||
# External PostgreSQL
|
||||
postgres:
|
||||
deploy: false
|
||||
external:
|
||||
host: "your-postgres.rds.amazonaws.com"
|
||||
port: 5432
|
||||
database: "trigger"
|
||||
username: "trigger_user"
|
||||
password: "your-password"
|
||||
|
||||
# External Redis
|
||||
redis:
|
||||
deploy: false
|
||||
external:
|
||||
host: "your-redis.cache.amazonaws.com"
|
||||
port: 6379
|
||||
password: "your-password"
|
||||
|
||||
# External Docker Registry (e.g., Kind local registry)
|
||||
registry:
|
||||
deploy: true
|
||||
external:
|
||||
host: "localhost"
|
||||
port: 5001
|
||||
username: ""
|
||||
password: ""
|
||||
```
|
||||
|
||||
### Ingress Configuration
|
||||
|
||||
```yaml
|
||||
# Webapp ingress
|
||||
webapp:
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: trigger.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: trigger-tls
|
||||
hosts:
|
||||
- trigger.example.com
|
||||
|
||||
# Registry ingress
|
||||
registry:
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
hosts:
|
||||
- host: registry.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: registry-tls
|
||||
hosts:
|
||||
- registry.example.com
|
||||
```
|
||||
|
||||
### Resource Configuration
|
||||
|
||||
```yaml
|
||||
resources:
|
||||
webapp:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
postgres:
|
||||
primary:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
```
|
||||
|
||||
## Deployment Modes
|
||||
|
||||
### Testing/Development
|
||||
- Use default values
|
||||
- Single replica
|
||||
- Lower resource limits
|
||||
- Bootstrap mode enabled
|
||||
|
||||
### Production
|
||||
- Custom secrets (required)
|
||||
- Multiple replicas with anti-affinity
|
||||
- Production resource limits
|
||||
- External services recommended
|
||||
- Ingress with TLS
|
||||
- Persistent storage
|
||||
|
||||
## Persistence
|
||||
|
||||
All services support persistent storage and allow you to control the storage class globally or per service. Our internal services (Registry) now support the full Bitnami persistence configuration pattern:
|
||||
|
||||
### Basic Persistence Configuration
|
||||
|
||||
```yaml
|
||||
global:
|
||||
storageClass: "fast-ssd" # Default for all services
|
||||
|
||||
# Bitnami chart services (simplified configuration)
|
||||
postgres:
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
storageClass: "postgres-nvme" # Optional: override for PostgreSQL
|
||||
|
||||
redis:
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 5Gi
|
||||
storageClass: "redis-ssd" # Optional: override for Redis
|
||||
|
||||
clickhouse:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
storageClass: "analytics-hdd" # Optional: override for ClickHouse
|
||||
|
||||
s3:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
storageClass: "objectstore-ssd" # Optional: override for S3
|
||||
```
|
||||
|
||||
### Internal Services - Full Bitnami-Style Configuration
|
||||
|
||||
Our internal services (Registry) support the complete Bitnami persistence configuration pattern:
|
||||
|
||||
```yaml
|
||||
# Registry - Full persistence configuration options
|
||||
registry:
|
||||
persistence:
|
||||
enabled: true
|
||||
# Name to assign the volume
|
||||
volumeName: "data"
|
||||
# Name of an existing PVC to use
|
||||
existingClaim: ""
|
||||
# The path the volume will be mounted at
|
||||
mountPath: "/var/lib/registry"
|
||||
# The subdirectory of the volume to mount to
|
||||
subPath: ""
|
||||
# PVC Storage Class for Registry data volume
|
||||
storageClass: "registry-ssd"
|
||||
# PVC Access Mode for Registry volume
|
||||
accessModes:
|
||||
- "ReadWriteOnce"
|
||||
# PVC Storage Request for Registry volume
|
||||
size: 10Gi
|
||||
# Annotations for the PVC
|
||||
annotations:
|
||||
backup.velero.io/backup-volumes: "data"
|
||||
# Labels for the PVC
|
||||
labels:
|
||||
app.kubernetes.io/component: "storage"
|
||||
# Selector to match an existing Persistent Volume
|
||||
selector:
|
||||
matchLabels:
|
||||
tier: "registry"
|
||||
# Custom PVC data source
|
||||
dataSource:
|
||||
name: "registry-snapshot"
|
||||
kind: "VolumeSnapshot"
|
||||
apiGroup: "snapshot.storage.k8s.io"
|
||||
|
||||
# Shared persistent volume for worker token file
|
||||
persistence:
|
||||
shared:
|
||||
enabled: true
|
||||
size: 5Mi
|
||||
accessMode: ReadWriteOnce
|
||||
# accessMode: ReadWriteMany # Use for cross-node deployment
|
||||
storageClass: ""
|
||||
retain: true # Prevents deletion on uninstall
|
||||
```
|
||||
|
||||
### Persistence Configuration Rules
|
||||
|
||||
- **Service-level storageClass** overrides the global value for that service only
|
||||
- **Global storageClass** applies to all services that don't specify their own
|
||||
- **Cluster default** is used if neither global nor service-level storageClass is set
|
||||
- **Internal services** (Registry) support full Bitnami-style configuration
|
||||
- **Bitnami chart services** use their respective chart's configuration patterns
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Health Checks
|
||||
|
||||
Health checks are configured for all services:
|
||||
- HTTP endpoints for web services
|
||||
- Database connection tests
|
||||
- Readiness and liveness probes
|
||||
|
||||
### Health Probe Configuration
|
||||
|
||||
All non-Bitnami services support configurable health probes:
|
||||
|
||||
```yaml
|
||||
# Webapp health probes
|
||||
webapp:
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 1
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
# Supervisor health probes
|
||||
supervisor:
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 1
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
# Electric health probes
|
||||
electric:
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 1
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
# Registry health probes
|
||||
registry:
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 1
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
```
|
||||
|
||||
### Prometheus Integration
|
||||
|
||||
ServiceMonitors are available for webapp and supervisor services:
|
||||
|
||||
```yaml
|
||||
webapp:
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
interval: "30s"
|
||||
path: "/metrics"
|
||||
labels:
|
||||
release: prometheus-stack
|
||||
|
||||
supervisor:
|
||||
serviceMonitor:
|
||||
enabled: true
|
||||
interval: "30s"
|
||||
path: "/metrics"
|
||||
labels:
|
||||
release: prometheus-stack
|
||||
```
|
||||
|
||||
## Operations
|
||||
|
||||
### Force Pod Restart
|
||||
|
||||
When you need to force all pods to restart (e.g., to pick up updated secrets or config):
|
||||
|
||||
```bash
|
||||
# Force restart using timestamp annotation (Helm-native approach)
|
||||
helm upgrade <release-name> . --set-string podAnnotations.restartedAt="$(date +%s)"
|
||||
|
||||
# Example
|
||||
helm upgrade trigger . --set-string podAnnotations.restartedAt="$(date +%s)"
|
||||
```
|
||||
|
||||
This approach:
|
||||
- ✅ Uses Helm's built-in annotation mechanism
|
||||
- ✅ Safe - doesn't recreate immutable resources like PVCs
|
||||
- ✅ Targeted - only restarts pods that need updates
|
||||
- ✅ Trackable - increments Helm revision number
|
||||
|
||||
### Configuration Updates
|
||||
|
||||
After changing secrets or ConfigMaps in your values file:
|
||||
|
||||
```bash
|
||||
# 1. Upgrade with new values
|
||||
helm upgrade trigger . -f values-production.yaml
|
||||
|
||||
# 2. Force pod restart to pick up changes
|
||||
helm upgrade trigger . -f values-production.yaml \
|
||||
--set-string podAnnotations.restartedAt="$(date +%s)"
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Check Pod Status
|
||||
```bash
|
||||
kubectl get pods -l app.kubernetes.io/name=trigger.dev
|
||||
```
|
||||
|
||||
### View Logs
|
||||
```bash
|
||||
# Webapp logs
|
||||
kubectl logs -l app.kubernetes.io/component=webapp
|
||||
|
||||
# Database logs
|
||||
kubectl logs -l app.kubernetes.io/component=postgres
|
||||
```
|
||||
|
||||
### Run Tests
|
||||
```bash
|
||||
helm test trigger.dev
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Validate Deployment
|
||||
|
||||
```bash
|
||||
# Check Helm template syntax
|
||||
helm template trigger.dev . --dry-run > /dev/null && echo "Template validation successful"
|
||||
|
||||
# Test webapp health endpoint (requires port forwarding)
|
||||
curl -s -o /dev/null -w "%{http_code}" http://localhost:3040/healthcheck || echo "Connection failed"
|
||||
|
||||
# Port forward to access webapp locally
|
||||
kubectl port-forward svc/trigger.dev-webapp 3040:3030 --address 0.0.0.0
|
||||
```
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Secrets errors**: Ensure all secrets are exactly 32 hex characters
|
||||
2. **Database connection**: Check PostgreSQL is ready before webapp starts
|
||||
3. **Resource limits**: Increase limits for ClickHouse in constrained environments
|
||||
4. **Config not applying**: Use the pod restart technique above to force config reload
|
||||
5. **Image pull errors**: When testing locally, deploy with `npx trigger.dev@latest deploy --push`
|
||||
|
||||
## Examples
|
||||
|
||||
See `values-production-example.yaml` for a complete production configuration example.
|
||||
|
||||
## Version Management
|
||||
|
||||
### Understanding Versions
|
||||
|
||||
The Helm chart uses three types of versions:
|
||||
|
||||
1. **Chart Version** (`Chart.yaml:version`) - Helm chart packaging version
|
||||
2. **App Version** (`Chart.yaml:appVersion`) - Trigger.dev application version
|
||||
3. **Component Versions** (`values.yaml`) - Individual service versions (Electric, ClickHouse, etc.)
|
||||
|
||||
### Release Process
|
||||
|
||||
#### For Chart Maintainers
|
||||
|
||||
1. **Update Chart Version** for chart changes:
|
||||
```bash
|
||||
# Edit Chart.yaml
|
||||
version: 4.1.0 # Increment for chart changes (semver)
|
||||
```
|
||||
|
||||
2. **Update App Version** when Trigger.dev releases new version:
|
||||
```bash
|
||||
# Edit Chart.yaml
|
||||
appVersion: "v4.1.0" # Match Trigger.dev release (v-prefixed image tag)
|
||||
```
|
||||
|
||||
3. **Release via GitHub**:
|
||||
```bash
|
||||
# Tag and push
|
||||
git tag helm-v4.1.0
|
||||
git push origin helm-v4.1.0
|
||||
|
||||
# GitHub Actions will automatically build and publish to GHCR
|
||||
```
|
||||
|
||||
#### For Users
|
||||
|
||||
```bash
|
||||
# Install specific chart version
|
||||
helm upgrade --install trigger \
|
||||
oci://ghcr.io/triggerdotdev/charts/trigger.dev \
|
||||
--version 4.1.0
|
||||
|
||||
# Install latest chart version
|
||||
helm upgrade --install trigger \
|
||||
oci://ghcr.io/triggerdotdev/charts/trigger.dev
|
||||
|
||||
# Override app version (advanced)
|
||||
helm upgrade --install trigger . \
|
||||
--set webapp.image.tag=v4.0.1
|
||||
```
|
||||
|
||||
## Production Readiness Checklist
|
||||
|
||||
### 🔒 Security (REQUIRED)
|
||||
|
||||
- [ ] **Generate unique secrets** (never use defaults):
|
||||
```bash
|
||||
# Generate 4 secrets
|
||||
for i in {1..4}; do openssl rand -hex 16; done
|
||||
```
|
||||
|
||||
- [ ] **Configure security contexts**:
|
||||
```yaml
|
||||
webapp:
|
||||
podSecurityContext:
|
||||
fsGroup: 1000
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 1000
|
||||
allowPrivilegeEscalation: false
|
||||
readOnlyRootFilesystem: true
|
||||
capabilities:
|
||||
drop: [ALL]
|
||||
```
|
||||
|
||||
- [ ] **Enable network policies** (if supported by cluster)
|
||||
- [ ] **Configure proper RBAC** for supervisor
|
||||
- [ ] **Use TLS ingress** with cert-manager
|
||||
|
||||
### 📊 Resource Management (REQUIRED)
|
||||
|
||||
- [ ] **Set resource limits and requests** - for example:
|
||||
```yaml
|
||||
webapp:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
postgres:
|
||||
primary:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
redis:
|
||||
master:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
|
||||
# ClickHouse can be very resource intensive, so we recommend setting limits and requests accordingly
|
||||
# Note: not doing this can cause OOM crashes which will cause issues across many different features
|
||||
clickhouse:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 4000m
|
||||
memory: 16Gi
|
||||
requests:
|
||||
cpu: 2000m
|
||||
memory: 8Gi
|
||||
|
||||
supervisor:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
```
|
||||
|
||||
- [ ] **Configure persistent storage for all services** - for example:
|
||||
```yaml
|
||||
global:
|
||||
storageClass: "fast-nvme" # Default for all services
|
||||
|
||||
postgres:
|
||||
primary:
|
||||
persistence:
|
||||
size: 500Gi
|
||||
|
||||
redis:
|
||||
master:
|
||||
persistence:
|
||||
size: 20Gi
|
||||
|
||||
clickhouse:
|
||||
persistence:
|
||||
size: 100Gi
|
||||
|
||||
s3:
|
||||
persistence:
|
||||
size: 200Gi
|
||||
|
||||
# Internal services support full Bitnami-style configuration
|
||||
registry:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 100Gi
|
||||
storageClass: "registry-ssd"
|
||||
annotations:
|
||||
backup.velero.io/backup-volumes: "data"
|
||||
```
|
||||
|
||||
### 🏗️ High Availability (RECOMMENDED)
|
||||
|
||||
- [ ] **Multiple replicas** with pod anti-affinity
|
||||
- [ ] **Pod disruption budgets**
|
||||
- [ ] **External managed services** (RDS, ElastiCache, etc.)
|
||||
- [ ] **Multi-AZ storage classes**
|
||||
- [ ] **Backup strategies** for databases
|
||||
|
||||
### 📈 Monitoring (RECOMMENDED)
|
||||
|
||||
- [ ] **Enable ServiceMonitors** for Prometheus
|
||||
- [ ] **Configure alerting** for critical services
|
||||
- [ ] **Set up log aggregation**
|
||||
- [ ] **Monitor resource usage** and adjust limits
|
||||
|
||||
### 🚀 Performance (OPTIONAL)
|
||||
|
||||
- [ ] **Horizontal Pod Autoscaler** for webapp
|
||||
- [ ] **Vertical Pod Autoscaler** for data services
|
||||
- [ ] **Node affinity** for data services
|
||||
- [ ] **Separate storage classes** for different workloads
|
||||
|
||||
## Support
|
||||
|
||||
- Documentation: https://trigger.dev/docs/self-hosting
|
||||
- GitHub Issues: https://github.com/triggerdotdev/trigger.dev/issues
|
||||
- Discord: https://discord.gg/untWVke9aH
|
||||
@@ -0,0 +1,96 @@
|
||||
Thank you for installing {{ .Chart.Name }}.
|
||||
|
||||
Your release is named {{ .Release.Name }}.
|
||||
|
||||
🔐 SECURITY WARNING:
|
||||
{{- if or (eq .Values.secrets.sessionSecret "2818143646516f6fffd707b36f334bbb") (eq .Values.secrets.magicLinkSecret "44da78b7bbb0dfe709cf38931d25dcdd") (eq .Values.secrets.encryptionKey "f686147ab967943ebbe9ed3b496e465a") (eq .Values.secrets.managedWorkerSecret "447c29678f9eaf289e9c4b70d3dd8a7f") }}
|
||||
You are using DEFAULT SECRETS which are NOT SECURE for production!
|
||||
|
||||
For production deployments, generate new secrets:
|
||||
1. Run: openssl rand -hex 16 (repeat for each secret)
|
||||
2. Override in your values.yaml:
|
||||
secrets:
|
||||
sessionSecret: "your-new-32-char-hex-secret"
|
||||
magicLinkSecret: "your-new-32-char-hex-secret"
|
||||
encryptionKey: "your-new-32-char-hex-secret"
|
||||
managedWorkerSecret: "your-new-32-char-hex-secret"
|
||||
{{- else }}
|
||||
Custom secrets detected - good for production deployment!
|
||||
{{- end }}
|
||||
|
||||
To get started:
|
||||
|
||||
1. Wait for all pods to be ready:
|
||||
kubectl get pods --namespace {{ .Release.Namespace }} -w
|
||||
|
||||
2. Access the webapp:
|
||||
{{- if .Values.webapp.ingress.enabled }}
|
||||
{{- range $host := .Values.webapp.ingress.hosts }}
|
||||
{{- range .paths }}
|
||||
http{{ if $.Values.webapp.ingress.tls }}s{{ end }}://{{ $host.host }}{{ .path }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- else if contains "NodePort" .Values.webapp.service.type }}
|
||||
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "trigger-v4.fullname" . }}-webapp)
|
||||
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
|
||||
echo http://$NODE_IP:$NODE_PORT
|
||||
{{- else if contains "LoadBalancer" .Values.webapp.service.type }}
|
||||
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
|
||||
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "trigger-v4.fullname" . }}-webapp'
|
||||
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "trigger-v4.fullname" . }}-webapp --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
|
||||
echo http://$SERVICE_IP:{{ .Values.webapp.service.port }}
|
||||
{{- else if contains "ClusterIP" .Values.webapp.service.type }}
|
||||
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "{{ include "trigger-v4.selectorLabels" . }},app.kubernetes.io/component=webapp" -o jsonpath="{.items[0].metadata.name}")
|
||||
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
|
||||
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8030:$CONTAINER_PORT
|
||||
|
||||
The application will be available at http://localhost:8030
|
||||
{{- end }}
|
||||
|
||||
For more information about the deployment, run:
|
||||
kubectl --namespace {{ .Release.Namespace }} get all -l "{{ include "trigger-v4.selectorLabels" . }}"
|
||||
|
||||
{{- if .Values.webapp.bootstrap.enabled }}
|
||||
|
||||
Bootstrap Mode is enabled:
|
||||
- Worker group "{{ .Values.webapp.bootstrap.workerGroupName }}" will be automatically created
|
||||
- Worker token will be available at {{ .Values.webapp.bootstrap.workerTokenPath }}
|
||||
{{- end }}
|
||||
|
||||
Configuration:
|
||||
{{- if .Values.postgres.deploy }}
|
||||
- Using internal PostgreSQL
|
||||
{{- else }}
|
||||
- Using external PostgreSQL at {{ .Values.postgres.external.host }}:{{ .Values.postgres.external.port | default 5432 }}
|
||||
{{- end }}
|
||||
{{- if .Values.redis.deploy }}
|
||||
- Using internal Redis
|
||||
{{- else }}
|
||||
- Using external Redis at {{ .Values.redis.external.host }}:{{ .Values.redis.external.port | default 6379 }}
|
||||
{{- end }}
|
||||
{{- if .Values.electric.deploy }}
|
||||
- Using internal Electric sync service
|
||||
{{- else }}
|
||||
- Using external Electric sync service at {{ .Values.electric.external.url }}
|
||||
{{- end }}
|
||||
{{- if .Values.clickhouse.deploy }}
|
||||
- Using internal ClickHouse
|
||||
{{- else }}
|
||||
- Using external ClickHouse at {{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
|
||||
{{- end }}
|
||||
{{- if .Values.s3.deploy }}
|
||||
- Using internal S3-compatible object storage (MinIO)
|
||||
{{- else }}
|
||||
- Using external S3-compatible object storage at {{ .Values.s3.external.endpoint }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.deploy }}
|
||||
- Using internal Docker registry
|
||||
{{- else }}
|
||||
- Using external Docker registry at {{ .Values.registry.external.host }}
|
||||
{{- if hasPrefix "localhost" .Values.registry.external.host }}
|
||||
|
||||
⚠️ Registry Warning:
|
||||
Using localhost for registry. Deployments will only work when testing locally in kind or minikube.
|
||||
Please ensure registry.external is properly configured to point at an external registry.
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,654 @@
|
||||
{{/*
|
||||
Expand the name of the chart.
|
||||
*/}}
|
||||
{{- define "trigger-v4.name" -}}
|
||||
{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create a default fully qualified app name.
|
||||
We truncate at 63 chars because some Kubernetes name fields are limited to this (by the DNS naming spec).
|
||||
If release name contains chart name it will be used as a full name.
|
||||
*/}}
|
||||
{{- define "trigger-v4.fullname" -}}
|
||||
{{- if .Values.fullnameOverride }}
|
||||
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- $name := default .Chart.Name .Values.nameOverride }}
|
||||
{{- if contains $name .Release.Name }}
|
||||
{{- .Release.Name | trunc 63 | trimSuffix "-" }}
|
||||
{{- else }}
|
||||
{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create chart name and version as used by the chart label.
|
||||
*/}}
|
||||
{{- define "trigger-v4.chart" -}}
|
||||
{{- printf "%s-%s" .Chart.Name .Chart.Version | replace "+" "_" | trunc 63 | trimSuffix "-" }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Common labels
|
||||
*/}}
|
||||
{{- define "trigger-v4.labels" -}}
|
||||
helm.sh/chart: {{ include "trigger-v4.chart" . }}
|
||||
{{ include "trigger-v4.selectorLabels" . }}
|
||||
{{- if .Chart.AppVersion }}
|
||||
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||
{{- end }}
|
||||
app.kubernetes.io/managed-by: {{ .Release.Service }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Selector labels
|
||||
*/}}
|
||||
{{- define "trigger-v4.selectorLabels" -}}
|
||||
app.kubernetes.io/name: {{ include "trigger-v4.name" . }}
|
||||
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Component labels
|
||||
*/}}
|
||||
{{- define "trigger-v4.componentLabels" -}}
|
||||
{{ include "trigger-v4.labels" . }}
|
||||
app.kubernetes.io/component: {{ .component }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Component selector labels
|
||||
*/}}
|
||||
{{- define "trigger-v4.componentSelectorLabels" -}}
|
||||
{{ include "trigger-v4.selectorLabels" . }}
|
||||
app.kubernetes.io/component: {{ .component }}
|
||||
{{- end }}
|
||||
|
||||
|
||||
{{/*
|
||||
Get the full image name for webapp
|
||||
*/}}
|
||||
{{- define "trigger-v4.image" -}}
|
||||
{{- $registry := .Values.global.imageRegistry | default .Values.webapp.image.registry -}}
|
||||
{{- $repository := .Values.webapp.image.repository -}}
|
||||
{{- $tag := .Values.webapp.image.tag | default .Chart.AppVersion -}}
|
||||
{{- if $registry }}
|
||||
{{- printf "%s/%s:%s" $registry $repository $tag }}
|
||||
{{- else }}
|
||||
{{- printf "%s:%s" $repository $tag }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Get the full image name for supervisor
|
||||
*/}}
|
||||
{{- define "trigger-v4.supervisor.image" -}}
|
||||
{{- $registry := .Values.global.imageRegistry | default .Values.supervisor.image.registry -}}
|
||||
{{- $repository := .Values.supervisor.image.repository -}}
|
||||
{{- $tag := .Values.supervisor.image.tag | default .Chart.AppVersion -}}
|
||||
{{- if $registry }}
|
||||
{{- printf "%s/%s:%s" $registry $repository $tag }}
|
||||
{{- else }}
|
||||
{{- printf "%s:%s" $repository $tag }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Get the full image name for webapp volumePermissions init container
|
||||
*/}}
|
||||
{{- define "trigger-v4.webapp.volumePermissions.image" -}}
|
||||
{{- $registry := .Values.global.imageRegistry | default .Values.webapp.volumePermissions.image.registry -}}
|
||||
{{- $repository := .Values.webapp.volumePermissions.image.repository -}}
|
||||
{{- $tag := .Values.webapp.volumePermissions.image.tag -}}
|
||||
{{- if $registry }}
|
||||
{{- printf "%s/%s:%s" $registry $repository $tag }}
|
||||
{{- else }}
|
||||
{{- printf "%s:%s" $repository $tag }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Get the full image name for webapp tokenSyncer sidecar
|
||||
*/}}
|
||||
{{- define "trigger-v4.webapp.tokenSyncer.image" -}}
|
||||
{{- $registry := .Values.global.imageRegistry | default .Values.webapp.tokenSyncer.image.registry -}}
|
||||
{{- $repository := .Values.webapp.tokenSyncer.image.repository -}}
|
||||
{{- $tag := .Values.webapp.tokenSyncer.image.tag -}}
|
||||
{{- if $registry }}
|
||||
{{- printf "%s/%s:%s" $registry $repository $tag }}
|
||||
{{- else }}
|
||||
{{- printf "%s:%s" $repository $tag }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL hostname (deprecated - used only for legacy DATABASE_HOST env var)
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.hostname" -}}
|
||||
{{- if .Values.postgres.deploy }}
|
||||
{{- printf "%s-postgres" .Release.Name }}
|
||||
{{- else }}
|
||||
{{- "external-postgres" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL connection string (fallback when not using secrets)
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.connectionString" -}}
|
||||
{{- if .Values.postgres.external.databaseUrl -}}
|
||||
{{ .Values.postgres.external.databaseUrl }}
|
||||
{{- else if .Values.postgres.deploy -}}
|
||||
postgresql://{{ .Values.postgres.auth.username }}:{{ .Values.postgres.auth.password }}@{{ include "trigger-v4.postgres.hostname" . }}:5432/{{ .Values.postgres.auth.database }}?schema={{ .Values.postgres.connection.schema | default "public" }}&sslmode={{ .Values.postgres.connection.sslMode | default "prefer" }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Check if we should use DATABASE_URL from secret
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.useSecretUrl" -}}
|
||||
{{- and .Values.postgres.external.existingSecret -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis hostname
|
||||
*/}}
|
||||
{{- define "trigger-v4.redis.hostname" -}}
|
||||
{{- if .Values.redis.external.host }}
|
||||
{{- .Values.redis.external.host }}
|
||||
{{- else if .Values.redis.deploy }}
|
||||
{{- printf "%s-redis-master" .Release.Name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis connection details
|
||||
*/}}
|
||||
{{- define "trigger-v4.redis.host" -}}
|
||||
{{- include "trigger-v4.redis.hostname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "trigger-v4.redis.port" -}}
|
||||
{{- if .Values.redis.external.host -}}
|
||||
{{ .Values.redis.external.port | default 6379 }}
|
||||
{{- else if .Values.redis.deploy -}}
|
||||
6379
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis password
|
||||
*/}}
|
||||
{{- define "trigger-v4.redis.password" -}}
|
||||
{{- if .Values.redis.external.host -}}
|
||||
{{ .Values.redis.external.password }}
|
||||
{{- else if .Values.redis.deploy -}}
|
||||
{{ .Values.redis.auth.password }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis TLS disabled setting
|
||||
*/}}
|
||||
{{- define "trigger-v4.redis.tlsDisabled" -}}
|
||||
{{- if .Values.redis.external.host -}}
|
||||
{{ not (.Values.redis.external.tls.enabled | default false) }}
|
||||
{{- else -}}
|
||||
{{- true -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL external secret name
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.external.secretName" -}}
|
||||
{{- if .Values.postgres.external.existingSecret -}}
|
||||
{{ .Values.postgres.external.existingSecret }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.secretsName" . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL external secret database URL key
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.external.databaseUrlKey" -}}
|
||||
{{- if .Values.postgres.external.existingSecret -}}
|
||||
{{ .Values.postgres.external.secretKeys.databaseUrlKey }}
|
||||
{{- else -}}
|
||||
postgres-database-url
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL external secret direct URL key
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.external.directUrlKey" -}}
|
||||
{{- if .Values.postgres.external.existingSecret -}}
|
||||
{{ .Values.postgres.external.secretKeys.directUrlKey | default .Values.postgres.external.secretKeys.databaseUrlKey }}
|
||||
{{- else -}}
|
||||
postgres-direct-url
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL direct URL (fallback to database URL if not set)
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.directUrl" -}}
|
||||
{{- if .Values.postgres.external.directUrl -}}
|
||||
{{ .Values.postgres.external.directUrl }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.postgres.connectionString" . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis external secret name
|
||||
*/}}
|
||||
{{- define "trigger-v4.redis.external.secretName" -}}
|
||||
{{- if .Values.redis.external.existingSecret -}}
|
||||
{{ .Values.redis.external.existingSecret }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.secretsName" . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Redis external secret password key
|
||||
*/}}
|
||||
{{- define "trigger-v4.redis.external.passwordKey" -}}
|
||||
{{- if .Values.redis.external.existingSecret -}}
|
||||
{{ .Values.redis.external.existingSecretPasswordKey }}
|
||||
{{- else -}}
|
||||
redis-password
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ClickHouse external secret name
|
||||
*/}}
|
||||
{{- define "trigger-v4.clickhouse.external.secretName" -}}
|
||||
{{- if .Values.clickhouse.external.existingSecret -}}
|
||||
{{ .Values.clickhouse.external.existingSecret }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.secretsName" . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ClickHouse external secret password key
|
||||
*/}}
|
||||
{{- define "trigger-v4.clickhouse.external.passwordKey" -}}
|
||||
{{- if .Values.clickhouse.external.existingSecret -}}
|
||||
{{ .Values.clickhouse.external.existingSecretKey }}
|
||||
{{- else -}}
|
||||
clickhouse-password
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 external secret name
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.external.secretName" -}}
|
||||
{{- if .Values.s3.external.existingSecret -}}
|
||||
{{ .Values.s3.external.existingSecret }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.secretsName" . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 external secret access key ID key
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.external.accessKeyIdKey" -}}
|
||||
{{- if .Values.s3.external.existingSecret -}}
|
||||
{{ .Values.s3.external.existingSecretAccessKeyIdKey }}
|
||||
{{- else -}}
|
||||
s3-access-key-id
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 external secret secret access key key
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.external.secretAccessKeyKey" -}}
|
||||
{{- if .Values.s3.external.existingSecret -}}
|
||||
{{ .Values.s3.external.existingSecretSecretAccessKeyKey }}
|
||||
{{- else -}}
|
||||
s3-secret-access-key
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 auth secret name
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.auth.secretName" -}}
|
||||
{{- if .Values.s3.auth.existingSecret -}}
|
||||
{{ .Values.s3.auth.existingSecret }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.secretsName" . }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 auth secret access key ID key
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.auth.accessKeyIdKey" -}}
|
||||
{{- if .Values.s3.auth.existingSecret -}}
|
||||
{{ .Values.s3.auth.accessKeyIdSecretKey }}
|
||||
{{- else -}}
|
||||
s3-auth-access-key-id
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 auth secret secret access key key
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.auth.secretAccessKeyKey" -}}
|
||||
{{- if .Values.s3.auth.existingSecret -}}
|
||||
{{ .Values.s3.auth.secretAccessKeySecretKey }}
|
||||
{{- else -}}
|
||||
s3-auth-secret-access-key
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 auth effective access key ID (with fallback to rootUser)
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.auth.effectiveAccessKeyId" -}}
|
||||
{{- if .Values.s3.auth.accessKeyId -}}
|
||||
{{ .Values.s3.auth.accessKeyId }}
|
||||
{{- else -}}
|
||||
{{ .Values.s3.auth.rootUser }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 auth effective secret access key (with fallback to rootPassword)
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.auth.effectiveSecretAccessKey" -}}
|
||||
{{- if .Values.s3.auth.secretAccessKey -}}
|
||||
{{ .Values.s3.auth.secretAccessKey }}
|
||||
{{- else -}}
|
||||
{{ .Values.s3.auth.rootPassword }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Electric service URL
|
||||
*/}}
|
||||
{{- define "trigger-v4.electric.url" -}}
|
||||
{{- if .Values.electric.deploy -}}
|
||||
http://{{ include "trigger-v4.fullname" . }}-electric:{{ .Values.electric.service.port }}
|
||||
{{- else -}}
|
||||
{{ .Values.electric.external.url }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Whether realtime streams v2 (S2) is wired up: either the bundled s2-lite is
|
||||
deployed, or an external S2 endpoint has been configured.
|
||||
*/}}
|
||||
{{- define "trigger-v4.s2.enabled" -}}
|
||||
{{- if or .Values.s2.deploy .Values.s2.external.endpoint -}}
|
||||
true
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S2 API endpoint URL, including the /v1 suffix expected by the client.
|
||||
*/}}
|
||||
{{- define "trigger-v4.s2.url" -}}
|
||||
{{- if .Values.s2.deploy -}}
|
||||
http://{{ include "trigger-v4.fullname" . }}-s2:{{ .Values.s2.service.port }}/v1
|
||||
{{- else -}}
|
||||
{{ .Values.s2.external.endpoint }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ClickHouse hostname
|
||||
*/}}
|
||||
{{- define "trigger-v4.clickhouse.hostname" -}}
|
||||
{{- if .Values.clickhouse.host }}
|
||||
{{- .Values.clickhouse.host }}
|
||||
{{- else if .Values.clickhouse.deploy }}
|
||||
{{- printf "%s-clickhouse" .Release.Name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ClickHouse URL for application (with secure parameter)
|
||||
|
||||
Note on the external+existingSecret branch: the password is expanded via
|
||||
Kubernetes' `$(VAR)` syntax, not shell `${VAR}`. Kubelet substitutes
|
||||
`$(CLICKHOUSE_PASSWORD)` at container-creation time from the
|
||||
CLICKHOUSE_PASSWORD env var declared just before CLICKHOUSE_URL in
|
||||
webapp.yaml. Shell-style `${...}` does not work here because
|
||||
`docker/scripts/entrypoint.sh` assigns CLICKHOUSE_URL to GOOSE_DBSTRING
|
||||
with a single-pass expansion (`export GOOSE_DBSTRING="$CLICKHOUSE_URL"`),
|
||||
so any inner `${...}` reaches goose verbatim and fails URL parsing.
|
||||
|
||||
CLICKHOUSE_PASSWORD must contain only URL-userinfo-safe characters — the
|
||||
value is substituted verbatim, so `@ : / ? # [ ] %` break the URL. Use a
|
||||
hex-encoded password or percent-encode before storing in the Secret.
|
||||
*/}}
|
||||
{{- define "trigger-v4.clickhouse.url" -}}
|
||||
{{- if .Values.clickhouse.deploy -}}
|
||||
{{- $protocol := ternary "https" "http" .Values.clickhouse.secure -}}
|
||||
{{- $secure := ternary "true" "false" .Values.clickhouse.secure -}}
|
||||
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:{{ .Values.clickhouse.auth.password }}@{{ include "trigger-v4.clickhouse.hostname" . }}:8123?secure={{ $secure }}
|
||||
{{- else if .Values.clickhouse.external.host -}}
|
||||
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
|
||||
{{- $secure := ternary "true" "false" .Values.clickhouse.external.secure -}}
|
||||
{{- if .Values.clickhouse.external.existingSecret -}}
|
||||
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:$(CLICKHOUSE_PASSWORD)@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
|
||||
{{- else -}}
|
||||
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:{{ .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}?secure={{ $secure }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
ClickHouse URL for replication (without secure parameter)
|
||||
|
||||
See the note on clickhouse.url above — same `$(VAR)` vs `${VAR}` rationale
|
||||
applies to the replication URL.
|
||||
*/}}
|
||||
{{- define "trigger-v4.clickhouse.replication.url" -}}
|
||||
{{- if .Values.clickhouse.deploy -}}
|
||||
{{- $protocol := ternary "https" "http" .Values.clickhouse.secure -}}
|
||||
{{ $protocol }}://{{ .Values.clickhouse.auth.username }}:{{ .Values.clickhouse.auth.password }}@{{ include "trigger-v4.clickhouse.hostname" . }}:8123
|
||||
{{- else if .Values.clickhouse.external.host -}}
|
||||
{{- $protocol := ternary "https" "http" .Values.clickhouse.external.secure -}}
|
||||
{{- if .Values.clickhouse.external.existingSecret -}}
|
||||
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:$(CLICKHOUSE_PASSWORD)@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
|
||||
{{- else -}}
|
||||
{{ $protocol }}://{{ .Values.clickhouse.external.username }}:{{ .Values.clickhouse.external.password }}@{{ .Values.clickhouse.external.host }}:{{ .Values.clickhouse.external.httpPort | default 8123 }}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 hostname
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.hostname" -}}
|
||||
{{- if .Values.s3.external.endpoint }}
|
||||
{{- .Values.s3.external.endpoint }}
|
||||
{{- else if .Values.s3.deploy }}
|
||||
{{- printf "http://%s-minio:9000" .Release.Name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
S3 connection details
|
||||
*/}}
|
||||
{{- define "trigger-v4.s3.url" -}}
|
||||
{{- include "trigger-v4.s3.hostname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Backward compatibility - MinIO helpers (deprecated)
|
||||
*/}}
|
||||
{{- define "trigger-v4.minio.hostname" -}}
|
||||
{{- include "trigger-v4.s3.hostname" . }}
|
||||
{{- end }}
|
||||
|
||||
{{- define "trigger-v4.minio.url" -}}
|
||||
{{- include "trigger-v4.s3.url" . }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Get the secrets name - either existing secret or generated name
|
||||
*/}}
|
||||
{{- define "trigger-v4.secretsName" -}}
|
||||
{{- if .Values.secrets.existingSecret -}}
|
||||
{{ .Values.secrets.existingSecret }}
|
||||
{{- else -}}
|
||||
{{ include "trigger-v4.fullname" . }}-secrets
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Registry connection details
|
||||
*/}}
|
||||
{{- define "trigger-v4.registry.host" -}}
|
||||
{{- if .Values.registry.deploy -}}
|
||||
{{ .Values.registry.host }}
|
||||
{{- else -}}
|
||||
{{ .Values.registry.external.host }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Webapp connectivity check enabled
|
||||
*/}}
|
||||
{{- define "trigger-v4.webapp.connectivityCheckEnabled" -}}
|
||||
{{- $connectivityCheckEnabled := true -}}
|
||||
{{- if hasKey .Values.webapp "connectivityCheck" -}}
|
||||
{{- if hasKey .Values.webapp.connectivityCheck "postgres" -}}
|
||||
{{- $connectivityCheckEnabled = .Values.webapp.connectivityCheck.postgres -}}
|
||||
{{- end -}}
|
||||
{{- end -}}
|
||||
{{- $connectivityCheckEnabled -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
PostgreSQL host (for wait-for-it script)
|
||||
*/}}
|
||||
{{- define "trigger-v4.postgres.host" -}}
|
||||
{{- if .Values.postgres.deploy -}}
|
||||
{{ include "trigger-v4.postgres.hostname" . }}:5432
|
||||
{{- else if .Values.postgres.external.connectivityCheck.host -}}
|
||||
{{ .Values.postgres.external.connectivityCheck.host }}
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Supervisor connection details
|
||||
*/}}
|
||||
{{- define "trigger-v4.supervisor.url" -}}
|
||||
{{- if .Values.supervisor.enabled -}}
|
||||
http://{{ include "trigger-v4.fullname" . }}-supervisor:{{ .Values.supervisor.service.ports.workload }}
|
||||
{{- else -}}
|
||||
""
|
||||
{{- end -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the supervisor service account to use.
|
||||
When create is false, name must be set explicitly - falling back to the namespace's
|
||||
default ServiceAccount would silently grant it the RoleBinding's permissions.
|
||||
*/}}
|
||||
{{- define "trigger-v4.supervisorServiceAccountName" -}}
|
||||
{{- if .Values.supervisor.serviceAccount.create }}
|
||||
{{- default (printf "%s-supervisor" (include "trigger-v4.fullname" .)) .Values.supervisor.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- if not .Values.supervisor.serviceAccount.name }}
|
||||
{{- fail "supervisor.serviceAccount.name must be set when supervisor.serviceAccount.create is false" }}
|
||||
{{- end }}
|
||||
{{- .Values.supervisor.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the webapp service account to use.
|
||||
When create is false, name must be set explicitly - falling back to the namespace's
|
||||
default ServiceAccount would silently grant it the token-syncer RoleBinding's permissions.
|
||||
*/}}
|
||||
{{- define "trigger-v4.webappServiceAccountName" -}}
|
||||
{{- if .Values.webapp.serviceAccount.create }}
|
||||
{{- default (printf "%s-webapp" (include "trigger-v4.fullname" .)) .Values.webapp.serviceAccount.name }}
|
||||
{{- else }}
|
||||
{{- if not .Values.webapp.serviceAccount.name }}
|
||||
{{- fail "webapp.serviceAccount.name must be set when webapp.serviceAccount.create is false" }}
|
||||
{{- end }}
|
||||
{{- .Values.webapp.serviceAccount.name }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Create the name of the supervisor role to use
|
||||
*/}}
|
||||
{{- define "trigger-v4.supervisorRoleName" -}}
|
||||
{{- default (printf "%s-supervisor-%s" (include "trigger-v4.fullname" .) .Release.Namespace) .Values.supervisor.rbac.role.name }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Generate docker config for image pull secret
|
||||
*/}}
|
||||
{{- define "trigger-v4.imagePullSecret" }}
|
||||
{{- if and .Values.registry.deploy .Values.registry.auth.enabled }}
|
||||
{{- $registryHost := include "trigger-v4.registry.host" . }}
|
||||
{{- $username := .Values.registry.auth.username }}
|
||||
{{- $password := .Values.registry.auth.password }}
|
||||
{{- $auth := printf "%s:%s" $username $password | b64enc }}
|
||||
{{- $config := dict "auths" (dict $registryHost (dict "username" $username "password" $password "auth" $auth)) }}
|
||||
{{- $config | toJson }}
|
||||
{{- else if and (not .Values.registry.deploy) .Values.registry.external.auth.enabled }}
|
||||
{{- $registryHost := .Values.registry.external.host }}
|
||||
{{- $username := .Values.registry.external.auth.username }}
|
||||
{{- $password := .Values.registry.external.auth.password }}
|
||||
{{- $auth := printf "%s:%s" $username $password | b64enc }}
|
||||
{{- $config := dict "auths" (dict $registryHost (dict "username" $username "password" $password "auth" $auth)) }}
|
||||
{{- $config | toJson }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Merge webapp ingress annotations to avoid duplicates
|
||||
*/}}
|
||||
{{- define "trigger-v4.webapp.ingress.annotations" -}}
|
||||
{{- $annotations := dict -}}
|
||||
{{- if .Values.webapp.ingress.annotations -}}
|
||||
{{- $annotations = .Values.webapp.ingress.annotations -}}
|
||||
{{- end -}}
|
||||
{{- if .Values.webapp.ingress.certManager.enabled -}}
|
||||
{{- $_ := set $annotations "cert-manager.io/cluster-issuer" .Values.webapp.ingress.certManager.clusterIssuer -}}
|
||||
{{- end -}}
|
||||
{{- if .Values.webapp.ingress.externalDns.enabled -}}
|
||||
{{- $_ := set $annotations "external-dns.alpha.kubernetes.io/hostname" .Values.webapp.ingress.externalDns.hostname -}}
|
||||
{{- $_ := set $annotations "external-dns.alpha.kubernetes.io/ttl" (.Values.webapp.ingress.externalDns.ttl | toString) -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $annotations -}}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
Merge registry ingress annotations to avoid duplicates
|
||||
*/}}
|
||||
{{- define "trigger-v4.registry.ingress.annotations" -}}
|
||||
{{- $annotations := dict -}}
|
||||
{{- if .Values.registry.ingress.annotations -}}
|
||||
{{- $annotations = .Values.registry.ingress.annotations -}}
|
||||
{{- end -}}
|
||||
{{- if .Values.registry.ingress.certManager.enabled -}}
|
||||
{{- $_ := set $annotations "cert-manager.io/cluster-issuer" .Values.registry.ingress.certManager.clusterIssuer -}}
|
||||
{{- end -}}
|
||||
{{- if .Values.registry.ingress.externalDns.enabled -}}
|
||||
{{- $_ := set $annotations "external-dns.alpha.kubernetes.io/hostname" .Values.registry.ingress.externalDns.hostname -}}
|
||||
{{- $_ := set $annotations "external-dns.alpha.kubernetes.io/ttl" (.Values.registry.ingress.externalDns.ttl | toString) -}}
|
||||
{{- end -}}
|
||||
{{- toYaml $annotations -}}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,109 @@
|
||||
{{- if .Values.electric.deploy }}
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-electric
|
||||
labels:
|
||||
{{- $component := "electric" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.electric.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.electric.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: electric
|
||||
{{- with .Values.electric.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.electric.image.registry }}/{{ .Values.electric.image.repository }}:{{ .Values.electric.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.electric.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.electric.service.targetPort }}
|
||||
protocol: TCP
|
||||
env:
|
||||
{{- 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" . }}
|
||||
{{- else }}
|
||||
- name: DATABASE_URL
|
||||
value: {{ include "trigger-v4.postgres.connectionString" . | quote }}
|
||||
{{- end }}
|
||||
- name: ELECTRIC_INSECURE
|
||||
value: {{ .Values.electric.config.insecure | quote }}
|
||||
- name: ELECTRIC_USAGE_REPORTING
|
||||
value: {{ .Values.electric.config.usageReporting | quote }}
|
||||
{{- with .Values.electric.extraEnvVars }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if .Values.electric.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /v1/health
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.electric.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.electric.livenessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.electric.livenessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.electric.livenessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.electric.livenessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.electric.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /v1/health
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.electric.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.electric.readinessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.electric.readinessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.electric.readinessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.electric.readinessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.electric.startupProbe.enabled }}
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /v1/health
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.electric.startupProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.electric.startupProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.electric.startupProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.electric.startupProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.electric.startupProbe.successThreshold }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.electric.resources | nindent 12 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-electric
|
||||
labels:
|
||||
{{- $component := "electric" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.electric.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.electric.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,4 @@
|
||||
{{- range .Values.extraManifests }}
|
||||
---
|
||||
{{ toYaml . }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if and .Values.registry.deploy .Values.registry.ingress.enabled -}}
|
||||
{{- $fullName := include "trigger-v4.fullname" . -}}
|
||||
{{- $svcPort := .Values.registry.service.port -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-registry
|
||||
labels:
|
||||
{{- $component := "registry" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "trigger-v4.registry.ingress.annotations" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Values.registry.ingress.className }}
|
||||
ingressClassName: {{ .Values.registry.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.registry.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.registry.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- if .paths }}
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType | default "Prefix" }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}-registry
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}-registry
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,182 @@
|
||||
{{- if .Values.registry.deploy }}
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-registry
|
||||
labels:
|
||||
{{- $component := "registry" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: {{ include "trigger-v4.fullname" . }}-registry-headless
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
{{- with .Values.registry.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.registry.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: registry
|
||||
{{- with .Values.registry.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.registry.image.registry }}/{{ .Values.registry.image.repository }}:{{ .Values.registry.image.tag }}"
|
||||
imagePullPolicy: {{ .Values.registry.image.pullPolicy }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.registry.service.targetPort }}
|
||||
protocol: TCP
|
||||
{{- if or .Values.registry.auth.enabled .Values.registry.extraEnvVars }}
|
||||
env:
|
||||
{{- if .Values.registry.auth.enabled }}
|
||||
- name: REGISTRY_AUTH
|
||||
value: "htpasswd"
|
||||
- name: REGISTRY_AUTH_HTPASSWD_REALM
|
||||
value: "Registry Realm"
|
||||
- name: REGISTRY_AUTH_HTPASSWD_PATH
|
||||
value: "/auth/htpasswd"
|
||||
{{- end }}
|
||||
{{- with .Values.registry.extraEnvVars }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.registry.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.registry.livenessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.registry.livenessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.registry.livenessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.registry.livenessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.registry.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.registry.readinessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.registry.readinessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.registry.readinessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.registry.readinessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.startupProbe.enabled }}
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.registry.startupProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.registry.startupProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.registry.startupProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.registry.startupProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.registry.startupProbe.successThreshold }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.registry.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: {{ .Values.registry.persistence.volumeName }}
|
||||
mountPath: {{ .Values.registry.persistence.mountPath }}
|
||||
{{- if .Values.registry.persistence.subPath }}
|
||||
subPath: {{ .Values.registry.persistence.subPath }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.auth.enabled }}
|
||||
- name: registry-auth
|
||||
mountPath: /auth
|
||||
readOnly: true
|
||||
{{- end }}
|
||||
volumes:
|
||||
{{- if .Values.registry.auth.enabled }}
|
||||
- name: registry-auth
|
||||
secret:
|
||||
secretName: {{ include "trigger-v4.fullname" . }}-registry-auth
|
||||
{{- end }}
|
||||
{{- if not .Values.registry.persistence.enabled }}
|
||||
- name: {{ .Values.registry.persistence.volumeName }}
|
||||
emptyDir: {}
|
||||
{{- else if .Values.registry.persistence.existingClaim }}
|
||||
- name: {{ .Values.registry.persistence.volumeName }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ .Values.registry.persistence.existingClaim }}
|
||||
{{- end }}
|
||||
{{- if .Values.registry.persistence.enabled }}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: {{ .Values.registry.persistence.volumeName }}
|
||||
{{- with .Values.registry.persistence.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- $component := "registry" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 10 }}
|
||||
{{- with .Values.registry.persistence.labels }}
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
{{- toYaml .Values.registry.persistence.accessModes | nindent 10 }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.registry.persistence.size }}
|
||||
{{- $storageClass := .Values.registry.persistence.storageClass | default .Values.global.storageClass }}
|
||||
{{- if $storageClass }}
|
||||
storageClassName: {{ $storageClass | quote }}
|
||||
{{- end }}
|
||||
{{- with .Values.registry.persistence.selector }}
|
||||
selector:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- with .Values.registry.persistence.dataSource }}
|
||||
dataSource:
|
||||
{{- toYaml . | nindent 10 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-registry-headless
|
||||
labels:
|
||||
{{- $component := "registry" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
type: ClusterIP
|
||||
clusterIP: None
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.registry.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
selector:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-registry
|
||||
labels:
|
||||
{{- $component := "registry" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.registry.service.type }}
|
||||
ports:
|
||||
- name: http
|
||||
port: {{ .Values.registry.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
selector:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,142 @@
|
||||
{{- if .Values.s2.deploy }}
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-s2-spec
|
||||
labels:
|
||||
{{- $component := "s2" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
data:
|
||||
s2-spec.json: |
|
||||
{
|
||||
"$schema": "https://raw.githubusercontent.com/s2-streamstore/s2/main/cli/schema.json",
|
||||
"basins": [
|
||||
{
|
||||
"name": {{ .Values.s2.basin | quote }},
|
||||
"config": {
|
||||
"create_stream_on_append": true,
|
||||
"create_stream_on_read": true
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-s2
|
||||
labels:
|
||||
{{- $component := "s2" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
serviceName: {{ include "trigger-v4.fullname" . }}-s2
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
annotations:
|
||||
checksum/spec: {{ .Values.s2.basin | sha256sum }}
|
||||
{{- with .Values.s2.podAnnotations }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
labels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 8 }}
|
||||
spec:
|
||||
{{- with .Values.s2.podSecurityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: s2
|
||||
{{- with .Values.s2.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
image: "{{ .Values.s2.image.registry }}/{{ .Values.s2.image.repository }}:{{ .Values.s2.image.tag }}{{ with .Values.s2.image.digest }}@{{ . }}{{ end }}"
|
||||
imagePullPolicy: {{ .Values.s2.image.pullPolicy }}
|
||||
command:
|
||||
- "lite"
|
||||
- "--init-file"
|
||||
- "/config/s2-spec.json"
|
||||
- "--local-root"
|
||||
- "/data"
|
||||
- "--port"
|
||||
- {{ .Values.s2.service.targetPort | quote }}
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: {{ .Values.s2.service.targetPort }}
|
||||
protocol: TCP
|
||||
{{- if .Values.s2.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.s2.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.s2.livenessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.s2.livenessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.s2.livenessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.s2.livenessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.s2.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
tcpSocket:
|
||||
port: http
|
||||
initialDelaySeconds: {{ .Values.s2.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.s2.readinessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.s2.readinessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.s2.readinessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.s2.readinessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.s2.resources | nindent 12 }}
|
||||
volumeMounts:
|
||||
- name: spec
|
||||
mountPath: /config
|
||||
readOnly: true
|
||||
- name: data
|
||||
mountPath: /data
|
||||
volumes:
|
||||
- name: spec
|
||||
configMap:
|
||||
name: {{ include "trigger-v4.fullname" . }}-s2-spec
|
||||
{{- if not .Values.s2.persistence.enabled }}
|
||||
- name: data
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- if .Values.s2.persistence.enabled }}
|
||||
volumeClaimTemplates:
|
||||
- metadata:
|
||||
name: data
|
||||
{{- if .Values.s2.persistence.retain }}
|
||||
annotations:
|
||||
helm.sh/resource-policy: keep
|
||||
{{- end }}
|
||||
spec:
|
||||
accessModes:
|
||||
- {{ .Values.s2.persistence.accessMode }}
|
||||
resources:
|
||||
requests:
|
||||
storage: {{ .Values.s2.persistence.size }}
|
||||
{{- if .Values.s2.persistence.storageClass }}
|
||||
storageClassName: {{ .Values.s2.persistence.storageClass }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-s2
|
||||
labels:
|
||||
{{- $component := "s2" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.s2.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.s2.service.port }}
|
||||
targetPort: http
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,68 @@
|
||||
{{- if and .Values.secrets.enabled (not .Values.secrets.existingSecret) }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-secrets
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
SESSION_SECRET: {{ .Values.secrets.sessionSecret | b64enc | quote }}
|
||||
MAGIC_LINK_SECRET: {{ .Values.secrets.magicLinkSecret | b64enc | quote }}
|
||||
ENCRYPTION_KEY: {{ .Values.secrets.encryptionKey | b64enc | quote }}
|
||||
MANAGED_WORKER_SECRET: {{ .Values.secrets.managedWorkerSecret | b64enc | quote }}
|
||||
{{- if and .Values.s3.external.accessKeyId (not .Values.s3.external.existingSecret) }}
|
||||
s3-access-key-id: {{ .Values.s3.external.accessKeyId | b64enc | quote }}
|
||||
s3-secret-access-key: {{ .Values.s3.external.secretAccessKey | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- if and .Values.s3.deploy (not .Values.s3.auth.existingSecret) }}
|
||||
s3-auth-access-key-id: {{ include "trigger-v4.s3.auth.effectiveAccessKeyId" . | b64enc | quote }}
|
||||
s3-auth-secret-access-key: {{ include "trigger-v4.s3.auth.effectiveSecretAccessKey" . | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- if and .Values.postgres.external.databaseUrl (not .Values.postgres.external.existingSecret) }}
|
||||
postgres-database-url: {{ .Values.postgres.external.databaseUrl | b64enc | quote }}
|
||||
{{- if .Values.postgres.external.directUrl }}
|
||||
postgres-direct-url: {{ .Values.postgres.external.directUrl | b64enc | quote }}
|
||||
{{- else }}
|
||||
postgres-direct-url: {{ .Values.postgres.external.databaseUrl | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- if and .Values.redis.external.host (not .Values.redis.external.existingSecret) .Values.redis.external.password }}
|
||||
redis-password: {{ .Values.redis.external.password | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- if and .Values.clickhouse.external.host (not .Values.clickhouse.external.existingSecret) .Values.clickhouse.external.password }}
|
||||
clickhouse-password: {{ .Values.clickhouse.external.password | b64enc | quote }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if and .Values.registry.deploy .Values.registry.auth.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-registry-auth
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
type: Opaque
|
||||
data:
|
||||
htpasswd: {{ htpasswd .Values.registry.auth.username .Values.registry.auth.password | trim | b64enc | quote }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-registry-secret
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: {{ include "trigger-v4.imagePullSecret" . | b64enc }}
|
||||
{{- else if and (not .Values.registry.deploy) .Values.registry.external.auth.enabled }}
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-registry-secret
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: {{ include "trigger-v4.imagePullSecret" . | b64enc }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,55 @@
|
||||
{{- if .Values.webapp.serviceMonitor.enabled }}
|
||||
---
|
||||
# Webapp ServiceMonitor
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-webapp
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: webapp
|
||||
{{- with .Values.webapp.serviceMonitor.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trigger-v4.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: webapp
|
||||
endpoints:
|
||||
- port: http
|
||||
path: {{ .Values.webapp.serviceMonitor.path }}
|
||||
interval: {{ .Values.webapp.serviceMonitor.interval }}
|
||||
{{- with .Values.webapp.serviceMonitor.basicAuth }}
|
||||
basicAuth:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.supervisor.serviceMonitor.enabled }}
|
||||
---
|
||||
# Supervisor ServiceMonitor
|
||||
apiVersion: monitoring.coreos.com/v1
|
||||
kind: ServiceMonitor
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-supervisor
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
app.kubernetes.io/component: supervisor
|
||||
{{- with .Values.supervisor.serviceMonitor.labels }}
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trigger-v4.selectorLabels" . | nindent 6 }}
|
||||
app.kubernetes.io/component: supervisor
|
||||
endpoints:
|
||||
- port: metrics
|
||||
path: {{ .Values.supervisor.serviceMonitor.path }}
|
||||
interval: {{ .Values.supervisor.serviceMonitor.interval }}
|
||||
{{- with .Values.supervisor.serviceMonitor.basicAuth }}
|
||||
basicAuth:
|
||||
{{- toYaml . | nindent 6 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,295 @@
|
||||
{{- if .Values.supervisor.serviceAccount.create }}
|
||||
apiVersion: v1
|
||||
kind: ServiceAccount
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.supervisorServiceAccountName" . }}
|
||||
labels:
|
||||
{{- $component := "supervisor" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
{{- with .Values.supervisor.serviceAccount.annotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 4 }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
---
|
||||
{{- if .Values.supervisor.rbac.create }}
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: Role
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.supervisorRoleName" . }}
|
||||
namespace: {{ default .Release.Namespace .Values.supervisor.config.kubernetes.namespace }}
|
||||
labels:
|
||||
{{- $component := "supervisor" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
rules:
|
||||
- apiGroups: [""]
|
||||
resources: ["pods"]
|
||||
verbs: ["create", "delete", "deletecollection", "get", "list", "watch"]
|
||||
---
|
||||
apiVersion: rbac.authorization.k8s.io/v1
|
||||
kind: RoleBinding
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.supervisorRoleName" . }}-binding
|
||||
namespace: {{ default .Release.Namespace .Values.supervisor.config.kubernetes.namespace }}
|
||||
labels:
|
||||
{{- $component := "supervisor" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
subjects:
|
||||
- kind: ServiceAccount
|
||||
name: {{ include "trigger-v4.supervisorServiceAccountName" . }}
|
||||
namespace: {{ default .Release.Namespace }}
|
||||
roleRef:
|
||||
kind: Role
|
||||
name: {{ include "trigger-v4.supervisorRoleName" . }}
|
||||
apiGroup: rbac.authorization.k8s.io
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-supervisor
|
||||
labels:
|
||||
{{- $component := "supervisor" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
replicas: 1
|
||||
strategy:
|
||||
type: RollingUpdate
|
||||
rollingUpdate:
|
||||
maxUnavailable: 0
|
||||
maxSurge: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 6 }}
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 8 }}
|
||||
{{- with .Values.supervisor.podAnnotations }}
|
||||
annotations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
spec:
|
||||
serviceAccountName: {{ include "trigger-v4.supervisorServiceAccountName" . }}
|
||||
securityContext:
|
||||
fsGroup: 1000
|
||||
{{- with .Values.supervisor.podSecurityContext }}
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.webapp.bootstrap.enabled }}
|
||||
initContainers:
|
||||
- name: init-shared
|
||||
image: busybox:1.35
|
||||
command: ['sh', '-c', 'mkdir -p /home/node/shared']
|
||||
securityContext:
|
||||
runAsUser: 1000
|
||||
volumeMounts:
|
||||
- name: shared
|
||||
mountPath: /home/node/shared
|
||||
{{- end }}
|
||||
containers:
|
||||
- name: supervisor
|
||||
image: {{ include "trigger-v4.supervisor.image" . }}
|
||||
imagePullPolicy: {{ .Values.supervisor.image.pullPolicy }}
|
||||
ports:
|
||||
- name: workload
|
||||
containerPort: {{ .Values.supervisor.service.ports.workload }}
|
||||
protocol: TCP
|
||||
- name: metrics
|
||||
containerPort: {{ .Values.supervisor.service.ports.metrics }}
|
||||
protocol: TCP
|
||||
{{- if .Values.supervisor.livenessProbe.enabled }}
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: workload
|
||||
initialDelaySeconds: {{ .Values.supervisor.livenessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.supervisor.livenessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.supervisor.livenessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.supervisor.livenessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.supervisor.livenessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.supervisor.readinessProbe.enabled }}
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: workload
|
||||
initialDelaySeconds: {{ .Values.supervisor.readinessProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.supervisor.readinessProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.supervisor.readinessProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.supervisor.readinessProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.supervisor.readinessProbe.successThreshold }}
|
||||
{{- end }}
|
||||
{{- if .Values.supervisor.startupProbe.enabled }}
|
||||
startupProbe:
|
||||
httpGet:
|
||||
path: /health
|
||||
port: workload
|
||||
initialDelaySeconds: {{ .Values.supervisor.startupProbe.initialDelaySeconds }}
|
||||
periodSeconds: {{ .Values.supervisor.startupProbe.periodSeconds }}
|
||||
timeoutSeconds: {{ .Values.supervisor.startupProbe.timeoutSeconds }}
|
||||
failureThreshold: {{ .Values.supervisor.startupProbe.failureThreshold }}
|
||||
successThreshold: {{ .Values.supervisor.startupProbe.successThreshold }}
|
||||
{{- end }}
|
||||
resources:
|
||||
{{- toYaml .Values.supervisor.resources | nindent 12 }}
|
||||
env:
|
||||
# Core configuration
|
||||
- name: TRIGGER_API_URL
|
||||
value: "http://{{ include "trigger-v4.fullname" . }}-webapp:{{ .Values.webapp.service.port }}"
|
||||
- name: TRIGGER_WORKER_TOKEN
|
||||
{{- if .Values.webapp.bootstrap.enabled }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "trigger-v4.fullname" . }}-worker-token
|
||||
key: token
|
||||
{{- else if .Values.supervisor.bootstrap.workerToken.secret.name }}
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ .Values.supervisor.bootstrap.workerToken.secret.name }}
|
||||
key: {{ .Values.supervisor.bootstrap.workerToken.secret.key }}
|
||||
{{- else }}
|
||||
value: {{ .Values.supervisor.bootstrap.workerToken.value | quote }}
|
||||
{{- end }}
|
||||
{{- if or .Values.secrets.enabled .Values.secrets.existingSecret }}
|
||||
- name: MANAGED_WORKER_SECRET
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: {{ include "trigger-v4.secretsName" . }}
|
||||
key: MANAGED_WORKER_SECRET
|
||||
{{- end }}
|
||||
# Worker instance configuration
|
||||
- name: TRIGGER_WORKER_INSTANCE_NAME
|
||||
valueFrom:
|
||||
fieldRef:
|
||||
fieldPath: spec.nodeName
|
||||
# Kubernetes configuration
|
||||
- name: KUBERNETES_NAMESPACE
|
||||
value: {{ default .Release.Namespace .Values.supervisor.config.kubernetes.namespace | quote }}
|
||||
- name: KUBERNETES_FORCE_ENABLED
|
||||
value: {{ .Values.supervisor.config.kubernetes.forceEnabled | quote }}
|
||||
- name: KUBERNETES_WORKER_NODETYPE_LABEL
|
||||
value: {{ .Values.supervisor.config.kubernetes.workerNodetypeLabel | quote }}
|
||||
{{- $registryAuthEnabled := false }}
|
||||
{{- if .Values.registry.deploy }}
|
||||
{{- $registryAuthEnabled = .Values.registry.auth.enabled }}
|
||||
{{- else }}
|
||||
{{- $registryAuthEnabled = .Values.registry.external.auth.enabled }}
|
||||
{{- end }}
|
||||
{{- if $registryAuthEnabled }}
|
||||
- name: KUBERNETES_IMAGE_PULL_SECRETS
|
||||
value: "{{ include "trigger-v4.fullname" . }}-registry-secret"
|
||||
{{- end }}
|
||||
- name: KUBERNETES_EPHEMERAL_STORAGE_SIZE_LIMIT
|
||||
value: {{ default "10Gi" .Values.supervisor.config.kubernetes.ephemeralStorageSizeLimit | quote }}
|
||||
- name: KUBERNETES_EPHEMERAL_STORAGE_SIZE_REQUEST
|
||||
value: {{ default "2Gi" .Values.supervisor.config.kubernetes.ephemeralStorageSizeRequest | quote }}
|
||||
# Pod cleaner configuration
|
||||
- name: POD_CLEANER_ENABLED
|
||||
value: {{ .Values.supervisor.config.podCleaner.enabled | quote }}
|
||||
- name: POD_CLEANER_BATCH_SIZE
|
||||
value: {{ .Values.supervisor.config.podCleaner.batchSize | quote }}
|
||||
- name: POD_CLEANER_INTERVAL_MS
|
||||
value: {{ .Values.supervisor.config.podCleaner.intervalMs | quote }}
|
||||
# Failed pod handler
|
||||
- name: FAILED_POD_HANDLER_ENABLED
|
||||
value: {{ .Values.supervisor.config.failedPodHandler.enabled | quote }}
|
||||
- name: FAILED_POD_HANDLER_RECONNECT_INTERVAL_MS
|
||||
value: {{ .Values.supervisor.config.failedPodHandler.reconnectIntervalMs | quote }}
|
||||
# Workload API configuration
|
||||
- name: TRIGGER_WORKLOAD_API_PROTOCOL
|
||||
value: {{ .Values.supervisor.config.workloadApi.protocol | quote }}
|
||||
- name: TRIGGER_WORKLOAD_API_DOMAIN
|
||||
value: "{{ include "trigger-v4.fullname" . }}-supervisor.{{ .Release.Namespace }}.svc.cluster.local"
|
||||
- name: TRIGGER_WORKLOAD_API_PORT_EXTERNAL
|
||||
value: {{ .Values.supervisor.config.workloadApi.portExternal | quote }}
|
||||
- name: TRIGGER_WORKLOAD_API_PORT_INTERNAL
|
||||
value: {{ .Values.supervisor.config.workloadApi.portInternal | quote }}
|
||||
- name: TRIGGER_WORKLOAD_API_HOST_INTERNAL
|
||||
value: {{ .Values.supervisor.config.workloadApi.hostInternal | quote }}
|
||||
- name: TRIGGER_WORKLOAD_API_ENABLED
|
||||
value: {{ .Values.supervisor.config.workloadApi.enabled | quote }}
|
||||
# Dequeue configuration
|
||||
- name: TRIGGER_DEQUEUE_ENABLED
|
||||
value: {{ .Values.supervisor.config.dequeue.enabled | quote }}
|
||||
- name: TRIGGER_DEQUEUE_INTERVAL_MS
|
||||
value: {{ .Values.supervisor.config.dequeue.intervalMs | quote }}
|
||||
- name: TRIGGER_DEQUEUE_MAX_RUN_COUNT
|
||||
value: {{ .Values.supervisor.config.dequeue.maxRunCount | quote }}
|
||||
- name: TRIGGER_DEQUEUE_IDLE_INTERVAL_MS
|
||||
value: {{ .Values.supervisor.config.dequeue.idleIntervalMs | quote }}
|
||||
# Heartbeat configuration
|
||||
- name: RUNNER_HEARTBEAT_INTERVAL_SECONDS
|
||||
value: {{ .Values.supervisor.config.runner.heartbeatIntervalSeconds | quote }}
|
||||
- name: RUNNER_SNAPSHOT_POLL_INTERVAL_SECONDS
|
||||
value: {{ .Values.supervisor.config.runner.snapshotPollIntervalSeconds | quote }}
|
||||
# Metrics configuration
|
||||
- name: METRICS_ENABLED
|
||||
value: {{ .Values.supervisor.config.metrics.enabled | quote }}
|
||||
- name: METRICS_COLLECT_DEFAULTS
|
||||
value: {{ .Values.supervisor.config.metrics.collectDefaults | quote }}
|
||||
- name: METRICS_HOST
|
||||
value: {{ .Values.supervisor.config.metrics.host | quote }}
|
||||
- name: METRICS_PORT
|
||||
value: {{ .Values.supervisor.config.metrics.port | quote }}
|
||||
# Debug
|
||||
- name: DEBUG
|
||||
value: {{ .Values.supervisor.config.debug | quote }}
|
||||
# OTEL
|
||||
- name: OTEL_EXPORTER_OTLP_ENDPOINT
|
||||
value: "http://{{ include "trigger-v4.fullname" . }}-webapp.{{ .Release.Namespace }}.svc.cluster.local:{{ .Values.webapp.service.port }}/otel"
|
||||
{{- with .Values.supervisor.extraEnvVars }}
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.webapp.bootstrap.enabled }}
|
||||
volumeMounts:
|
||||
- name: shared
|
||||
mountPath: /home/node/shared
|
||||
{{- end }}
|
||||
{{- with .Values.supervisor.securityContext }}
|
||||
securityContext:
|
||||
{{- toYaml . | nindent 12 }}
|
||||
{{- end }}
|
||||
{{- if not .Values.webapp.bootstrap.enabled }}
|
||||
volumes:
|
||||
- name: shared
|
||||
{{- if .Values.persistence.shared.enabled }}
|
||||
persistentVolumeClaim:
|
||||
claimName: {{ include "trigger-v4.fullname" . }}-shared
|
||||
{{- else }}
|
||||
emptyDir: {}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- with .Values.supervisor.nodeSelector }}
|
||||
nodeSelector:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.supervisor.affinity }}
|
||||
affinity:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
{{- with .Values.supervisor.tolerations }}
|
||||
tolerations:
|
||||
{{- toYaml . | nindent 8 }}
|
||||
{{- end }}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-supervisor
|
||||
labels:
|
||||
{{- $component := "supervisor" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
spec:
|
||||
type: {{ .Values.supervisor.service.type }}
|
||||
ports:
|
||||
- port: {{ .Values.supervisor.service.ports.workload }}
|
||||
targetPort: workload
|
||||
protocol: TCP
|
||||
name: workload
|
||||
- port: {{ .Values.supervisor.service.ports.metrics }}
|
||||
targetPort: metrics
|
||||
protocol: TCP
|
||||
name: metrics
|
||||
selector:
|
||||
{{- include "trigger-v4.componentSelectorLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.clickhouse.deploy }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-clickhouse"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-clickhouse
|
||||
image: curlimages/curl:8.14.1
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing ClickHouse HTTP interface..."
|
||||
curl -f --user "{{ .Values.clickhouse.auth.adminUser }}:{{ .Values.clickhouse.auth.adminPassword }}" "http://{{ include "trigger-v4.fullname" . }}-clickhouse:{{ .Values.clickhouse.service.ports.http }}/ping"
|
||||
echo "ClickHouse test completed successfully"
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.electric.deploy }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-electric"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-electric
|
||||
image: curlimages/curl:8.14.1
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing Electric health endpoint..."
|
||||
curl -f http://{{ include "trigger-v4.fullname" . }}-electric:{{ .Values.electric.service.port }}/api/status
|
||||
echo "Electric test completed successfully"
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.postgres.deploy }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-postgres"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-postgres
|
||||
image: {{ .Values.postgres.image.registry }}/{{ .Values.postgres.image.repository }}:{{ .Values.postgres.image.tag }}
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing PostgreSQL connection..."
|
||||
pg_isready -h {{ include "trigger-v4.fullname" . }}-postgres -p {{ .Values.postgres.primary.service.ports.postgres }} -U {{ .Values.postgres.auth.username }}
|
||||
echo "PostgreSQL test completed successfully"
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.redis.deploy }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-redis"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-redis
|
||||
image: {{ .Values.redis.image.registry }}/{{ .Values.redis.image.repository }}:{{ .Values.redis.image.tag }}
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing Redis connection..."
|
||||
redis-cli -h {{ include "trigger-v4.fullname" . }}-redis-master -p {{ .Values.redis.master.service.ports.redis }} ping
|
||||
echo "Redis test completed successfully"
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.s3.deploy }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-s3"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-s3
|
||||
image: curlimages/curl:8.14.1
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing S3 (MinIO) health endpoint..."
|
||||
curl -f http://{{ include "trigger-v4.fullname" . }}-minio:9000/minio/health/live
|
||||
echo "S3 test completed successfully"
|
||||
{{- end }}
|
||||
@@ -0,0 +1,21 @@
|
||||
{{- if .Values.supervisor.deploy }}
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-supervisor"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-supervisor
|
||||
image: curlimages/curl:8.14.1
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing Supervisor metrics endpoint..."
|
||||
curl -f http://{{ include "trigger-v4.fullname" . }}-supervisor:{{ .Values.supervisor.service.ports.metrics }}/metrics
|
||||
echo "Supervisor test completed successfully"
|
||||
{{- end }}
|
||||
@@ -0,0 +1,19 @@
|
||||
apiVersion: v1
|
||||
kind: Pod
|
||||
metadata:
|
||||
name: "{{ include "trigger-v4.fullname" . }}-test-webapp"
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
"helm.sh/hook": test
|
||||
spec:
|
||||
restartPolicy: Never
|
||||
containers:
|
||||
- name: test-webapp
|
||||
image: curlimages/curl:8.14.1
|
||||
command: ['sh', '-c']
|
||||
args:
|
||||
- |
|
||||
echo "Testing webapp health endpoint..."
|
||||
curl -f http://{{ include "trigger-v4.fullname" . }}-webapp:{{ .Values.webapp.service.port }}/healthcheck
|
||||
echo "Webapp test completed successfully"
|
||||
@@ -0,0 +1,67 @@
|
||||
{{/*
|
||||
Validation template to ensure external service configurations are provided when deploy: false
|
||||
This template will fail the Helm deployment if external config is missing for required services
|
||||
*/}}
|
||||
{{- if not .Values.postgres.deploy }}
|
||||
{{- if and (not .Values.postgres.external.databaseUrl) (not .Values.postgres.external.existingSecret) }}
|
||||
{{- fail "PostgreSQL external configuration is required when postgres.deploy=false. Please provide either postgres.external.databaseUrl or postgres.external.existingSecret" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if not .Values.redis.deploy }}
|
||||
{{- if not .Values.redis.external.host }}
|
||||
{{- fail "Redis external configuration is required when redis.deploy=false. Please provide redis.external.host" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if not .Values.clickhouse.deploy }}
|
||||
{{- if or (not .Values.clickhouse.external.host) (not .Values.clickhouse.external.username) }}
|
||||
{{- fail "ClickHouse external configuration is required when clickhouse.deploy=false. Please provide clickhouse.external.host and clickhouse.external.username" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if .Values.s3.deploy }}
|
||||
{{- if and (not .Values.s3.auth.existingSecret) (not .Values.s3.auth.accessKeyId) (not .Values.s3.auth.rootUser) }}
|
||||
{{- fail "S3 auth credentials are required when s3.deploy=true. Please provide either s3.auth.accessKeyId, s3.auth.existingSecret, or s3.auth.rootUser" }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
{{- if not .Values.s3.external.endpoint }}
|
||||
{{- fail "S3 external configuration is required when s3.deploy=false. Please provide s3.external.endpoint" }}
|
||||
{{- end }}
|
||||
{{- if and (not .Values.s3.external.existingSecret) (or (not .Values.s3.external.accessKeyId) (not .Values.s3.external.secretAccessKey)) }}
|
||||
{{- fail "S3 credentials are required when s3.deploy=false. Please provide either s3.external.existingSecret or both s3.external.accessKeyId and s3.external.secretAccessKey" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if not .Values.electric.deploy }}
|
||||
{{- if not .Values.electric.external.url }}
|
||||
{{- fail "Electric external configuration is required when electric.deploy=false. Please provide electric.external.url" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{- if and .Values.s2.deploy .Values.s2.external.endpoint }}
|
||||
{{- fail "S2 configuration conflict: s2.external.endpoint is set but s2.deploy=true, so the external endpoint would be ignored. Set s2.deploy=false to use an external S2 endpoint, or clear s2.external.endpoint to use the bundled s2-lite." }}
|
||||
{{- end }}
|
||||
|
||||
{{- if not .Values.registry.deploy }}
|
||||
{{- if or (not .Values.registry.external.host) }}
|
||||
{{- fail "Registry external configuration is required when registry.deploy=false. Please provide registry.external.host" }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
|
||||
{{/*
|
||||
This template produces no output but will fail the deployment if validation fails
|
||||
*/}}
|
||||
---
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: {{ include "trigger-v4.fullname" . }}-external-config-validation
|
||||
labels:
|
||||
{{- include "trigger-v4.labels" . | nindent 4 }}
|
||||
annotations:
|
||||
helm.sh/hook: pre-install,pre-upgrade
|
||||
helm.sh/hook-weight: "-10"
|
||||
helm.sh/hook-delete-policy: before-hook-creation
|
||||
data:
|
||||
validation: "completed"
|
||||
@@ -0,0 +1,52 @@
|
||||
{{- if .Values.webapp.ingress.enabled -}}
|
||||
{{- $fullName := include "trigger-v4.fullname" . -}}
|
||||
{{- $svcPort := .Values.webapp.service.port -}}
|
||||
apiVersion: networking.k8s.io/v1
|
||||
kind: Ingress
|
||||
metadata:
|
||||
name: {{ $fullName }}-webapp
|
||||
labels:
|
||||
{{- $component := "webapp" }}
|
||||
{{- include "trigger-v4.componentLabels" (dict "Chart" .Chart "Release" .Release "Values" .Values "component" $component) | nindent 4 }}
|
||||
annotations:
|
||||
{{- include "trigger-v4.webapp.ingress.annotations" . | nindent 4 }}
|
||||
spec:
|
||||
{{- if .Values.webapp.ingress.className }}
|
||||
ingressClassName: {{ .Values.webapp.ingress.className }}
|
||||
{{- end }}
|
||||
{{- if .Values.webapp.ingress.tls }}
|
||||
tls:
|
||||
{{- range .Values.webapp.ingress.tls }}
|
||||
- hosts:
|
||||
{{- range .hosts }}
|
||||
- {{ . | quote }}
|
||||
{{- end }}
|
||||
secretName: {{ .secretName }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
rules:
|
||||
{{- range .Values.webapp.ingress.hosts }}
|
||||
- host: {{ .host | quote }}
|
||||
http:
|
||||
paths:
|
||||
{{- if .paths }}
|
||||
{{- range .paths }}
|
||||
- path: {{ .path }}
|
||||
pathType: {{ .pathType | default "Prefix" }}
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}-webapp
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- else }}
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
backend:
|
||||
service:
|
||||
name: {{ $fullName }}-webapp
|
||||
port:
|
||||
number: {{ $svcPort }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
{{- end }}
|
||||
@@ -0,0 +1,494 @@
|
||||
{{- 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 }}
|
||||
@@ -0,0 +1,201 @@
|
||||
# Production values example for Trigger.dev v4 Helm chart
|
||||
# Copy this file and customize for your production deployment
|
||||
|
||||
# REQUIRED: Generate your own secrets using: openssl rand -hex 16
|
||||
secrets:
|
||||
sessionSecret: "YOUR_32_CHAR_HEX_SECRET_HERE_001"
|
||||
magicLinkSecret: "YOUR_32_CHAR_HEX_SECRET_HERE_002"
|
||||
encryptionKey: "YOUR_32_CHAR_HEX_SECRET_HERE_003"
|
||||
managedWorkerSecret: "YOUR_32_CHAR_HEX_SECRET_HERE_004"
|
||||
|
||||
# Production webapp configuration
|
||||
webapp:
|
||||
# Origin configuration
|
||||
appOrigin: "https://trigger.example.com"
|
||||
loginOrigin: "https://trigger.example.com"
|
||||
apiOrigin: "https://trigger.example.com"
|
||||
|
||||
# Production ingress
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
hosts:
|
||||
- host: trigger.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: trigger-tls
|
||||
hosts:
|
||||
- trigger.example.com
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 2000m
|
||||
memory: 4Gi
|
||||
requests:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
|
||||
# Production PostgreSQL (or use external)
|
||||
postgres:
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 100Gi
|
||||
storageClass: "fast-ssd"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 1000m
|
||||
memory: 2Gi
|
||||
requests:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
|
||||
# Production Redis (or use external)
|
||||
redis:
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 20Gi
|
||||
storageClass: "fast-ssd"
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
|
||||
# Production ClickHouse
|
||||
clickhouse:
|
||||
# Set to true to enable TLS/secure connections in production
|
||||
secure: true
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 100Gi
|
||||
storageClass: "fast-ssd"
|
||||
# ClickHouse can be very resource intensive, so we recommend setting limits and requests accordingly
|
||||
# Note: not doing this can cause OOM crashes which will cause issues across many different
|
||||
resources:
|
||||
limits:
|
||||
cpu: 4000m
|
||||
memory: 16Gi
|
||||
requests:
|
||||
cpu: 2000m
|
||||
memory: 8Gi
|
||||
|
||||
# Production S3-compatible object storage
|
||||
s3:
|
||||
auth:
|
||||
rootUser: "admin"
|
||||
rootPassword: "your-strong-s3-password"
|
||||
# Webapp credentials for S3 access (can be different from root)
|
||||
accessKeyId: "your-access-key"
|
||||
secretAccessKey: "your-secret-key"
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 500Gi
|
||||
storageClass: "standard"
|
||||
|
||||
# Production Registry
|
||||
registry:
|
||||
repositoryNamespace: "mycompany" # Docker repository namespace for deployed images, will be part of the image ref
|
||||
auth:
|
||||
username: "registry-user"
|
||||
password: "your-strong-registry-password"
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 100Gi
|
||||
storageClass: "standard"
|
||||
|
||||
# Production ingress
|
||||
ingress:
|
||||
enabled: true
|
||||
className: "nginx"
|
||||
annotations:
|
||||
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||
hosts:
|
||||
- host: registry.example.com
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
- secretName: registry-tls
|
||||
hosts:
|
||||
- registry.example.com
|
||||
|
||||
# Production Supervisor (Kubernetes worker orchestrator)
|
||||
supervisor:
|
||||
resources:
|
||||
limits:
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 250m
|
||||
memory: 512Mi
|
||||
# Example: Use external PostgreSQL instead
|
||||
# postgres:
|
||||
# deploy: false
|
||||
# connection:
|
||||
# sslMode: "require" # Use 'require' or 'verify-full' for production
|
||||
# external:
|
||||
# # Database URL configuration - simplified approach using URLs
|
||||
# databaseUrl: "postgresql://trigger_user:your-db-password@your-postgres-host.rds.amazonaws.com:5432/trigger?schema=public&sslmode=require"
|
||||
# directUrl: "" # Optional: Direct URL for migrations (if not set, databaseUrl will be used)
|
||||
# #
|
||||
# # Optional: Connectivity check configuration during webapp startup
|
||||
# connectivityCheck:
|
||||
# host: "your-postgres-host.rds.amazonaws.com:5432"
|
||||
# #
|
||||
# # Secure credential management (recommended for production)
|
||||
# # existingSecret: "postgres-credentials" # Name of existing secret containing DATABASE_URL
|
||||
# # secretKeys:
|
||||
# # databaseUrlKey: "postgres-database-url" # Key in existing secret
|
||||
# # directUrlKey: "postgres-direct-url" # Key in existing secret (optional)
|
||||
|
||||
# Example: Use external Redis instead
|
||||
# redis:
|
||||
# deploy: false
|
||||
# external:
|
||||
# host: "your-redis-cluster.cache.amazonaws.com"
|
||||
# port: 6379
|
||||
# password: "your-redis-password" # Optional - ignored if existingSecret is set
|
||||
# tls:
|
||||
# enabled: true # Set to true for Redis instances requiring TLS (e.g., AWS ElastiCache)
|
||||
# #
|
||||
# # Secure credential management (recommended for production)
|
||||
# # existingSecret: "redis-credentials" # Name of existing secret containing password
|
||||
# # existingSecretPasswordKey: "redis-password" # Key in existing secret containing password
|
||||
|
||||
# Example: Use external ClickHouse instead
|
||||
# clickhouse:
|
||||
# deploy: false
|
||||
# external:
|
||||
# host: "your-clickhouse-host.cloud.provider.com"
|
||||
# httpPort: 8443 # Use 8443 for HTTPS
|
||||
# nativePort: 9440 # Use 9440 for secure native connections
|
||||
# username: "trigger_user"
|
||||
# password: "your-clickhouse-password" # Optional - ignored if existingSecret is set
|
||||
# secure: true # Use true for TLS/secure connections
|
||||
# #
|
||||
# # Secure credential management (recommended for production)
|
||||
# # existingSecret: "clickhouse-credentials" # Name of existing secret containing password
|
||||
# # existingSecretKey: "clickhouse-password" # Key in existing secret containing password
|
||||
|
||||
# Example: Use external S3-compatible storage instead
|
||||
# s3:
|
||||
# deploy: false
|
||||
# external:
|
||||
# endpoint: "https://s3.amazonaws.com" # or your S3-compatible endpoint
|
||||
# accessKeyId: "your-access-key"
|
||||
# secretAccessKey: "your-secret-key"
|
||||
# #
|
||||
# # Secure credential management (recommended for production)
|
||||
# # existingSecret: "s3-credentials" # Name of existing secret containing S3 credentials
|
||||
# # existingSecretAccessKeyIdKey: "access-key-id" # Key in existing secret containing access key ID
|
||||
# # existingSecretSecretAccessKeyKey: "secret-access-key" # Key in existing secret containing secret access key
|
||||
@@ -0,0 +1,922 @@
|
||||
global:
|
||||
imageRegistry: ""
|
||||
imagePullSecrets: []
|
||||
storageClass: ""
|
||||
security:
|
||||
# Required when using bitnami legacy images
|
||||
allowInsecureImages: true
|
||||
|
||||
nameOverride: ""
|
||||
fullnameOverride: ""
|
||||
|
||||
# Secrets configuration
|
||||
# IMPORTANT: The default values below are for TESTING ONLY and should NOT be used in production
|
||||
# For production deployments:
|
||||
# 1. Generate new secrets using: openssl rand -hex 16
|
||||
# 2. Override these values in your values.yaml or use external secret management
|
||||
# 3. Each secret must be exactly 32 hex characters (16 bytes)
|
||||
secrets:
|
||||
# Enable/disable creation of secrets
|
||||
# Set to false to use external secret management (Vault, Infisical, External Secrets, etc.)
|
||||
# When disabled, you can also use extraEnvVars and podAnnotations for secret injection
|
||||
enabled: true
|
||||
|
||||
# Name of existing secret to use instead of creating one
|
||||
# If empty, a secret will be created with the values below
|
||||
# The secret must contain the following keys:
|
||||
# - SESSION_SECRET
|
||||
# - MAGIC_LINK_SECRET
|
||||
# - ENCRYPTION_KEY
|
||||
# - MANAGED_WORKER_SECRET
|
||||
existingSecret: ""
|
||||
|
||||
# Session secret for user authentication (32 hex chars)
|
||||
sessionSecret: "2818143646516f6fffd707b36f334bbb"
|
||||
# Magic link secret for passwordless login (32 hex chars)
|
||||
magicLinkSecret: "44da78b7bbb0dfe709cf38931d25dcdd"
|
||||
# Encryption key for sensitive data (32 hex chars)
|
||||
encryptionKey: "f686147ab967943ebbe9ed3b496e465a"
|
||||
# Worker secret for managed worker authentication (32 hex chars)
|
||||
managedWorkerSecret: "447c29678f9eaf289e9c4b70d3dd8a7f"
|
||||
# Object store credentials moved to s3.auth and s3.external section
|
||||
|
||||
# Webapp configuration
|
||||
webapp:
|
||||
image:
|
||||
registry: ghcr.io
|
||||
repository: triggerdotdev/trigger.dev
|
||||
tag: "" # Defaults to Chart.appVersion when empty
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Init container for shared directory setup
|
||||
volumePermissions:
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: busybox
|
||||
tag: "1.35"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Sidecar for token syncing
|
||||
tokenSyncer:
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: bitnamilegacy/kubectl
|
||||
tag: "1.28"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Origin configuration
|
||||
appOrigin: "http://localhost:3040"
|
||||
loginOrigin: "http://localhost:3040"
|
||||
apiOrigin: "http://localhost:3040"
|
||||
|
||||
replicaCount: 1
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3030
|
||||
targetPort: 3000
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# podSecurityContext:
|
||||
# fsGroup: 1000
|
||||
|
||||
# securityContext:
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
# Topology Spread Constraints for pod assignment spread across your cluster among failure-domains. Evaluated as a template
|
||||
topologySpreadConstraints: []
|
||||
|
||||
logLevel: "info"
|
||||
gracefulShutdownTimeout: 1000
|
||||
|
||||
# Bootstrap configuration
|
||||
bootstrap:
|
||||
enabled: true
|
||||
workerGroupName: "bootstrap"
|
||||
workerTokenPath: "/home/node/shared/worker_token"
|
||||
|
||||
# Limits
|
||||
limits:
|
||||
taskPayloadOffloadThreshold: 524288 # 512KB
|
||||
taskPayloadMaximumSize: 3145728 # 3MB
|
||||
batchTaskPayloadMaximumSize: 1000000 # 1MB
|
||||
taskRunMetadataMaximumSize: 262144 # 256KB
|
||||
defaultEnvExecutionConcurrencyLimit: 100
|
||||
defaultOrgExecutionConcurrencyLimit: 300
|
||||
|
||||
# Resources
|
||||
resources:
|
||||
{}
|
||||
# Example resource configuration:
|
||||
# limits:
|
||||
# cpu: 1000m
|
||||
# memory: 2Gi
|
||||
# requests:
|
||||
# cpu: 500m
|
||||
# memory: 1Gi
|
||||
|
||||
# Connectivity check configuration
|
||||
connectivityCheck:
|
||||
postgres: true # Set to false to disable DATABASE_HOST env var (overrides postgres.external.connectivityCheck)
|
||||
|
||||
# Extra environment variables for webapp
|
||||
extraEnvVars:
|
||||
[]
|
||||
# - name: CUSTOM_VAR
|
||||
# value: "custom-value"
|
||||
# - name: SECRET_VAR
|
||||
# valueFrom:
|
||||
# secretKeyRef:
|
||||
# name: my-secret
|
||||
# key: secret-key
|
||||
#
|
||||
# Example: PostgreSQL SSL with custom CA certificate
|
||||
# - name: NODE_EXTRA_CA_CERTS
|
||||
# value: "/etc/ssl/certs/postgres-ca.crt"
|
||||
|
||||
# Extra volumes for the webapp pod
|
||||
extraVolumes:
|
||||
[]
|
||||
# - name: config-volume
|
||||
# configMap:
|
||||
# name: my-config
|
||||
# - name: secret-volume
|
||||
# secret:
|
||||
# secretName: my-secret
|
||||
#
|
||||
# Example: PostgreSQL SSL CA certificate volume
|
||||
# - name: postgres-ca-cert
|
||||
# secret:
|
||||
# secretName: postgres-ca-secret
|
||||
# items:
|
||||
# - key: ca.crt
|
||||
# path: postgres-ca.crt
|
||||
|
||||
# Extra volume mounts for the webapp container
|
||||
extraVolumeMounts:
|
||||
[]
|
||||
# - name: config-volume
|
||||
# mountPath: /etc/config
|
||||
# readOnly: true
|
||||
# - name: secret-volume
|
||||
# mountPath: /etc/secrets
|
||||
# readOnly: true
|
||||
#
|
||||
# Example: PostgreSQL SSL CA certificate mount
|
||||
# - name: postgres-ca-cert
|
||||
# mountPath: /etc/ssl/certs
|
||||
# readOnly: true
|
||||
|
||||
# ServiceMonitor for Prometheus monitoring
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
interval: "30s"
|
||||
path: "/metrics"
|
||||
labels: {}
|
||||
basicAuth: {}
|
||||
|
||||
# Health probe configuration
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 30
|
||||
timeoutSeconds: 10
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
clickhouse:
|
||||
logLevel: "info" # one of: log, error, warn, info, debug
|
||||
runReplication:
|
||||
logLevel: "info" # one of: log, error, warn, info, debug
|
||||
|
||||
# ServiceAccount configuration
|
||||
serviceAccount:
|
||||
create: true
|
||||
# Name of the ServiceAccount to use. Required when create is false - otherwise
|
||||
# the token-syncer RoleBinding would bind to the namespace's "default" SA.
|
||||
name: ""
|
||||
# Annotations to add to the ServiceAccount (e.g. eks.amazonaws.com/role-arn for IRSA)
|
||||
annotations: {}
|
||||
|
||||
# Observability configuration (OTel)
|
||||
observability:
|
||||
tracing:
|
||||
exporterUrl: ""
|
||||
exporterAuthHeaders: ""
|
||||
loggingEnabled: "0"
|
||||
samplingRate: "20"
|
||||
instrumentPrismaEnabled: "0"
|
||||
disabled: "0"
|
||||
logging:
|
||||
exporterUrl: ""
|
||||
# Log auth headers are currently set to tracing.exporterAuthHeaders
|
||||
metrics:
|
||||
exporterUrl: ""
|
||||
exporterAuthHeaders: ""
|
||||
exporterEnabled: "0"
|
||||
exporterIntervalMs: 30000
|
||||
|
||||
# Webapp ingress configuration
|
||||
ingress:
|
||||
enabled: false
|
||||
className: "traefik"
|
||||
# Custom annotations for the ingress resource
|
||||
# Note: The following annotation keys are reserved and will be automatically set:
|
||||
# - cert-manager.io/cluster-issuer (when certManager.enabled is true)
|
||||
# - external-dns.alpha.kubernetes.io/hostname (when externalDns.enabled is true)
|
||||
# - external-dns.alpha.kubernetes.io/ttl (when externalDns.enabled is true)
|
||||
annotations: {}
|
||||
certManager:
|
||||
enabled: false
|
||||
clusterIssuer: "letsencrypt-prod"
|
||||
externalDns:
|
||||
enabled: false
|
||||
hostname: ""
|
||||
ttl: "300"
|
||||
hosts:
|
||||
- host: trigger.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
[]
|
||||
# - secretName: trigger-tls
|
||||
# hosts:
|
||||
# - trigger.local
|
||||
|
||||
# Supervisor configuration
|
||||
supervisor:
|
||||
image:
|
||||
registry: ghcr.io
|
||||
repository: triggerdotdev/supervisor
|
||||
tag: "" # Defaults to Chart.appVersion when empty
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# podSecurityContext:
|
||||
# fsGroup: 1000
|
||||
|
||||
# securityContext:
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
workload: 3000
|
||||
metrics: 9088
|
||||
resources: {}
|
||||
config:
|
||||
kubernetes:
|
||||
forceEnabled: true
|
||||
namespace: "" # Default: uses release namespace
|
||||
workerNodetypeLabel: "" # When set, runs will only be scheduled on nodes with "nodetype=<label>"
|
||||
ephemeralStorageSizeLimit: "" # Default: 10Gi
|
||||
ephemeralStorageSizeRequest: "" # Default: 2Gi´
|
||||
podCleaner:
|
||||
enabled: true
|
||||
batchSize: 100
|
||||
intervalMs: 10000 # 10 seconds´
|
||||
failedPodHandler:
|
||||
enabled: true
|
||||
reconnectIntervalMs: 1000
|
||||
workloadApi:
|
||||
enabled: true
|
||||
protocol: "http"
|
||||
portExternal: 3000
|
||||
portInternal: 3000
|
||||
hostInternal: "0.0.0.0"
|
||||
dequeue:
|
||||
enabled: true
|
||||
intervalMs: 250
|
||||
maxRunCount: 100
|
||||
idleIntervalMs: 500
|
||||
runner:
|
||||
heartbeatIntervalSeconds: 30
|
||||
snapshotPollIntervalSeconds: 30
|
||||
metrics:
|
||||
enabled: true
|
||||
collectDefaults: true
|
||||
host: "0.0.0.0"
|
||||
port: 9088
|
||||
debug: false
|
||||
# RBAC configuration
|
||||
serviceAccount:
|
||||
create: true
|
||||
name: ""
|
||||
annotations: {}
|
||||
rbac:
|
||||
create: true
|
||||
# Namespace-scoped permissions for pod management
|
||||
role:
|
||||
name: ""
|
||||
# Extra environment variables for Supervisor
|
||||
extraEnvVars:
|
||||
[]
|
||||
# - name: CUSTOM_VAR
|
||||
# value: "custom-value"
|
||||
|
||||
# ServiceMonitor for Prometheus monitoring
|
||||
serviceMonitor:
|
||||
enabled: false
|
||||
interval: "30s"
|
||||
path: "/metrics"
|
||||
labels: {}
|
||||
basicAuth: {}
|
||||
|
||||
# Health probe configuration
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 15
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
# Bootstrap configuration
|
||||
# When enabled: reads token from shared file, otherwise uses workerToken config
|
||||
bootstrap:
|
||||
enabled: true
|
||||
workerTokenPath: "/home/node/shared/worker_token"
|
||||
workerToken:
|
||||
# Direct value (not recommended for production)
|
||||
value: ""
|
||||
# Secret reference
|
||||
secret:
|
||||
name: ""
|
||||
key: ""
|
||||
|
||||
nodeSelector: {}
|
||||
tolerations: []
|
||||
affinity: {}
|
||||
|
||||
# PostgreSQL configuration
|
||||
# Subchart: https://github.com/bitnami/charts/tree/main/bitnami/postgresql
|
||||
postgres:
|
||||
deploy: true
|
||||
|
||||
image:
|
||||
# Use bitnami legacy repo
|
||||
repository: bitnamilegacy/postgresql
|
||||
# image: docker.io/bitnamilegacy/postgresql:17.5.0-debian-12-r12
|
||||
|
||||
# Bitnami PostgreSQL chart configuration (when deploy: true)
|
||||
auth:
|
||||
enablePostgresUser: true
|
||||
postgresPassword: "postgres"
|
||||
username: "postgres"
|
||||
password: "postgres"
|
||||
database: "main"
|
||||
|
||||
primary:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resourcesPreset: "small"
|
||||
resources: {}
|
||||
configuration: |
|
||||
listen_addresses = '*'
|
||||
wal_level = logical
|
||||
|
||||
# Custom connection settings
|
||||
connection:
|
||||
schema: "public"
|
||||
sslMode: "disable" # Use "require" or "verify-full" for production with custom CA
|
||||
|
||||
# External PostgreSQL connection (when deploy: false)
|
||||
external:
|
||||
# Database URL configuration - simplified approach using URLs instead of individual parameters
|
||||
databaseUrl: "" # Full PostgreSQL connection URL (e.g., postgresql://user:pass@host:port/db?schema=public&sslmode=prefer)
|
||||
directUrl: "" # Optional: Direct URL for migrations (if not set, databaseUrl will be used)
|
||||
#
|
||||
# Optional: Connectivity check configuration during webapp startup
|
||||
connectivityCheck:
|
||||
host: "" # Optional: hostname:port for wait-for-it script (e.g., "postgres.example.com:5432")
|
||||
#
|
||||
# Secure credential management
|
||||
existingSecret: "" # Name of existing secret containing DATABASE_URL
|
||||
secretKeys:
|
||||
databaseUrlKey: "postgres-database-url" # Key in existing secret containing complete DATABASE_URL
|
||||
directUrlKey: "postgres-direct-url" # Key in existing secret containing direct URL (optional)
|
||||
#
|
||||
# Example: For SSL connections with custom CA (e.g., AWS RDS):
|
||||
# 1. Set connection.sslMode to "require" or "verify-full"
|
||||
# 2. Create a secret with your CA certificate:
|
||||
# kubectl create secret generic postgres-ca-secret --from-file=ca.crt=/path/to/rds-ca-cert.pem
|
||||
# 3. Configure extraVolumes, extraVolumeMounts, and extraEnvVars (see webapp section above)
|
||||
|
||||
# Redis configuration
|
||||
# Subchart: https://github.com/bitnami/charts/tree/main/bitnami/redis
|
||||
redis:
|
||||
deploy: true
|
||||
|
||||
image:
|
||||
# Use bitnami legacy repo
|
||||
repository: bitnamilegacy/redis
|
||||
# image: docker.io/bitnamilegacy/redis:8.0.2-debian-12-r4
|
||||
|
||||
# Bitnami Redis chart configuration (when deploy: true)
|
||||
auth:
|
||||
enabled: false
|
||||
|
||||
# Single-node configuration (disable replica)
|
||||
architecture: standalone
|
||||
|
||||
master:
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 5Gi
|
||||
resources: {}
|
||||
|
||||
# External Redis connection (when deploy: false)
|
||||
external:
|
||||
host: ""
|
||||
port: 6379
|
||||
password: "" # Optional - ignored if existingSecret is set
|
||||
tls:
|
||||
enabled: false # Set to true for Redis instances requiring TLS (e.g., AWS ElastiCache)
|
||||
#
|
||||
# Secure credential management
|
||||
existingSecret: "" # Name of existing secret containing password
|
||||
existingSecretPasswordKey: "redis-password" # Key in existing secret containing password
|
||||
|
||||
# Electric configuration
|
||||
electric:
|
||||
deploy: true
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: electricsql/electric
|
||||
tag: "1.2.4"
|
||||
pullPolicy: IfNotPresent
|
||||
config:
|
||||
insecure: true
|
||||
usageReporting: false
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# podSecurityContext:
|
||||
# fsGroup: 1000
|
||||
|
||||
# securityContext:
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 3000
|
||||
targetPort: 3000
|
||||
resources: {}
|
||||
|
||||
# Health probe configuration
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
# External Electric connection (when deploy: false)
|
||||
external:
|
||||
url: "" # For example: "http://electric:3000"
|
||||
|
||||
# Extra environment variables for Electric
|
||||
extraEnvVars:
|
||||
[]
|
||||
# - name: CUSTOM_VAR
|
||||
# value: "custom-value"
|
||||
|
||||
# S2 (realtime streams v2)
|
||||
# s2-lite is the open-source, self-hostable S2 server (https://s2.dev). It backs
|
||||
# realtime streams v2, which power AI-agent token streaming and run streams. When
|
||||
# enabled, the webapp defaults to v2; set `defaultStreamVersion: v1` to fall back
|
||||
# to the Redis-backed v1 streams. Disable entirely with `deploy: false` and no
|
||||
# external endpoint.
|
||||
s2:
|
||||
deploy: true
|
||||
image:
|
||||
registry: ghcr.io
|
||||
repository: s2-streamstore/s2
|
||||
tag: "latest"
|
||||
# Pinning by digest is strongly recommended for reproducible deployments
|
||||
digest: "sha256:d6ded5ca7dd619fa7c946f06e39a98f9c95c6883c8bb884e5eaa129f232c920c"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
# Which stream protocol version the webapp defaults to when a client doesn't pin one.
|
||||
# Only takes effect while S2 is enabled (deploy: true or an external endpoint set);
|
||||
# with S2 fully disabled the webapp always falls back to v1.
|
||||
defaultStreamVersion: "v2"
|
||||
|
||||
# Basin that holds realtime streams. Created on startup from the init config.
|
||||
# Must be at least 8 characters.
|
||||
basin: "trigger-realtime"
|
||||
|
||||
# s2-lite needs no authentication; skip minting per-stream access tokens.
|
||||
# Set to false when pointing at a hosted S2 that requires a token.
|
||||
skipAccessTokens: true
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# s2-lite is distroless and runs as uid 65532. fsGroup makes the persistent
|
||||
# volume writable by that user without running the container as root.
|
||||
podSecurityContext:
|
||||
fsGroup: 65532
|
||||
securityContext:
|
||||
runAsNonRoot: true
|
||||
runAsUser: 65532
|
||||
runAsGroup: 65532
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 80
|
||||
# High container port so s2-lite can bind as the non-root image user (65532)
|
||||
# without needing CAP_NET_BIND_SERVICE for a privileged port
|
||||
targetPort: 8080
|
||||
|
||||
# Persistent storage for the SlateDB-backed stream data
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 5Gi
|
||||
accessMode: ReadWriteOnce
|
||||
storageClass: ""
|
||||
retain: false
|
||||
|
||||
resources: {}
|
||||
|
||||
# Health probe configuration (distroless image → TCP probes, no shell/HTTP tooling)
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 5
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
|
||||
# External S2 connection (when deploy: false). Point at a hosted S2 basin, e.g.
|
||||
# "https://<basin>.b.aws.s2.dev/v1", set skipAccessTokens: false above, and
|
||||
# supply an access token either inline or via an existing secret.
|
||||
external:
|
||||
endpoint: ""
|
||||
accessToken: ""
|
||||
existingSecret: ""
|
||||
existingSecretAccessTokenKey: "access-token"
|
||||
|
||||
# ClickHouse configuration
|
||||
# Subchart: https://github.com/bitnami/charts/tree/main/bitnami/clickhouse
|
||||
clickhouse:
|
||||
deploy: true
|
||||
|
||||
image:
|
||||
# Use bitnami legacy repo
|
||||
repository: bitnamilegacy/clickhouse
|
||||
# image: docker.io/bitnamilegacy/clickhouse:25.7.5-debian-12-r0
|
||||
|
||||
# TLS/Secure connection configuration
|
||||
secure: false # Set to true to use HTTPS and secure connections
|
||||
|
||||
# Bitnami ClickHouse chart configuration (when deploy: true)
|
||||
auth:
|
||||
username: "default"
|
||||
password: "password"
|
||||
|
||||
# Single-node configuration (disable clustering for dev/test)
|
||||
keeper:
|
||||
enabled: false
|
||||
|
||||
shards: 1
|
||||
replicaCount: 1
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
|
||||
## ClickHouse resource requests and limits
|
||||
## ref: http://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/
|
||||
## @param resourcesPreset Set container resources according to one common preset (allowed values: none, nano, micro, small, medium, large, xlarge, 2xlarge). This is ignored if resources is set (resources is recommended for production).
|
||||
## More information: https://github.com/bitnami/charts/blob/main/bitnami/common/templates/_resources.tpl#L15
|
||||
resourcesPreset: "xlarge"
|
||||
resources: {}
|
||||
|
||||
# External ClickHouse connection (when deploy: false)
|
||||
external:
|
||||
host: ""
|
||||
httpPort: 8123
|
||||
nativePort: 9000
|
||||
username: ""
|
||||
password: "" # Optional - ignored if existingSecret is set
|
||||
secure: false # Set to true for external secure connections
|
||||
#
|
||||
# Secure credential management
|
||||
existingSecret: "" # Name of existing secret containing password
|
||||
existingSecretKey: "clickhouse-password" # Key in existing secret containing password
|
||||
|
||||
# ClickHouse configuration override
|
||||
# These defaults are based on official recommendations for systems with <16GB RAM:
|
||||
# https://clickhouse.com/docs/operations/tips
|
||||
configdFiles:
|
||||
override.xml: |
|
||||
<clickhouse>
|
||||
<logger>
|
||||
<level>warning</level>
|
||||
</logger>
|
||||
<!-- Official recommendations for systems with <16GB RAM -->
|
||||
<mark_cache_size>524288000</mark_cache_size> <!-- 500MB -->
|
||||
<concurrent_threads_soft_limit_num>1</concurrent_threads_soft_limit_num>
|
||||
<profiles>
|
||||
<default>
|
||||
<max_block_size>8192</max_block_size>
|
||||
<max_download_threads>1</max_download_threads>
|
||||
<input_format_parallel_parsing>0</input_format_parallel_parsing>
|
||||
<output_format_parallel_formatting>0</output_format_parallel_formatting>
|
||||
</default>
|
||||
</profiles>
|
||||
</clickhouse>
|
||||
|
||||
# S3-compatible object storage configuration
|
||||
# Subchart: https://github.com/bitnami/charts/tree/main/bitnami/minio
|
||||
s3:
|
||||
# Set to false to use external S3-compatible storage
|
||||
# Set to true to deploy internal MinIO (default)
|
||||
deploy: true
|
||||
|
||||
image:
|
||||
# Use bitnami legacy repo
|
||||
repository: bitnamilegacy/minio
|
||||
# image: docker.io/bitnamilegacy/minio:2025.6.13-debian-12-r0
|
||||
|
||||
# MinIO Console (Browser UI) configuration
|
||||
console:
|
||||
image:
|
||||
repository: bitnamilegacy/minio-object-browser
|
||||
# image: docker.io/bitnamilegacy/minio-object-browser:2025.1.10-debian-12-r1
|
||||
|
||||
# Bitnami MinIO chart configuration (when deploy: true)
|
||||
# MinIO provides S3-compatible storage when deployed internally
|
||||
auth:
|
||||
rootUser: "admin"
|
||||
rootPassword: "very-safe-password"
|
||||
# Webapp credentials for S3 access (defaults to root credentials if not specified)
|
||||
accessKeyId: "" # Defaults to rootUser if empty
|
||||
secretAccessKey: "" # Defaults to rootPassword if empty
|
||||
# Existing secret support for webapp credentials
|
||||
existingSecret: "" # If set, accessKeyId/secretAccessKey will be ignored
|
||||
accessKeyIdSecretKey: "access-key-id" # Key in existingSecret containing access key ID
|
||||
secretAccessKeySecretKey: "secret-access-key" # Key in existingSecret containing secret access key
|
||||
|
||||
# The required "packets" bucket is created by default.
|
||||
defaultBuckets: "packets"
|
||||
|
||||
persistence:
|
||||
enabled: true
|
||||
size: 10Gi
|
||||
resources: {}
|
||||
|
||||
# External S3 connection (when deploy: false)
|
||||
external:
|
||||
endpoint: "" # e.g., "https://s3.amazonaws.com" or "https://your-minio.com:9000"
|
||||
accessKeyId: "admin" # Default for internal MinIO - change for production
|
||||
secretAccessKey: "very-safe-password" # Default for internal MinIO - change for production
|
||||
#
|
||||
# Secure credential management
|
||||
existingSecret: "" # Name of existing secret containing S3 credentials
|
||||
existingSecretAccessKeyIdKey: "access-key-id" # Key in existing secret containing access key ID
|
||||
existingSecretSecretAccessKeyKey: "secret-access-key" # Key in existing secret containing secret access key
|
||||
#
|
||||
# Multi-provider support (optional)
|
||||
# To use multiple S3-compatible providers (e.g., S3 + R2), set defaultProtocol and configure named providers
|
||||
# via extraEnvVars. For example:
|
||||
# - OBJECT_STORE_DEFAULT_PROTOCOL=s3 # Protocol to use for new uploads
|
||||
# - OBJECT_STORE_S3_BASE_URL=https://s3.amazonaws.com
|
||||
# - OBJECT_STORE_S3_ACCESS_KEY_ID=...
|
||||
# - OBJECT_STORE_S3_SECRET_ACCESS_KEY=...
|
||||
# - OBJECT_STORE_R2_BASE_URL=https://...r2.cloudflarestorage.com
|
||||
# - OBJECT_STORE_R2_ACCESS_KEY_ID=...
|
||||
# - OBJECT_STORE_R2_SECRET_ACCESS_KEY=...
|
||||
# See documentation for migration guide: https://trigger.dev/docs/self-hosting/env/webapp
|
||||
|
||||
# Docker Registry configuration
|
||||
registry:
|
||||
# EXPERIMENTAL - requires ingress/TLS setup or additional cluster configuration. Configure `external` details instead.
|
||||
deploy: false
|
||||
|
||||
# This will be used when deploy: true
|
||||
host: "registry.example.com"
|
||||
|
||||
# Docker repository namespace for deployed images, will be part of the image ref
|
||||
repositoryNamespace: "trigger"
|
||||
|
||||
image:
|
||||
registry: docker.io
|
||||
repository: registry
|
||||
tag: "2"
|
||||
pullPolicy: IfNotPresent
|
||||
|
||||
auth:
|
||||
enabled: true
|
||||
username: "registry-user"
|
||||
password: "very-secure-indeed"
|
||||
|
||||
# External Registry connection (when deploy: false)
|
||||
external:
|
||||
host: "localhost:5001"
|
||||
auth:
|
||||
enabled: false
|
||||
username: ""
|
||||
password: ""
|
||||
|
||||
podAnnotations: {}
|
||||
|
||||
# podSecurityContext:
|
||||
# fsGroup: 1000
|
||||
|
||||
# securityContext:
|
||||
# runAsNonRoot: true
|
||||
# runAsUser: 1000
|
||||
|
||||
# Persistence configuration (Bitnami-style)
|
||||
persistence:
|
||||
enabled: true
|
||||
# Name to assign the volume
|
||||
volumeName: "data"
|
||||
# Name of an existing PVC to use
|
||||
existingClaim: ""
|
||||
# The path the volume will be mounted at
|
||||
mountPath: "/var/lib/registry"
|
||||
# The subdirectory of the volume to mount to
|
||||
subPath: ""
|
||||
# PVC Storage Class for Registry data volume
|
||||
storageClass: ""
|
||||
# PVC Access Mode for Registry volume
|
||||
accessModes:
|
||||
- "ReadWriteOnce"
|
||||
# PVC Storage Request for Registry volume
|
||||
size: 10Gi
|
||||
# Annotations for the PVC
|
||||
annotations: {}
|
||||
# Labels for the PVC
|
||||
labels: {}
|
||||
# Selector to match an existing Persistent Volume
|
||||
selector: {}
|
||||
# Custom PVC data source
|
||||
dataSource: {}
|
||||
|
||||
service:
|
||||
type: ClusterIP
|
||||
port: 5000
|
||||
targetPort: 5000
|
||||
resources: {}
|
||||
|
||||
# Health probe configuration
|
||||
livenessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
readinessProbe:
|
||||
enabled: true
|
||||
initialDelaySeconds: 10
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 5
|
||||
successThreshold: 1
|
||||
startupProbe:
|
||||
enabled: false
|
||||
initialDelaySeconds: 0
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 60
|
||||
successThreshold: 1
|
||||
|
||||
# Extra environment variables for Registry
|
||||
extraEnvVars:
|
||||
[]
|
||||
# - name: CUSTOM_VAR
|
||||
# value: "custom-value"
|
||||
|
||||
# Registry ingress configuration
|
||||
ingress:
|
||||
enabled: false
|
||||
className: "traefik"
|
||||
# Custom annotations for the ingress resource
|
||||
# Note: The following annotation keys are reserved and will be automatically set:
|
||||
# - cert-manager.io/cluster-issuer (when certManager.enabled is true)
|
||||
# - external-dns.alpha.kubernetes.io/hostname (when externalDns.enabled is true)
|
||||
# - external-dns.alpha.kubernetes.io/ttl (when externalDns.enabled is true)
|
||||
annotations: {}
|
||||
certManager:
|
||||
enabled: false
|
||||
clusterIssuer: "letsencrypt-prod"
|
||||
externalDns:
|
||||
enabled: false
|
||||
hostname: ""
|
||||
ttl: "300"
|
||||
hosts:
|
||||
- host: registry.local
|
||||
paths:
|
||||
- path: /
|
||||
pathType: Prefix
|
||||
tls:
|
||||
[]
|
||||
# - secretName: registry-tls
|
||||
# hosts:
|
||||
# - registry.local
|
||||
|
||||
# Shared persistent volumes
|
||||
persistence:
|
||||
# This is used for the worker token file
|
||||
shared:
|
||||
enabled: true
|
||||
size: 5Mi
|
||||
accessMode: ReadWriteOnce
|
||||
# accessMode: ReadWriteMany # Use for cross-node deployment (requires compatible storage class)
|
||||
storageClass: ""
|
||||
retain: true # Prevents deletion on uninstall
|
||||
|
||||
# Telemetry configuration
|
||||
telemetry:
|
||||
enabled: true
|
||||
|
||||
# Extra Kubernetes manifests
|
||||
# This allows you to add additional Kubernetes resources that will be deployed with the chart
|
||||
extraManifests:
|
||||
[]
|
||||
# - apiVersion: v1
|
||||
# kind: ConfigMap
|
||||
# metadata:
|
||||
# name: my-config
|
||||
# data:
|
||||
# key: value
|
||||
# - apiVersion: apps/v1
|
||||
# kind: Deployment
|
||||
# metadata:
|
||||
# name: my-app
|
||||
# spec:
|
||||
# replicas: 1
|
||||
# selector:
|
||||
# matchLabels:
|
||||
# app: my-app
|
||||
# template:
|
||||
# metadata:
|
||||
# labels:
|
||||
# app: my-app
|
||||
# spec:
|
||||
# containers:
|
||||
# - name: my-container
|
||||
# image: nginx:latest
|
||||
Executable
+75
@@ -0,0 +1,75 @@
|
||||
#!/bin/sh
|
||||
set -o errexit
|
||||
|
||||
cluster_name="${1:-trigger-test}"
|
||||
|
||||
# 1. Create registry container unless it already exists
|
||||
reg_name='kind-registry'
|
||||
reg_port='5001'
|
||||
if [ "$(docker inspect -f '{{.State.Running}}' "${reg_name}" 2>/dev/null || true)" != 'true' ]; then
|
||||
docker run \
|
||||
-d --restart=always -p "127.0.0.1:${reg_port}:5000" --network bridge --name "${reg_name}" \
|
||||
registry:2
|
||||
fi
|
||||
|
||||
# 2. Create kind cluster with containerd registry config dir enabled
|
||||
#
|
||||
# NOTE: the containerd config patch is not necessary with images from kind v0.27.0+
|
||||
# It may enable some older images to work similarly.
|
||||
# If you're only supporting newer relases, you can just use `kind create cluster` here.
|
||||
#
|
||||
# See:
|
||||
# https://github.com/kubernetes-sigs/kind/issues/2875
|
||||
# https://github.com/containerd/containerd/blob/main/docs/cri/config.md#registry-configuration
|
||||
# See: https://github.com/containerd/containerd/blob/main/docs/hosts.md
|
||||
cat <<EOF | kind create cluster --name "${cluster_name}" --config=-
|
||||
kind: Cluster
|
||||
apiVersion: kind.x-k8s.io/v1alpha4
|
||||
nodes:
|
||||
- role: control-plane
|
||||
labels:
|
||||
nodetype: v4-worker
|
||||
containerdConfigPatches:
|
||||
- |-
|
||||
[plugins."io.containerd.grpc.v1.cri".registry]
|
||||
config_path = "/etc/containerd/certs.d"
|
||||
EOF
|
||||
|
||||
# 3. Add the registry config to the nodes
|
||||
#
|
||||
# This is necessary because localhost resolves to loopback addresses that are
|
||||
# network-namespace local.
|
||||
# In other words: localhost in the container is not localhost on the host.
|
||||
#
|
||||
# We want a consistent name that works from both ends, so we tell containerd to
|
||||
# alias localhost:${reg_port} to the registry container when pulling images
|
||||
REGISTRY_DIR="/etc/containerd/certs.d/localhost:${reg_port}"
|
||||
for node in $(kind get nodes --name ${cluster_name}); do
|
||||
docker exec "${node}" mkdir -p "${REGISTRY_DIR}"
|
||||
cat <<EOF | docker exec -i "${node}" cp /dev/stdin "${REGISTRY_DIR}/hosts.toml"
|
||||
[host."http://${reg_name}:5000"]
|
||||
EOF
|
||||
done
|
||||
|
||||
# 4. Connect the registry to the cluster network if not already connected
|
||||
# This allows kind to bootstrap the network but ensures they're on the same network
|
||||
if [ "$(docker inspect -f='{{json .NetworkSettings.Networks.kind}}' "${reg_name}")" = 'null' ]; then
|
||||
docker network connect "kind" "${reg_name}"
|
||||
fi
|
||||
|
||||
# 5. Document the local registry
|
||||
# https://github.com/kubernetes/enhancements/tree/master/keps/sig-cluster-lifecycle/generic/1755-communicating-a-local-registry
|
||||
cat <<EOF | kubectl apply -f -
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: local-registry-hosting
|
||||
namespace: kube-public
|
||||
data:
|
||||
localRegistryHosting.v1: |
|
||||
host: "localhost:${reg_port}"
|
||||
help: "https://kind.sigs.k8s.io/docs/user/local-registry/"
|
||||
EOF
|
||||
|
||||
echo "Kind cluster ${cluster_name} with local registry is ready!"
|
||||
echo "You can now push images to localhost:${reg_port}"
|
||||
Reference in New Issue
Block a user