2ea469af1e
optional: true covers a Secret that does not exist; it does not cover the variable being unset. Flux substitutes in strict mode, so the unused second slot failed the whole build and every change to this repo since has silently stopped reaching the cluster. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
135 lines
4.6 KiB
YAML
135 lines
4.6 KiB
YAML
apiVersion: apps/v1
|
|
kind: Deployment
|
|
metadata:
|
|
name: n8n
|
|
namespace: ${NAMESPACE}
|
|
spec:
|
|
# One replica. n8n's queue mode splits the editor from workers and needs Redis
|
|
# to do it; without that, a second replica is two schedulers racing over the
|
|
# same cron triggers. See the README before scaling this.
|
|
replicas: 1
|
|
strategy:
|
|
# The volume is ReadWriteOnce, so a rolling update deadlocks: the new pod
|
|
# waits for a volume the old pod has not released.
|
|
type: Recreate
|
|
selector:
|
|
matchLabels:
|
|
app: n8n
|
|
template:
|
|
metadata:
|
|
labels:
|
|
app: n8n
|
|
spec:
|
|
securityContext:
|
|
runAsNonRoot: true
|
|
runAsUser: 1000
|
|
fsGroup: 1000
|
|
initContainers:
|
|
- name: wait-for-postgres
|
|
image: ${POSTGRES_IMAGE}
|
|
command:
|
|
- sh
|
|
- -c
|
|
- |
|
|
until pg_isready -h n8n-postgres -U n8n -d n8n; do
|
|
echo "waiting for postgres..."; sleep 3
|
|
done
|
|
containers:
|
|
- name: n8n
|
|
image: ${N8N_IMAGE}
|
|
ports:
|
|
- name: http
|
|
containerPort: 5678
|
|
env:
|
|
- name: DB_TYPE
|
|
value: postgresdb
|
|
- name: DB_POSTGRESDB_HOST
|
|
value: n8n-postgres
|
|
- name: DB_POSTGRESDB_PORT
|
|
value: "5432"
|
|
- name: DB_POSTGRESDB_DATABASE
|
|
value: n8n
|
|
- name: DB_POSTGRESDB_USER
|
|
value: n8n
|
|
- name: DB_POSTGRESDB_PASSWORD
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: n8n-secrets
|
|
key: DB_PASSWORD
|
|
# Encrypts stored credentials. Held in Vault, never regenerated —
|
|
# a new key does not re-encrypt, it orphans everything already
|
|
# stored.
|
|
- name: N8N_ENCRYPTION_KEY
|
|
valueFrom:
|
|
secretKeyRef:
|
|
name: n8n-secrets
|
|
key: N8N_ENCRYPTION_KEY
|
|
# A private CA to trust, so a workflow can call an internal
|
|
# endpoint over TLS without anyone disabling verification to make it
|
|
# work. n8n is Node, hence this variable rather than a trust store.
|
|
# Provided by the deployment; an empty ConfigMap disables it in
|
|
# practice, since the file will not exist and Node falls back to its
|
|
# own bundle.
|
|
- name: NODE_EXTRA_CA_CERTS
|
|
value: /etc/extra-ca/ca.crt
|
|
envFrom:
|
|
- configMapRef:
|
|
name: n8n-config
|
|
# Whatever else this deployment's workflows need in their
|
|
# environment. Provided by the deployment, not by this repo: an
|
|
# empty Secret of that name is a valid answer.
|
|
#
|
|
# Two slots rather than one, because a deployment's environment
|
|
# usually comes from more than one owner — credentials the platform
|
|
# holds, and credentials a workflow's own estate holds.
|
|
#
|
|
# `optional: true` covers a Secret that does not exist; the `:=`
|
|
# defaults cover the *variable* not being set. Both are needed, and
|
|
# only the first was here: Flux substitutes in strict mode, so an
|
|
# unused slot failed the whole build rather than being skipped, and
|
|
# every later change to this repo silently stopped reaching the
|
|
# cluster.
|
|
- secretRef:
|
|
name: ${EXTRA_ENV_SECRET:=n8n-extra-env}
|
|
optional: true
|
|
- secretRef:
|
|
name: ${EXTRA_ENV_SECRET_2:=n8n-extra-env-2}
|
|
optional: true
|
|
volumeMounts:
|
|
- name: data
|
|
mountPath: /home/node/.n8n
|
|
- name: extra-ca
|
|
mountPath: /etc/extra-ca
|
|
readOnly: true
|
|
readinessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: http
|
|
initialDelaySeconds: 15
|
|
periodSeconds: 10
|
|
livenessProbe:
|
|
httpGet:
|
|
path: /healthz
|
|
port: http
|
|
initialDelaySeconds: 60
|
|
periodSeconds: 20
|
|
resources:
|
|
requests:
|
|
cpu: 100m
|
|
memory: 512Mi
|
|
limits:
|
|
cpu: "2"
|
|
memory: 2Gi
|
|
securityContext:
|
|
allowPrivilegeEscalation: false
|
|
capabilities:
|
|
drop: ["ALL"]
|
|
volumes:
|
|
- name: data
|
|
persistentVolumeClaim:
|
|
claimName: n8n-data
|
|
- name: extra-ca
|
|
configMap:
|
|
name: ${EXTRA_CA_CONFIGMAP}
|
|
optional: true
|