I'll assume that you have read my previous article about Cloudflare tunnel and everything is up and running as needed. If not, go ahead and read it.
n8n is a fair-code licensed node-based workflow automation tool.
Fair-code is not a software license.
It describes a software model where software:
is generally free to use and can be distributed by anybody
has its source code openly available
can be extended by anybody in public and private communities
is commercially restricted by its authors
I am not going to go into more details, you are free to check n8n website to see what they offer and what you can do with it.
My setup is not the most secure one, so I assume that you will be running it locally on your RPI, as I am still learning the ups/downs of Kubernetes and there is a lot that I need to read/learn to cover all the security manners.
Requirements
n8n needs 3 main things to be configured and ready:
- Storage space.
- Service port.
- database
Before we start, make sure you create an empty database in your PostgreSQL instance, check our post for reference.
Storage Configuration:
There is a lot of options here, but you need to familiarize yourself with what K3s storage provides, remember K3s is a slimier version of K8s so not everything is available for you to use. Luckily for us, the local storage option is available.
So, what we will define is a local storage with read/write access permission and with 5GB of space, we can use the following to create it:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: n8n-pvc namespace: n8n-server spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 5Gi
Port Configuration
We are not going to change the default port, but we need to configure out cluster to allow the access to this port, so we have it like this:
apiVersion: v1 kind: Service metadata: name: n8n namespace: n8n-server spec: selector: app: n8n type: LoadBalancer ports: - name: n8n-port protocol: TCP port: 5678
Deployment
Now that we have the most basic information we need, we gather everything in one big yml
file.
Lets call our yaml file n8n.yml
and inside of it lets add the following:
--- apiVersion: v1 kind: Namespace metadata: name: n8n-server --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: n8n-pvc namespace: n8n-server spec: accessModes: - ReadWriteOnce storageClassName: local-path resources: requests: storage: 5Gi --- apiVersion: v1 kind: Service metadata: name: n8n namespace: n8n-server spec: selector: app: n8n type: LoadBalancer ports: - name: n8n-port protocol: TCP port: 5678 --- apiVersion: apps/v1 kind: Deployment metadata: name: n8n namespace: n8n-server spec: replicas: 1 selector: matchLabels: app: n8n template: metadata: labels: app: n8n name: n8n spec: nodeSelector: kubernetes.io/hostname: worker-2 containers: - name: n8n image: n8nio/n8n:latest imagePullPolicy: Always ports: - name: n8n containerPort: 5678 env: - name: NODE_ENV value: production - name: GENERIC_TIMEZONE value: Europe/Istanbul - name: WEBHOOK_TUNNEL_URL value: https://n8n.cluster.local:5678/ - name: DB_TYPE value: postgresdb - name: DB_POSTGRESDB_USER value: postgres - name: DB_POSTGRESDB_PASSWORD value: secret - name: DB_POSTGRESDB_DATABASE value: "n8n" - name: DB_POSTGRESDB_HOST value: postgres.postgres-server - name: DB_POSTGRESDB_PORT value: "5432" - name: N8N_ENCRYPTION_KEY value: "n8n" - name: N8N_BASIC_AUTH_ACTIVE value: "true" - name: N8N_BASIC_AUTH_PASSWORD value: admin - name: N8N_BASIC_AUTH_USER value: admin - name: N8N_PROTOCOL value: https - name: N8N_HOST value: n8n.cluster.local - name: N8N_PORT value: "5678" resources: limits: cpu: "1.0" memory: "1024Mi" requests: cpu: "0.5" memory: "512Mi" volumeMounts: - name: n8n-storage mountPath: /root/.n8n - name: n8n-storage mountPath: /opt/workflows volumes: - name: n8n-storage persistentVolumeClaim: claimName: n8n-pvc
If you like to know more about each and every environment variable that you can use, you can read the documentation here, but in general the one that I use setup the instance internal URL, the database configuration (I use the local postgres that we setup), the basic auth (for local service you don't need, so feel free to keep or remove them).
Since we stored all the information in one big file, all we need to do is to run the following command (from within your RPI):
kubectl apply -f n8n.yml
To check that everything is running we can run the following command:
kubectl get svc -n n8n-server
if everything was okay, you will get something like the following:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE n8n LoadBalancer 10.43.105.20 192.168.68.110,192.168.68.111,192.168.68.112 5678:30687/TCP 22d
You can now access the service by heading to your browser and visit the following url : http://19.168.68.110:5678
and you will be see something similar to this one, but without those workflows (these are the one I created/imported after the setup)

For sure, my RPI ip address is different than yours so you will need to use your RPI ip address not mine.
Cloudflare Tunnel
Assuming that your tunnel is up and running, as I mentioned here, you have to click on configure

and then click on public hostname

Then you will click on add a public hostname and add the following information, use your domain and the local IP address for your RPI

Once you save it, everything should like this

You can add as many public hosts as you want to your tunnel as long as they can connect to the local services.
You know that everything is working as it should, when you see the status healthy as the following from the tunnels list main page.

You can now use the url to access your instance, and since we configured the BASIC AUTH environment variable, your service is semi protected, but there is better way to protect it which is by using an identity provider, and Cloudflare provide you with many options to choose from

Talking about adding an identity provider is not within the scope of this article, but basically you will have to configure one then add an application with the same URL for that you use for your instance and choose that provider as your authentication method.