diff --git a/clusters/cl01tl/applications/homepage/values.yaml b/clusters/cl01tl/applications/homepage/values.yaml index 6dc3b8e3e..f2c3d95df 100644 --- a/clusters/cl01tl/applications/homepage/values.yaml +++ b/clusters/cl01tl/applications/homepage/values.yaml @@ -327,6 +327,13 @@ homepage: siteMonitor: http://komodo.komodo:80 statusStyle: dot namespace: komodo + - Automation: + icon: sh-n8n.webp + description: n8n + href: https://n8n.alexlebens.net + siteMonitor: http://n8n-main.n8n:80 + statusStyle: dot + namespace: komodo - Monitoring: - Kubernetes: icon: sh-headlamp.webp diff --git a/clusters/cl01tl/platform/n8n/Chart.yaml b/clusters/cl01tl/platform/n8n/Chart.yaml new file mode 100644 index 000000000..67dabf2c0 --- /dev/null +++ b/clusters/cl01tl/platform/n8n/Chart.yaml @@ -0,0 +1,32 @@ +apiVersion: v2 +name: n8n +version: 1.0.0 +description: n8n +keywords: + - n8n + - automation +home: https://wiki.alexlebens.dev/s/e4544bd4-c66a-420c-8020-c54b2078181a +sources: + - https://github.com/n8n-io/n8n + - https://github.com/valkey-io/valkey + - https://github.com/cloudnative-pg/cloudnative-pg + - https://github.com/n8n-io/n8n/pkgs/container/n8n + - https://github.com/bjw-s-labs/helm-charts/tree/main/charts/other/app-template + - https://github.com/bitnami/charts/tree/main/bitnami/valkey + - https://gitea.alexlebens.dev/alexlebens/helm-charts/src/branch/main/charts/postgres-cluster +maintainers: + - name: alexlebens +dependencies: + - name: app-template + alias: n8n + repository: https://bjw-s-labs.github.io/helm-charts/ + version: 4.0.1 + - name: valkey + version: 3.0.9 + repository: oci://harbor.alexlebens.net/proxy-registry-1.docker.io/bitnamicharts + - name: postgres-cluster + alias: postgres-17-cluster + version: 5.1.0 + repository: oci://harbor.alexlebens.net/helm-charts +icon: https://cdn.jsdelivr.net/gh/selfhst/icons/png/n8n.png +appVersion: 1.93.0 diff --git a/clusters/cl01tl/platform/n8n/templates/external-secret.yaml b/clusters/cl01tl/platform/n8n/templates/external-secret.yaml new file mode 100644 index 000000000..068c708d7 --- /dev/null +++ b/clusters/cl01tl/platform/n8n/templates/external-secret.yaml @@ -0,0 +1,51 @@ +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: n8n-config-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: n8n-config-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: key + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /cl01tl/n8n/config + metadataPolicy: None + property: key + +--- +apiVersion: external-secrets.io/v1 +kind: ExternalSecret +metadata: + name: n8n-postgresql-17-cluster-backup-secret + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: n8n-postgresql-17-cluster-backup-secret + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + secretStoreRef: + kind: ClusterSecretStore + name: vault + data: + - secretKey: ACCESS_KEY_ID + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/postgres-backups + metadataPolicy: None + property: access + - secretKey: ACCESS_SECRET_KEY + remoteRef: + conversionStrategy: Default + decodingStrategy: None + key: /digital-ocean/home-infra/postgres-backups + metadataPolicy: None + property: secret diff --git a/clusters/cl01tl/platform/n8n/templates/http-route.yaml b/clusters/cl01tl/platform/n8n/templates/http-route.yaml new file mode 100644 index 000000000..74ebf0111 --- /dev/null +++ b/clusters/cl01tl/platform/n8n/templates/http-route.yaml @@ -0,0 +1,47 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: http-route-n8n + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: http-route-n8n + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + parentRefs: + - group: gateway.networking.k8s.io + kind: Gateway + name: traefik-gateway + namespace: traefik + hostnames: + - n8n.alexlebens.net + rules: + - matches: + - path: + type: PathPrefix + value: / + - path: + type: PathPrefix + value: /webhook-test/ + backendRefs: + - group: '' + kind: Service + name: n8n-main + port: 80 + weight: 100 + - matches: + - path: + type: PathPrefix + value: /webhook/ + - path: + type: PathPrefix + value: /webhook-waiting/ + - path: + type: PathPrefix + value: /form/ + backendRefs: + - group: '' + kind: Service + name: n8n-webhook + port: 80 + weight: 100 diff --git a/clusters/cl01tl/platform/n8n/templates/service-monitor.yaml b/clusters/cl01tl/platform/n8n/templates/service-monitor.yaml new file mode 100644 index 000000000..38f0cabb3 --- /dev/null +++ b/clusters/cl01tl/platform/n8n/templates/service-monitor.yaml @@ -0,0 +1,61 @@ +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: n8n-main + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: n8n-main + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: n8n-main + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: http + interval: 3m + scrapeTimeout: 1m + path: /metrics + +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: n8n-worker + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: n8n-worker + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: n8n-worker + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: http + interval: 3m + scrapeTimeout: 1m + path: /metrics + +--- +apiVersion: monitoring.coreos.com/v1 +kind: ServiceMonitor +metadata: + name: n8n-webhook + namespace: {{ .Release.Namespace }} + labels: + app.kubernetes.io/name: n8n-webhook + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/part-of: {{ .Release.Name }} +spec: + selector: + matchLabels: + app.kubernetes.io/name: n8n-webhook + app.kubernetes.io/instance: {{ .Release.Name }} + endpoints: + - port: http + interval: 3m + scrapeTimeout: 1m + path: /metrics diff --git a/clusters/cl01tl/platform/n8n/values.yaml b/clusters/cl01tl/platform/n8n/values.yaml new file mode 100644 index 000000000..e332a365b --- /dev/null +++ b/clusters/cl01tl/platform/n8n/values.yaml @@ -0,0 +1,387 @@ +n8n: + controllers: + main: + type: deployment + replicas: 1 + strategy: Recreate + revisionHistoryLimit: 3 + initContainers: + init-chmod-data: + securityContext: + runAsUser: 0 + image: + repository: busybox + tag: 1.37.0 + pullPolicy: IfNotPresent + command: + - /bin/sh + - -ec + - | + /bin/chown -R 1000:1000 /data + resources: + requests: + cpu: 10m + memory: 128Mi + containers: + main: + image: + repository: ghcr.io/n8n-io/n8n + tag: 1.93.0 + pullPolicy: IfNotPresent + env: + - name: GENERIC_TIMEZONE + value: US/Central + - name: DB_TYPE + value: postgresdb + - name: DB_POSTGRESDB_DATABASE + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: dbname + - name: DB_POSTGRESDB_DATABASE + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: dbname + - name: DB_POSTGRESDB_HOST + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: host + - name: DB_POSTGRESDB_PORT + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: port + - name: DB_POSTGRESDB_USER + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: user + - name: DB_POSTGRESDB_PASSWORD + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: password + - name: N8N_METRICS + value: true + - name: QUEUE_HEALTH_CHECK_ACTIVE + value: true + - name: EXECUTIONS_MODE + value: queue + - name: QUEUE_BULL_REDIS_HOST + value: n8n-valkey-headless.n8n + - name: N8N_ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: n8n-config-secret + key: key + - name: WEBHOOK_URL + value: https://n8n.alexlebens.net/ + probes: + liveness: + enabled: true + custom: true + spec: + httpGet: + path: /healthz + port: 5678 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: + enabled: true + custom: true + spec: + httpGet: + path: /healthz/readiness + port: 5678 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + resources: + requests: + cpu: 10m + memory: 128Mi + worker: + type: daemonset + revisionHistoryLimit: 3 + pod: + nodeSelector: + kubernetes.io/arch: amd64 + containers: + main: + image: + repository: ghcr.io/n8n-io/n8n + tag: 1.93.0 + pullPolicy: IfNotPresent + command: + - n8n + args: + - worker + - --concurrency=10 + env: + - name: GENERIC_TIMEZONE + value: US/Central + - name: DB_TYPE + value: postgresdb + - name: DB_POSTGRESDB_DATABASE + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: dbname + - name: DB_POSTGRESDB_DATABASE + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: dbname + - name: DB_POSTGRESDB_HOST + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: host + - name: DB_POSTGRESDB_PORT + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: port + - name: DB_POSTGRESDB_USER + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: user + - name: DB_POSTGRESDB_PASSWORD + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: password + - name: N8N_METRICS + value: true + - name: QUEUE_HEALTH_CHECK_ACTIVE + value: true + - name: EXECUTIONS_MODE + value: queue + - name: QUEUE_BULL_REDIS_HOST + value: n8n-valkey-headless.n8n + - name: N8N_ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: n8n-config-secret + key: key + - name: WEBHOOK_URL + value: https://n8n.alexlebens.net/ + probes: + liveness: + enabled: true + custom: true + spec: + httpGet: + path: /healthz + port: 5678 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: + enabled: true + custom: true + spec: + httpGet: + path: /healthz/readiness + port: 5678 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + resources: + requests: + cpu: 10m + memory: 128Mi + webhook: + type: daemonset + revisionHistoryLimit: 3 + pod: + nodeSelector: + kubernetes.io/arch: amd64 + containers: + main: + image: + repository: ghcr.io/n8n-io/n8n + tag: 1.93.0 + pullPolicy: IfNotPresent + command: + - n8n + args: + - webhook + env: + - name: GENERIC_TIMEZONE + value: US/Central + - name: DB_TYPE + value: postgresdb + - name: DB_POSTGRESDB_DATABASE + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: dbname + - name: DB_POSTGRESDB_DATABASE + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: dbname + - name: DB_POSTGRESDB_HOST + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: host + - name: DB_POSTGRESDB_PORT + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: port + - name: DB_POSTGRESDB_USER + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: user + - name: DB_POSTGRESDB_PASSWORD + valueFrom: + secretKeyRef: + name: n8n-postgresql-17-cluster-app + key: password + - name: N8N_METRICS + value: true + - name: QUEUE_HEALTH_CHECK_ACTIVE + value: true + - name: EXECUTIONS_MODE + value: queue + - name: QUEUE_BULL_REDIS_HOST + value: n8n-valkey-headless.n8n + - name: N8N_ENCRYPTION_KEY + valueFrom: + secretKeyRef: + name: n8n-config-secret + key: key + - name: WEBHOOK_URL + value: https://n8n.alexlebens.net/ + - name: N8N_DIAGNOSTICS_ENABLED + value: false + - name: N8N_VERSION_NOTIFICATIONS_ENABLED + value: false + probes: + liveness: + enabled: true + custom: true + spec: + httpGet: + path: /healthz + port: 5678 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + readiness: + enabled: true + custom: true + spec: + httpGet: + path: /healthz/readiness + port: 5678 + initialDelaySeconds: 0 + periodSeconds: 10 + timeoutSeconds: 1 + failureThreshold: 3 + resources: + requests: + cpu: 10m + memory: 128Mi + service: + main: + controller: main + ports: + http: + port: 80 + targetPort: 5678 + protocol: HTTP + worker: + controller: worker + ports: + http: + port: 80 + targetPort: 5678 + protocol: HTTP + webhook: + controller: webhook + ports: + http: + port: 80 + targetPort: 5678 + protocol: HTTP + persistence: + data: + storageClass: ceph-block + accessMode: ReadWriteOnce + size: 5Gi + advancedMounts: + main: + main: + - path: /data + readOnly: false + cache: + type: emptyDir + advancedMounts: + worker: + main: + - path: /home/node/.n8n + readOnly: false + webhook: + main: + - path: /home/node/.n8n + readOnly: false +valkey: + architecture: replication + auth: + enabled: false + usePasswordFiles: false + primary: + resources: + requests: + cpu: 100m + memory: 64Mi + persistence: + enabled: true + size: 1Gi + replica: + replicaCount: 1 + resources: + requests: + cpu: 100m + memory: 64Mi + persistence: + enabled: true + size: 1Gi +postgres-17-cluster: + mode: standalone + cluster: + storage: + storageClass: local-path + walStorage: + storageClass: local-path + monitoring: + enabled: true + prometheusRule: + enabled: true + recovery: + method: objectStore + objectStore: + endpointURL: https://nyc3.digitaloceanspaces.com + destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/n8n/n8n-postgresql-17-cluster + endpointCredentials: n8n-postgresql-17-cluster-backup-secret + recoveryIndex: 1 + backup: + enabled: true + endpointURL: https://nyc3.digitaloceanspaces.com + destinationPath: s3://postgres-backups-ce540ddf106d186bbddca68a/cl01tl/n8n/n8n-postgresql-17-cluster + endpointCredentials: n8n-postgresql-17-cluster-backup-secret + backupIndex: 1 diff --git a/clusters/cl01tl/services/blocky/values.yaml b/clusters/cl01tl/services/blocky/values.yaml index 8265933b3..89afe1c67 100644 --- a/clusters/cl01tl/services/blocky/values.yaml +++ b/clusters/cl01tl/services/blocky/values.yaml @@ -132,6 +132,7 @@ blocky: mail IN CNAME traefik-cl01tl minio-directus IN CNAME traefik-cl01tl minio-outline IN CNAME traefik-cl01tl + n8n IN CNAME traefik-cl01tl ntfy IN CNAME traefik-cl01tl ollama IN CNAME traefik-cl01tl overseerr IN CNAME traefik-cl01tl diff --git a/hosts/ps08rp/blocky/config.yml b/hosts/ps08rp/blocky/config.yml index 5818c579e..142d53f97 100644 --- a/hosts/ps08rp/blocky/config.yml +++ b/hosts/ps08rp/blocky/config.yml @@ -107,6 +107,7 @@ customDNS: mail IN CNAME traefik-cl01tl minio-directus IN CNAME traefik-cl01tl minio-outline IN CNAME traefik-cl01tl + n8n IN CNAME traefik-cl01tl ntfy IN CNAME traefik-cl01tl ollama IN CNAME traefik-cl01tl overseerr IN CNAME traefik-cl01tl diff --git a/hosts/ps09rp/blocky/config.yml b/hosts/ps09rp/blocky/config.yml index 5818c579e..142d53f97 100644 --- a/hosts/ps09rp/blocky/config.yml +++ b/hosts/ps09rp/blocky/config.yml @@ -107,6 +107,7 @@ customDNS: mail IN CNAME traefik-cl01tl minio-directus IN CNAME traefik-cl01tl minio-outline IN CNAME traefik-cl01tl + n8n IN CNAME traefik-cl01tl ntfy IN CNAME traefik-cl01tl ollama IN CNAME traefik-cl01tl overseerr IN CNAME traefik-cl01tl