Files
infra-n8n/k8s/n8n/deployment.yaml
T
Stéphane Tailland f0363748b6 feat: a second environment-secret slot
A deployment's workflow environment usually comes from more than one owner —
credentials the platform holds, and credentials the workflows' own estate holds.
Both slots are optional, so an unused one needs no placeholder Secret.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-29 17:42:31 +02:00

129 lines
4.2 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. Both are
# marked optional, so an unused slot needs no placeholder Secret.
- secretRef:
name: ${EXTRA_ENV_SECRET}
optional: true
- secretRef:
name: ${EXTRA_ENV_SECRET_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