apiVersion: v1 kind: Namespace metadata: name: automation labels: name: automation --- apiVersion: v1 kind: PersistentVolume metadata: name: n8n-pv labels: app: n8n spec: capacity: storage: 20Gi volumeMode: Filesystem accessModes: - ReadWriteOnce persistentVolumeReclaimPolicy: Retain storageClassName: local-ssd local: path: /mnt/local-ssd/n8n nodeAffinity: required: nodeSelectorTerms: - matchExpressions: - key: kubernetes.io/hostname operator: In values: - hetzner-2 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: n8n-data namespace: automation labels: app: n8n spec: accessModes: - ReadWriteOnce storageClassName: local-ssd resources: requests: storage: 20Gi selector: matchLabels: app: n8n --- apiVersion: v1 kind: Secret metadata: name: n8n-secrets namespace: automation type: Opaque stringData: # Generate a strong encryption key with: openssl rand -base64 32 N8N_ENCRYPTION_KEY: "G/US0ePajEpWwRUjlchyOs6+6I/AT+0bisXmE2fugSU=" # Optional: Database connection if using PostgreSQL DB_TYPE: "postgresdb" DB_POSTGRESDB_HOST: "pg.betelgeusebytes.io" DB_POSTGRESDB_PORT: "5432" DB_POSTGRESDB_DATABASE: "n8n" DB_POSTGRESDB_USER: "app" DB_POSTGRESDB_PASSWORD: "pa$$word" --- apiVersion: apps/v1 kind: StatefulSet metadata: name: n8n namespace: automation spec: serviceName: n8n replicas: 1 selector: matchLabels: app: n8n template: metadata: labels: app: n8n spec: nodeSelector: kubernetes.io/hostname: hetzner-2 containers: - name: n8n image: n8nio/n8n:latest ports: - containerPort: 5678 name: http env: - name: N8N_HOST value: "n8n.betelgeusebytes.io" - name: N8N_PORT value: "5678" - name: N8N_PROTOCOL value: "https" - name: WEBHOOK_URL value: "https://n8n.betelgeusebytes.io/" - name: GENERIC_TIMEZONE value: "UTC" - name: N8N_ENCRYPTION_KEY valueFrom: secretKeyRef: name: n8n-secrets key: N8N_ENCRYPTION_KEY # Uncomment if using PostgreSQL - name: DB_TYPE valueFrom: secretKeyRef: name: n8n-secrets key: DB_TYPE - name: DB_POSTGRESDB_HOST valueFrom: secretKeyRef: name: n8n-secrets key: DB_POSTGRESDB_HOST - name: DB_POSTGRESDB_PORT valueFrom: secretKeyRef: name: n8n-secrets key: DB_POSTGRESDB_PORT - name: DB_POSTGRESDB_DATABASE valueFrom: secretKeyRef: name: n8n-secrets key: DB_POSTGRESDB_DATABASE - name: DB_POSTGRESDB_USER valueFrom: secretKeyRef: name: n8n-secrets key: DB_POSTGRESDB_USER - name: DB_POSTGRESDB_PASSWORD valueFrom: secretKeyRef: name: n8n-secrets key: DB_POSTGRESDB_PASSWORD volumeMounts: - name: n8n-data mountPath: /home/node/.n8n resources: requests: memory: "512Mi" cpu: "250m" limits: memory: "2Gi" cpu: "1000m" livenessProbe: httpGet: path: /healthz port: 5678 initialDelaySeconds: 60 periodSeconds: 30 timeoutSeconds: 10 failureThreshold: 5 readinessProbe: httpGet: path: /healthz port: 5678 initialDelaySeconds: 30 periodSeconds: 10 timeoutSeconds: 5 failureThreshold: 3 volumes: - name: n8n-data persistentVolumeClaim: claimName: n8n-data --- apiVersion: v1 kind: Service metadata: name: n8n namespace: automation labels: app: n8n spec: type: ClusterIP ports: - port: 5678 targetPort: 5678 protocol: TCP name: http selector: app: n8n --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: n8n namespace: automation annotations: cert-manager.io/cluster-issuer: "letsencrypt-prod" # nginx.ingress.kubernetes.io/proxy-body-size: "50m" # nginx.ingress.kubernetes.io/proxy-read-timeout: "300" # nginx.ingress.kubernetes.io/proxy-send-timeout: "300" # Uncomment below if you want basic auth protection in addition to n8n's auth # nginx.ingress.kubernetes.io/auth-type: basic # nginx.ingress.kubernetes.io/auth-secret: n8n-basic-auth # nginx.ingress.kubernetes.io/auth-realm: 'Authentication Required' spec: ingressClassName: nginx tls: - hosts: - n8n.betelgeusebytes.io secretName: wildcard-betelgeusebytes-tls rules: - host: n8n.betelgeusebytes.io http: paths: - path: / pathType: Prefix backend: service: name: n8n port: number: 5678