1949 lines
74 KiB
Markdown
1949 lines
74 KiB
Markdown
|
|
# N8N Workflow Automation Server - Setup Plan
|
|||
|
|
|
|||
|
|
**Document Created**: 2025-11-29
|
|||
|
|
**Infrastructure Survey Date**: 2025-11-29 14:13:39
|
|||
|
|
**Proxmox Node**: serviceslab
|
|||
|
|
**Author**: The Scribe (Steve's Architecture Module)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Executive Summary
|
|||
|
|
|
|||
|
|
This document provides a comprehensive plan for deploying n8n (a powerful workflow automation platform) in your Proxmox homelab. After analyzing your current infrastructure, I recommend deploying n8n as an **LXC container** with PostgreSQL database backing, reverse-proxied through your existing nginx container for SSL termination and secure external access.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## I. Current Infrastructure Overview
|
|||
|
|
|
|||
|
|
### Proxmox Host Specifications
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
╔════════════════════════════════════════════════════════════════╗
|
|||
|
|
║ PROXMOX NODE: serviceslab ║
|
|||
|
|
╠════════════════════════════════════════════════════════════════╣
|
|||
|
|
║ Version: Proxmox VE 8.3.3 ║
|
|||
|
|
║ Architecture: Single-node cluster ║
|
|||
|
|
║ CPU: Dual Intel Xeon X5670 @ 2.93GHz ║
|
|||
|
|
║ (2 sockets × 6 cores × 2 threads = 24 vCPUs) ║
|
|||
|
|
║ RAM: 173 GB total ║
|
|||
|
|
║ - Used: 92 GB ║
|
|||
|
|
║ - Available: 80 GB ║
|
|||
|
|
║ Management IP: 192.168.2.100/24 ║
|
|||
|
|
╚════════════════════════════════════════════════════════════════╝
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Storage Infrastructure
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Storage Pool Size Used Free Usage Type │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ local 43.9G 6.4G 35G 16% ext4 │
|
|||
|
|
│ Purpose: ISOs, templates, backups │
|
|||
|
|
│ │
|
|||
|
|
│ local-lvm 65.8G N/A N/A N/A LVM │
|
|||
|
|
│ Purpose: VM disk images (thin provisioned) │
|
|||
|
|
│ │
|
|||
|
|
│ Vault (ZFS) 4.36T 124G 4.24T 2% ZFS │
|
|||
|
|
│ Purpose: Primary VM/LXC storage │
|
|||
|
|
│ Health: ONLINE │
|
|||
|
|
│ Compression: Enabled │
|
|||
|
|
│ │
|
|||
|
|
│ PBS-Backups Remote storage at 192.168.2.151 │
|
|||
|
|
│ Purpose: Proxmox Backup Server repository │
|
|||
|
|
│ │
|
|||
|
|
│ iso-share (NFS) 3.1T at 192.168.2.150 │
|
|||
|
|
│ Purpose: Shared ISO library │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Network Configuration
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌──────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Network Topology │
|
|||
|
|
├──────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ Physical NIC: eno1 (f0:4d:a2:04:0c:17) │
|
|||
|
|
│ │ │
|
|||
|
|
│ └──► vmbr0 (Primary Bridge) │
|
|||
|
|
│ │ │
|
|||
|
|
│ ├─ IP: 192.168.2.100/24 │
|
|||
|
|
│ ├─ Gateway: 192.168.2.1 │
|
|||
|
|
│ ├─ VLAN-aware: yes │
|
|||
|
|
│ └─ VLAN range: 2-4094 │
|
|||
|
|
│ │
|
|||
|
|
│ vmbr1 (Isolated Network) │
|
|||
|
|
│ └─ IP: 192.168.3.0/24 │
|
|||
|
|
│ Purpose: Internal services network │
|
|||
|
|
│ │
|
|||
|
|
│ VLAN 5: Used for web servers and ansible control │
|
|||
|
|
└──────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Existing Virtual Machines (QEMU/KVM)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────┬─────────────────────┬───────┬──────────┬──────────┬────────────┐
|
|||
|
|
│ VM ID │ Name │ vCPU │ RAM (GB) │ Disk │ Network │
|
|||
|
|
├────────┼─────────────────────┼───────┼──────────┼──────────┼────────────┤
|
|||
|
|
│ 100 │ docker-hub │ 4 │ 8.2 │ 100G │ vmbr0 │
|
|||
|
|
│ 101 │ gitlab │ 4 │ 17.0 │ 50G │ vmbr0 │
|
|||
|
|
│ 104 │ ubuntu-dev │ N/A │ N/A │ N/A │ vmbr0 │
|
|||
|
|
│ 105 │ dev │ N/A │ N/A │ N/A │ vmbr0 │
|
|||
|
|
│ 106 │ Ansible-Control │ 2 │ 4.0 │ 32G │ vmbr0.5 │
|
|||
|
|
│ 107 │ ubuntu-docker │ 2 │ 4.0 │ 50G │ vmbr0 │
|
|||
|
|
│ │ (Template) │ │ │ │ │
|
|||
|
|
│ 108 │ CML │ N/A │ N/A │ N/A │ vmbr0 │
|
|||
|
|
│ 109 │ web-server-01 │ 1 │ 2.0 │ 32G │ vmbr0.5 │
|
|||
|
|
│ 110 │ web-server-02 │ N/A │ N/A │ 32G │ vmbr0.5 │
|
|||
|
|
│ 111 │ db-server-01 │ 1 │ 4.0 │ 32G │ vmbr0.5 │
|
|||
|
|
└────────┴─────────────────────┴───────┴──────────┴──────────┴────────────┘
|
|||
|
|
|
|||
|
|
Total VM Resources: ~11 vCPUs, ~40 GB RAM
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Existing LXC Containers
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────┬─────────────────────┬───────┬──────────┬──────────┬────────────┐
|
|||
|
|
│ CT ID │ Name │ Cores │ RAM (GB) │ Disk │ IP Address │
|
|||
|
|
├────────┼─────────────────────┼───────┼──────────┼──────────┼────────────┤
|
|||
|
|
│ 102 │ nginx │ 1 │ 2.0 │ 2G │ 192.168. │
|
|||
|
|
│ │ (Reverse Proxy) │ │ │ │ 2.101/24 │
|
|||
|
|
│ │ │ │ │ │ │
|
|||
|
|
│ 103 │ netbox │ N/A │ N/A │ N/A │ DHCP │
|
|||
|
|
│ │ (IPAM/Docs) │ │ │ │ │
|
|||
|
|
│ │ │ │ │ │ │
|
|||
|
|
│ 112 │ Anytype │ 2 │ 4.0 │ 25G │ DHCP │
|
|||
|
|
│ │ (Knowledge Mgmt) │ │ │ │ │
|
|||
|
|
└────────┴─────────────────────┴───────┴──────────┴──────────┴────────────┘
|
|||
|
|
|
|||
|
|
Features: All containers have nesting=1 (Docker support)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Resource Availability Assessment
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
╔═══════════════════════════════════════════════════════════════╗
|
|||
|
|
║ AVAILABLE RESOURCES ║
|
|||
|
|
╠═══════════════════════════════════════════════════════════════╣
|
|||
|
|
║ CPU: ~13 vCPUs available (24 total - ~11 allocated) ║
|
|||
|
|
║ RAM: ~80 GB available ║
|
|||
|
|
║ Disk: 4.12 TB available on Vault ZFS pool ║
|
|||
|
|
║ ║
|
|||
|
|
║ Verdict: EXCELLENT capacity for n8n deployment ║
|
|||
|
|
╚═══════════════════════════════════════════════════════════════╝
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## II. N8N Architecture Decision: LXC vs VM
|
|||
|
|
|
|||
|
|
### The Verdict: **LXC Container (Recommended)**
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ LXC vs VM Comparison │
|
|||
|
|
├──────────────────┬──────────────────────┬───────────────────────┤
|
|||
|
|
│ Factor │ LXC Container │ Virtual Machine │
|
|||
|
|
├──────────────────┼──────────────────────┼───────────────────────┤
|
|||
|
|
│ Boot Time │ < 5 seconds │ 30-60 seconds │
|
|||
|
|
│ RAM Overhead │ ~100 MB │ ~500 MB │
|
|||
|
|
│ Disk Space │ ~2-5 GB │ ~10-15 GB │
|
|||
|
|
│ Performance │ Near-native │ Slight overhead │
|
|||
|
|
│ Snapshot Speed │ Instant (ZFS) │ 5-30 seconds │
|
|||
|
|
│ Backup Size │ Smaller │ Larger │
|
|||
|
|
│ Docker Support │ Yes (with nesting) │ Native │
|
|||
|
|
│ Resource Isol. │ Good │ Excellent │
|
|||
|
|
│ Complexity │ Simple │ Moderate │
|
|||
|
|
└──────────────────┴──────────────────────┴───────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Why LXC for n8n?
|
|||
|
|
|
|||
|
|
**Advantages:**
|
|||
|
|
1. **Efficiency**: n8n is a Node.js application with modest requirements. LXC provides near-native performance with minimal overhead.
|
|||
|
|
2. **Fast Deployment**: Container creation takes seconds vs minutes for VMs.
|
|||
|
|
3. **Resource Conservation**: Uses ~500 MB less RAM than a VM, leaving more resources for workflows.
|
|||
|
|
4. **ZFS Snapshots**: Instant snapshots before updates or configuration changes.
|
|||
|
|
5. **Consistency**: Your existing nginx reverse proxy (CT 102) is already an LXC container.
|
|||
|
|
6. **Docker Compatibility**: With `nesting=1` feature, the container can run Docker if needed for custom nodes.
|
|||
|
|
|
|||
|
|
**Considerations:**
|
|||
|
|
- n8n doesn't require kernel-level isolation that VMs provide
|
|||
|
|
- No exotic hardware requirements
|
|||
|
|
- Perfectly suited for containerized deployment
|
|||
|
|
|
|||
|
|
### When to Use a VM Instead:
|
|||
|
|
|
|||
|
|
You would only need a VM if:
|
|||
|
|
- Running n8n with Windows-specific integrations
|
|||
|
|
- Requiring complete kernel isolation for security
|
|||
|
|
- Testing multiple OS environments simultaneously
|
|||
|
|
- Planning to run heavy compute workloads within workflows
|
|||
|
|
|
|||
|
|
**For typical n8n workflow automation: LXC is the superior choice.**
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## III. N8N Server Specifications
|
|||
|
|
|
|||
|
|
### Recommended LXC Configuration
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ N8N LXC Container Specs │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Container ID: 113 (next available) │
|
|||
|
|
│ Hostname: n8n │
|
|||
|
|
│ OS Template: Debian 12 (bookworm) or Ubuntu 24.04 LTS │
|
|||
|
|
│ │
|
|||
|
|
│ vCPU Cores: 2 (scalable to 4 if needed) │
|
|||
|
|
│ RAM: 4096 MB (4 GB) │
|
|||
|
|
│ Swap: 2048 MB (2 GB) │
|
|||
|
|
│ │
|
|||
|
|
│ Root Disk: 20 GB (Vault ZFS pool) │
|
|||
|
|
│ - OS: ~2 GB │
|
|||
|
|
│ - n8n: ~1 GB │
|
|||
|
|
│ - PostgreSQL: ~2 GB │
|
|||
|
|
│ - Workflow data: ~5 GB │
|
|||
|
|
│ - Growth buffer: ~10 GB │
|
|||
|
|
│ │
|
|||
|
|
│ Network: vmbr0 (Primary bridge) │
|
|||
|
|
│ IP Address: 192.168.2.113/24 (static) │
|
|||
|
|
│ Gateway: 192.168.2.1 │
|
|||
|
|
│ DNS: 8.8.8.8, 8.8.4.4 │
|
|||
|
|
│ │
|
|||
|
|
│ Features: nesting=1 (Docker support) │
|
|||
|
|
│ Start on Boot: Yes (onboot: 1) │
|
|||
|
|
│ Unprivileged: Yes (security best practice) │
|
|||
|
|
│ Firewall: Yes (Proxmox firewall enabled) │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Performance Scaling Guide
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Usage Level vCPU RAM Disk Notes
|
|||
|
|
───────────────────────────────────────────────────────────────
|
|||
|
|
Light (< 10 workflows) 2 4 GB 20 GB Recommended start
|
|||
|
|
Medium (10-50) 2 6 GB 30 GB Most homelabs
|
|||
|
|
Heavy (50-100) 4 8 GB 50 GB Power users
|
|||
|
|
Enterprise (100+) 4 12 GB 100 GB Consider VM/K8s
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## IV. Network Architecture & Integration
|
|||
|
|
|
|||
|
|
### Network Diagram
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Internet
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
┌─────────────────┐
|
|||
|
|
│ Router/Firewall │
|
|||
|
|
│ 192.168.2.1 │
|
|||
|
|
└────────┬─────────┘
|
|||
|
|
│
|
|||
|
|
┌──────────┴───────────┐
|
|||
|
|
│ vmbr0 Bridge │
|
|||
|
|
│ 192.168.2.0/24 │
|
|||
|
|
└──────────┬───────────┘
|
|||
|
|
│
|
|||
|
|
┌──────────────────┼──────────────────────┐
|
|||
|
|
│ │ │
|
|||
|
|
▼ ▼ ▼
|
|||
|
|
┌──────────┐ ┌──────────┐ ┌──────────┐
|
|||
|
|
│ nginx │ │ n8n │ │ GitLab │
|
|||
|
|
│ CT: 102 │ │ CT: 113 │ │ VM: 101 │
|
|||
|
|
│ .101:80 │◄─────┤ .113:5678│ │ DHCP │
|
|||
|
|
│ .101:443 │ └──────────┘ └──────────┘
|
|||
|
|
└──────────┘ │
|
|||
|
|
│ ▼
|
|||
|
|
│ ┌──────────────┐
|
|||
|
|
│ │ PostgreSQL │
|
|||
|
|
│ │ (in CT 113) │
|
|||
|
|
│ │ localhost: │
|
|||
|
|
│ │ 5432 │
|
|||
|
|
│ └──────────────┘
|
|||
|
|
│
|
|||
|
|
▼
|
|||
|
|
SSL Termination
|
|||
|
|
n8n.yourdomain.com ──► https://192.168.2.113:5678
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### IP Address Allocation
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌──────────────────┬────────────────────┬──────────────────────┐
|
|||
|
|
│ IP Address │ Hostname │ Service │
|
|||
|
|
├──────────────────┼────────────────────┼──────────────────────┤
|
|||
|
|
│ 192.168.2.1 │ router │ Gateway │
|
|||
|
|
│ 192.168.2.100 │ serviceslab │ Proxmox Host │
|
|||
|
|
│ 192.168.2.101 │ nginx │ Reverse Proxy │
|
|||
|
|
│ 192.168.2.113 │ n8n │ N8N Server (NEW) │
|
|||
|
|
│ 192.168.2.150 │ NAS │ NFS Storage │
|
|||
|
|
│ 192.168.2.151 │ PBS │ Backup Server │
|
|||
|
|
└──────────────────┴────────────────────┴──────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Port Mapping Strategy
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Port Configuration │
|
|||
|
|
├────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Internal n8n Container: │
|
|||
|
|
│ 5678/tcp ──► n8n Web Interface (HTTP) │
|
|||
|
|
│ 5432/tcp ──► PostgreSQL (localhost only) │
|
|||
|
|
│ │
|
|||
|
|
│ Nginx Reverse Proxy (CT 102): │
|
|||
|
|
│ 443/tcp ──► HTTPS (proxies to n8n:5678) │
|
|||
|
|
│ 80/tcp ──► HTTP (redirects to HTTPS) │
|
|||
|
|
│ │
|
|||
|
|
│ External Access: │
|
|||
|
|
│ https://n8n.yourdomain.com ──► nginx:443 ──► n8n:5678 │
|
|||
|
|
└────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Firewall Rules
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
# Proxmox Firewall Configuration for CT 113 (n8n)
|
|||
|
|
|
|||
|
|
Direction Protocol Source Dest Port Action Comment
|
|||
|
|
─────────────────────────────────────────────────────────────────
|
|||
|
|
IN TCP 192.168.2.101 5678 ACCEPT nginx proxy
|
|||
|
|
IN TCP 192.168.2.0/24 22 ACCEPT SSH admin
|
|||
|
|
IN TCP 0.0.0.0/0 5678 DROP Block direct
|
|||
|
|
OUT TCP any 80,443 ACCEPT Updates/webhooks
|
|||
|
|
OUT TCP any 25,587 ACCEPT Email (SMTP)
|
|||
|
|
OUT UDP any 53 ACCEPT DNS
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## V. Database Architecture
|
|||
|
|
|
|||
|
|
### PostgreSQL vs SQLite Decision Matrix
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌───────────────────┬─────────────────────┬─────────────────────┐
|
|||
|
|
│ Factor │ PostgreSQL (Rec.) │ SQLite │
|
|||
|
|
├───────────────────┼─────────────────────┼─────────────────────┤
|
|||
|
|
│ Performance │ Excellent │ Good │
|
|||
|
|
│ Concurrent Access │ Full support │ Limited │
|
|||
|
|
│ Data Integrity │ ACID compliant │ ACID compliant │
|
|||
|
|
│ Backup/Restore │ Standard tools │ File copy │
|
|||
|
|
│ Scaling │ Unlimited │ Limited to 1-2 GB │
|
|||
|
|
│ HA/Clustering │ Yes │ No │
|
|||
|
|
│ Setup Complexity │ Moderate │ Zero config │
|
|||
|
|
│ Production Ready │ Yes │ For small setups │
|
|||
|
|
└───────────────────┴─────────────────────┴─────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**Recommendation**: **PostgreSQL** for production reliability and future growth.
|
|||
|
|
|
|||
|
|
### PostgreSQL Configuration
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ PostgreSQL Database Specifications │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ Version: PostgreSQL 16 (latest stable) │
|
|||
|
|
│ Installation: Same container as n8n (CT 113) │
|
|||
|
|
│ Database Name: n8n_db │
|
|||
|
|
│ Database User: n8n_user │
|
|||
|
|
│ Listen Address: 127.0.0.1 (localhost only) │
|
|||
|
|
│ Port: 5432 │
|
|||
|
|
│ Max Connections: 20 │
|
|||
|
|
│ Shared Buffers: 512 MB │
|
|||
|
|
│ Maintenance Work: 128 MB │
|
|||
|
|
│ WAL Level: replica (for backups) │
|
|||
|
|
│ │
|
|||
|
|
│ Backup Strategy: │
|
|||
|
|
│ - Daily pg_dump to /var/backups/n8n/ │
|
|||
|
|
│ - Proxmox container backup to PBS (weekly) │
|
|||
|
|
│ - ZFS snapshots before updates (manual) │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## VI. Integration with Existing Services
|
|||
|
|
|
|||
|
|
### A. Nginx Reverse Proxy (CT 102)
|
|||
|
|
|
|||
|
|
Your existing nginx container will handle:
|
|||
|
|
|
|||
|
|
1. **SSL/TLS Termination** - Let's Encrypt certificates
|
|||
|
|
2. **HTTPS Enforcement** - HTTP to HTTPS redirect
|
|||
|
|
3. **Security Headers** - HSTS, CSP, X-Frame-Options
|
|||
|
|
4. **Rate Limiting** - Prevent abuse
|
|||
|
|
5. **Access Logging** - Centralized logging
|
|||
|
|
|
|||
|
|
**Nginx Configuration Snippet:**
|
|||
|
|
|
|||
|
|
```nginx
|
|||
|
|
# /etc/nginx/sites-available/n8n.yourdomain.com
|
|||
|
|
|
|||
|
|
upstream n8n_backend {
|
|||
|
|
server 192.168.2.113:5678;
|
|||
|
|
keepalive 32;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
server {
|
|||
|
|
listen 80;
|
|||
|
|
server_name n8n.yourdomain.com;
|
|||
|
|
return 301 https://$server_name$request_uri;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
server {
|
|||
|
|
listen 443 ssl http2;
|
|||
|
|
server_name n8n.yourdomain.com;
|
|||
|
|
|
|||
|
|
# SSL Configuration (Let's Encrypt)
|
|||
|
|
ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
|
|||
|
|
ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;
|
|||
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|||
|
|
ssl_ciphers HIGH:!aNULL:!MD5;
|
|||
|
|
|
|||
|
|
# Security Headers
|
|||
|
|
add_header Strict-Transport-Security "max-age=31536000" always;
|
|||
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|||
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|||
|
|
|
|||
|
|
# Proxy Settings
|
|||
|
|
location / {
|
|||
|
|
proxy_pass http://n8n_backend;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
proxy_set_header Upgrade $http_upgrade;
|
|||
|
|
proxy_set_header Connection "upgrade";
|
|||
|
|
proxy_set_header Host $host;
|
|||
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|||
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|||
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|||
|
|
|
|||
|
|
# Timeouts for long-running workflows
|
|||
|
|
proxy_connect_timeout 300s;
|
|||
|
|
proxy_send_timeout 300s;
|
|||
|
|
proxy_read_timeout 300s;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Health check endpoint
|
|||
|
|
location /healthz {
|
|||
|
|
proxy_pass http://n8n_backend/healthz;
|
|||
|
|
access_log off;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### B. GitLab Integration (VM 101)
|
|||
|
|
|
|||
|
|
N8N can automate GitLab workflows:
|
|||
|
|
|
|||
|
|
- **CI/CD Triggers** - Start pipelines on external events
|
|||
|
|
- **Issue Management** - Auto-create/update issues from tickets
|
|||
|
|
- **Merge Request Automation** - Code review workflows
|
|||
|
|
- **Repository Monitoring** - Track commits, tags, releases
|
|||
|
|
- **Deployment Notifications** - Slack/email on deployments
|
|||
|
|
|
|||
|
|
**Connection:**
|
|||
|
|
- GitLab API available at VM 101's IP (configure in n8n)
|
|||
|
|
- Create Personal Access Token in GitLab with API scope
|
|||
|
|
- Store token in n8n credentials manager
|
|||
|
|
|
|||
|
|
### C. Docker Hub (VM 100)
|
|||
|
|
|
|||
|
|
Integration possibilities:
|
|||
|
|
|
|||
|
|
- **Image Update Notifications** - Alert on new image versions
|
|||
|
|
- **Automated Pulls** - Trigger container updates
|
|||
|
|
- **Build Monitoring** - Track image builds
|
|||
|
|
|
|||
|
|
### D. Ansible Control (VM 106)
|
|||
|
|
|
|||
|
|
N8N can trigger Ansible playbooks:
|
|||
|
|
|
|||
|
|
- **Infrastructure Automation** - Run playbooks via webhook
|
|||
|
|
- **Configuration Management** - Scheduled config updates
|
|||
|
|
- **Orchestration** - Multi-system deployment workflows
|
|||
|
|
|
|||
|
|
**Setup Method:**
|
|||
|
|
- n8n HTTP Request node → Ansible AWX/Tower REST API
|
|||
|
|
- Or: n8n Execute Command node via SSH to Ansible Control VM
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## VII. Step-by-Step Setup Plan
|
|||
|
|
|
|||
|
|
### Phase 1: Container Creation (15 minutes)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Create LXC Container │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
Option A: Proxmox Web UI Method
|
|||
|
|
─────────────────────────────────
|
|||
|
|
1. Login to Proxmox at https://192.168.2.100:8006
|
|||
|
|
2. Click "Create CT" button
|
|||
|
|
3. Configure container:
|
|||
|
|
|
|||
|
|
General:
|
|||
|
|
├─ Node: serviceslab
|
|||
|
|
├─ CT ID: 113
|
|||
|
|
├─ Hostname: n8n
|
|||
|
|
├─ Unprivileged: ☑ (checked)
|
|||
|
|
└─ Password: [Set strong password]
|
|||
|
|
|
|||
|
|
Template:
|
|||
|
|
└─ Storage: local
|
|||
|
|
Template: debian-12-standard (or ubuntu-24.04-standard)
|
|||
|
|
|
|||
|
|
Disks:
|
|||
|
|
├─ Storage: Vault
|
|||
|
|
└─ Disk size: 20 GB
|
|||
|
|
|
|||
|
|
CPU:
|
|||
|
|
└─ Cores: 2
|
|||
|
|
|
|||
|
|
Memory:
|
|||
|
|
├─ Memory: 4096 MB
|
|||
|
|
└─ Swap: 2048 MB
|
|||
|
|
|
|||
|
|
Network:
|
|||
|
|
├─ Bridge: vmbr0
|
|||
|
|
├─ IPv4: Static
|
|||
|
|
├─ IPv4/CIDR: 192.168.2.113/24
|
|||
|
|
├─ Gateway: 192.168.2.1
|
|||
|
|
└─ IPv6: SLAAC (or disable)
|
|||
|
|
|
|||
|
|
DNS:
|
|||
|
|
├─ DNS domain: apophisnetworking.net
|
|||
|
|
└─ DNS servers: 8.8.8.8 8.8.4.4
|
|||
|
|
|
|||
|
|
4. Click "Confirm" then "Finish"
|
|||
|
|
5. Enable features:
|
|||
|
|
├─ Right-click CT 113 → Options
|
|||
|
|
├─ Features → Edit
|
|||
|
|
└─ Check: "nesting" ☑
|
|||
|
|
|
|||
|
|
6. Start container
|
|||
|
|
|
|||
|
|
|
|||
|
|
Option B: CLI Method (Proxmox SSH)
|
|||
|
|
──────────────────────────────────
|
|||
|
|
# SSH to Proxmox host
|
|||
|
|
ssh root@192.168.2.100
|
|||
|
|
|
|||
|
|
# Download template (if not present)
|
|||
|
|
pveam update
|
|||
|
|
pveam download local debian-12-standard_12.7-1_amd64.tar.zst
|
|||
|
|
|
|||
|
|
# Create container
|
|||
|
|
pct create 113 local:vztmpl/debian-12-standard_12.7-1_amd64.tar.zst \
|
|||
|
|
--hostname n8n \
|
|||
|
|
--cores 2 \
|
|||
|
|
--memory 4096 \
|
|||
|
|
--swap 2048 \
|
|||
|
|
--rootfs Vault:20 \
|
|||
|
|
--net0 name=eth0,bridge=vmbr0,ip=192.168.2.113/24,gw=192.168.2.1 \
|
|||
|
|
--nameserver 8.8.8.8 \
|
|||
|
|
--features nesting=1 \
|
|||
|
|
--unprivileged 1 \
|
|||
|
|
--onboot 1
|
|||
|
|
|
|||
|
|
# Start container
|
|||
|
|
pct start 113
|
|||
|
|
|
|||
|
|
# Enter container
|
|||
|
|
pct enter 113
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 2: System Preparation (10 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Inside CT 113 (after pct enter 113)
|
|||
|
|
|
|||
|
|
# Update system
|
|||
|
|
apt update && apt upgrade -y
|
|||
|
|
|
|||
|
|
# Install prerequisites
|
|||
|
|
apt install -y \
|
|||
|
|
curl \
|
|||
|
|
wget \
|
|||
|
|
git \
|
|||
|
|
gnupg2 \
|
|||
|
|
ca-certificates \
|
|||
|
|
lsb-release \
|
|||
|
|
postgresql-16 \
|
|||
|
|
postgresql-contrib \
|
|||
|
|
nginx-light \
|
|||
|
|
certbot \
|
|||
|
|
ufw
|
|||
|
|
|
|||
|
|
# Configure timezone
|
|||
|
|
timedatectl set-timezone America/New_York # Adjust to your TZ
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 3: PostgreSQL Setup (10 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Switch to postgres user
|
|||
|
|
sudo -u postgres psql
|
|||
|
|
|
|||
|
|
-- Execute these SQL commands:
|
|||
|
|
CREATE DATABASE n8n_db;
|
|||
|
|
CREATE USER n8n_user WITH ENCRYPTED PASSWORD 'YourSecurePassword123!';
|
|||
|
|
GRANT ALL PRIVILEGES ON DATABASE n8n_db TO n8n_user;
|
|||
|
|
\q
|
|||
|
|
|
|||
|
|
# Configure PostgreSQL
|
|||
|
|
cat >> /etc/postgresql/16/main/postgresql.conf << 'EOF'
|
|||
|
|
|
|||
|
|
# N8N Optimizations
|
|||
|
|
max_connections = 20
|
|||
|
|
shared_buffers = 512MB
|
|||
|
|
effective_cache_size = 2GB
|
|||
|
|
maintenance_work_mem = 128MB
|
|||
|
|
checkpoint_completion_target = 0.9
|
|||
|
|
wal_buffers = 16MB
|
|||
|
|
default_statistics_target = 100
|
|||
|
|
random_page_cost = 1.1
|
|||
|
|
effective_io_concurrency = 200
|
|||
|
|
work_mem = 26214kB
|
|||
|
|
min_wal_size = 1GB
|
|||
|
|
max_wal_size = 4GB
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# Restart PostgreSQL
|
|||
|
|
systemctl restart postgresql
|
|||
|
|
systemctl enable postgresql
|
|||
|
|
|
|||
|
|
# Test connection
|
|||
|
|
PGPASSWORD='YourSecurePassword123!' psql -U n8n_user -d n8n_db -h localhost -c "SELECT version();"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 4: Node.js & n8n Installation (15 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Install Node.js 20.x (LTS - recommended for n8n)
|
|||
|
|
curl -fsSL https://deb.nodesource.com/setup_20.x | bash -
|
|||
|
|
apt install -y nodejs
|
|||
|
|
|
|||
|
|
# Verify Node.js installation
|
|||
|
|
node --version # Should show v20.x.x
|
|||
|
|
npm --version # Should show 10.x.x
|
|||
|
|
|
|||
|
|
# Install n8n globally
|
|||
|
|
npm install -g n8n
|
|||
|
|
|
|||
|
|
# Create n8n system user
|
|||
|
|
useradd -r -m -d /opt/n8n -s /bin/bash n8n
|
|||
|
|
|
|||
|
|
# Create directory structure
|
|||
|
|
mkdir -p /opt/n8n/{.n8n,backups,logs}
|
|||
|
|
chown -R n8n:n8n /opt/n8n
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 5: N8N Configuration (10 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Create environment configuration
|
|||
|
|
cat > /opt/n8n/.env << 'EOF'
|
|||
|
|
# Database Configuration
|
|||
|
|
DB_TYPE=postgresdb
|
|||
|
|
DB_POSTGRESDB_HOST=localhost
|
|||
|
|
DB_POSTGRESDB_PORT=5432
|
|||
|
|
DB_POSTGRESDB_DATABASE=n8n_db
|
|||
|
|
DB_POSTGRESDB_USER=n8n_user
|
|||
|
|
DB_POSTGRESDB_PASSWORD=YourSecurePassword123!
|
|||
|
|
|
|||
|
|
# n8n Configuration
|
|||
|
|
N8N_PROTOCOL=https
|
|||
|
|
N8N_HOST=n8n.yourdomain.com
|
|||
|
|
N8N_PORT=5678
|
|||
|
|
N8N_PATH=/
|
|||
|
|
WEBHOOK_URL=https://n8n.yourdomain.com/
|
|||
|
|
|
|||
|
|
# Execution
|
|||
|
|
EXECUTIONS_DATA_SAVE_ON_ERROR=all
|
|||
|
|
EXECUTIONS_DATA_SAVE_ON_SUCCESS=all
|
|||
|
|
EXECUTIONS_DATA_SAVE_MANUAL_EXECUTIONS=true
|
|||
|
|
|
|||
|
|
# Performance
|
|||
|
|
N8N_PAYLOAD_SIZE_MAX=16
|
|||
|
|
EXECUTIONS_TIMEOUT=300
|
|||
|
|
EXECUTIONS_TIMEOUT_MAX=3600
|
|||
|
|
|
|||
|
|
# Timezone
|
|||
|
|
GENERIC_TIMEZONE=America/New_York
|
|||
|
|
|
|||
|
|
# Security
|
|||
|
|
N8N_BASIC_AUTH_ACTIVE=false
|
|||
|
|
N8N_JWT_AUTH_ACTIVE=true
|
|||
|
|
N8N_ENCRYPTION_KEY=$(openssl rand -hex 32)
|
|||
|
|
|
|||
|
|
# Paths
|
|||
|
|
N8N_USER_FOLDER=/opt/n8n/.n8n
|
|||
|
|
N8N_LOG_LOCATION=/opt/n8n/logs/
|
|||
|
|
N8N_LOG_LEVEL=info
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# Secure environment file
|
|||
|
|
chown n8n:n8n /opt/n8n/.env
|
|||
|
|
chmod 600 /opt/n8n/.env
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 6: Systemd Service Creation (5 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Create systemd service
|
|||
|
|
cat > /etc/systemd/system/n8n.service << 'EOF'
|
|||
|
|
[Unit]
|
|||
|
|
Description=n8n - Workflow Automation
|
|||
|
|
Documentation=https://docs.n8n.io
|
|||
|
|
After=network.target postgresql.service
|
|||
|
|
Wants=postgresql.service
|
|||
|
|
|
|||
|
|
[Service]
|
|||
|
|
Type=simple
|
|||
|
|
User=n8n
|
|||
|
|
Group=n8n
|
|||
|
|
WorkingDirectory=/opt/n8n
|
|||
|
|
EnvironmentFile=/opt/n8n/.env
|
|||
|
|
ExecStart=/usr/bin/n8n start
|
|||
|
|
|
|||
|
|
# Restart configuration
|
|||
|
|
Restart=always
|
|||
|
|
RestartSec=10
|
|||
|
|
StartLimitInterval=60
|
|||
|
|
StartLimitBurst=5
|
|||
|
|
|
|||
|
|
# Security
|
|||
|
|
NoNewPrivileges=true
|
|||
|
|
PrivateTmp=true
|
|||
|
|
ProtectSystem=strict
|
|||
|
|
ReadWritePaths=/opt/n8n
|
|||
|
|
ProtectHome=true
|
|||
|
|
|
|||
|
|
# Logging
|
|||
|
|
StandardOutput=append:/opt/n8n/logs/n8n.log
|
|||
|
|
StandardError=append:/opt/n8n/logs/n8n-error.log
|
|||
|
|
|
|||
|
|
[Install]
|
|||
|
|
WantedBy=multi-user.target
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# Reload systemd and start n8n
|
|||
|
|
systemctl daemon-reload
|
|||
|
|
systemctl enable n8n
|
|||
|
|
systemctl start n8n
|
|||
|
|
|
|||
|
|
# Check status
|
|||
|
|
systemctl status n8n
|
|||
|
|
|
|||
|
|
# View logs
|
|||
|
|
journalctl -u n8n -f
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 7: Nginx Reverse Proxy Configuration (20 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# On nginx container (CT 102)
|
|||
|
|
# SSH or pct enter 102
|
|||
|
|
|
|||
|
|
# Install certbot if not present
|
|||
|
|
apt update && apt install -y certbot python3-certbot-nginx
|
|||
|
|
|
|||
|
|
# Create nginx configuration
|
|||
|
|
cat > /etc/nginx/sites-available/n8n.yourdomain.com << 'EOF'
|
|||
|
|
upstream n8n_backend {
|
|||
|
|
server 192.168.2.113:5678;
|
|||
|
|
keepalive 64;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
server {
|
|||
|
|
listen 80;
|
|||
|
|
listen [::]:80;
|
|||
|
|
server_name n8n.yourdomain.com;
|
|||
|
|
|
|||
|
|
# Allow certbot challenges
|
|||
|
|
location /.well-known/acme-challenge/ {
|
|||
|
|
root /var/www/html;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
return 301 https://$server_name$request_uri;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
server {
|
|||
|
|
listen 443 ssl http2;
|
|||
|
|
listen [::]:443 ssl http2;
|
|||
|
|
server_name n8n.yourdomain.com;
|
|||
|
|
|
|||
|
|
# SSL certificates (will be configured by certbot)
|
|||
|
|
ssl_certificate /etc/letsencrypt/live/n8n.yourdomain.com/fullchain.pem;
|
|||
|
|
ssl_certificate_key /etc/letsencrypt/live/n8n.yourdomain.com/privkey.pem;
|
|||
|
|
|
|||
|
|
# SSL configuration
|
|||
|
|
ssl_protocols TLSv1.2 TLSv1.3;
|
|||
|
|
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
|
|||
|
|
ssl_prefer_server_ciphers off;
|
|||
|
|
ssl_session_cache shared:SSL:10m;
|
|||
|
|
ssl_session_timeout 10m;
|
|||
|
|
ssl_stapling on;
|
|||
|
|
ssl_stapling_verify on;
|
|||
|
|
|
|||
|
|
# Security headers
|
|||
|
|
add_header Strict-Transport-Security "max-age=63072000" always;
|
|||
|
|
add_header X-Content-Type-Options "nosniff" always;
|
|||
|
|
add_header X-Frame-Options "SAMEORIGIN" always;
|
|||
|
|
add_header X-XSS-Protection "1; mode=block" always;
|
|||
|
|
add_header Referrer-Policy "no-referrer-when-downgrade" always;
|
|||
|
|
|
|||
|
|
# Logging
|
|||
|
|
access_log /var/log/nginx/n8n-access.log;
|
|||
|
|
error_log /var/log/nginx/n8n-error.log;
|
|||
|
|
|
|||
|
|
# Client settings
|
|||
|
|
client_max_body_size 50M;
|
|||
|
|
|
|||
|
|
location / {
|
|||
|
|
proxy_pass http://n8n_backend;
|
|||
|
|
proxy_http_version 1.1;
|
|||
|
|
|
|||
|
|
# WebSocket support
|
|||
|
|
proxy_set_header Upgrade $http_upgrade;
|
|||
|
|
proxy_set_header Connection "upgrade";
|
|||
|
|
|
|||
|
|
# Proxy headers
|
|||
|
|
proxy_set_header Host $host;
|
|||
|
|
proxy_set_header X-Real-IP $remote_addr;
|
|||
|
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
|||
|
|
proxy_set_header X-Forwarded-Proto $scheme;
|
|||
|
|
proxy_set_header X-Forwarded-Host $host;
|
|||
|
|
proxy_set_header X-Forwarded-Port $server_port;
|
|||
|
|
|
|||
|
|
# Timeouts
|
|||
|
|
proxy_connect_timeout 300;
|
|||
|
|
proxy_send_timeout 300;
|
|||
|
|
proxy_read_timeout 300;
|
|||
|
|
send_timeout 300;
|
|||
|
|
|
|||
|
|
# Buffering
|
|||
|
|
proxy_buffering off;
|
|||
|
|
proxy_request_buffering off;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Health check
|
|||
|
|
location /healthz {
|
|||
|
|
proxy_pass http://n8n_backend/healthz;
|
|||
|
|
access_log off;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# Enable site
|
|||
|
|
ln -sf /etc/nginx/sites-available/n8n.yourdomain.com /etc/nginx/sites-enabled/
|
|||
|
|
|
|||
|
|
# Test nginx configuration
|
|||
|
|
nginx -t
|
|||
|
|
|
|||
|
|
# Obtain SSL certificate
|
|||
|
|
certbot --nginx -d n8n.yourdomain.com --non-interactive --agree-tos -m your@email.com
|
|||
|
|
|
|||
|
|
# Reload nginx
|
|||
|
|
systemctl reload nginx
|
|||
|
|
|
|||
|
|
# Setup auto-renewal
|
|||
|
|
systemctl enable certbot.timer
|
|||
|
|
systemctl start certbot.timer
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 8: Firewall Configuration (5 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# On n8n container (CT 113)
|
|||
|
|
ufw default deny incoming
|
|||
|
|
ufw default allow outgoing
|
|||
|
|
ufw allow from 192.168.2.0/24 to any port 22 comment 'SSH from LAN'
|
|||
|
|
ufw allow from 192.168.2.101 to any port 5678 comment 'nginx proxy'
|
|||
|
|
ufw enable
|
|||
|
|
|
|||
|
|
# On Proxmox host (configure Proxmox firewall)
|
|||
|
|
# Via Web UI:
|
|||
|
|
# Datacenter → Firewall → Add rules for CT 113
|
|||
|
|
# Or via CLI:
|
|||
|
|
cat >> /etc/pve/firewall/113.fw << 'EOF'
|
|||
|
|
[OPTIONS]
|
|||
|
|
enable: 1
|
|||
|
|
|
|||
|
|
[RULES]
|
|||
|
|
IN ACCEPT -source 192.168.2.101 -dport 5678 -proto tcp -log nolog
|
|||
|
|
IN ACCEPT -source 192.168.2.0/24 -dport 22 -proto tcp -log nolog
|
|||
|
|
IN DROP -dport 5678 -proto tcp -log warning
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# Apply firewall
|
|||
|
|
pve-firewall compile
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 9: Initial n8n Setup (10 minutes)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ First-Time Access │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
|
|||
|
|
1. Open browser to: https://n8n.yourdomain.com
|
|||
|
|
|
|||
|
|
2. Create owner account:
|
|||
|
|
├─ Email: your@email.com
|
|||
|
|
├─ First Name: [Your Name]
|
|||
|
|
├─ Last Name: [Your Last Name]
|
|||
|
|
└─ Password: [Strong password]
|
|||
|
|
|
|||
|
|
3. Setup tour will guide you through:
|
|||
|
|
├─ Creating your first workflow
|
|||
|
|
├─ Adding credentials
|
|||
|
|
└─ Testing a simple automation
|
|||
|
|
|
|||
|
|
4. Configure critical settings:
|
|||
|
|
Settings → General:
|
|||
|
|
├─ Timezone: Match your location
|
|||
|
|
├─ Execution timeout: 300 seconds (default)
|
|||
|
|
└─ Save data: All executions (for debugging)
|
|||
|
|
|
|||
|
|
5. Setup credentials for integrations:
|
|||
|
|
Credentials → Add Credential:
|
|||
|
|
├─ GitLab API (for VM 101)
|
|||
|
|
├─ SMTP (for email notifications)
|
|||
|
|
├─ Webhook authentication
|
|||
|
|
└─ Any other services you use
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Phase 10: Backup Configuration (15 minutes)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# On n8n container (CT 113)
|
|||
|
|
|
|||
|
|
# Create backup script
|
|||
|
|
cat > /opt/n8n/backup.sh << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# N8N Backup Script
|
|||
|
|
|
|||
|
|
BACKUP_DIR="/opt/n8n/backups"
|
|||
|
|
DATE=$(date +%Y%m%d_%H%M%S)
|
|||
|
|
BACKUP_NAME="n8n_backup_${DATE}"
|
|||
|
|
|
|||
|
|
# Create backup directory
|
|||
|
|
mkdir -p ${BACKUP_DIR}/${BACKUP_NAME}
|
|||
|
|
|
|||
|
|
# Backup PostgreSQL database
|
|||
|
|
PGPASSWORD='YourSecurePassword123!' pg_dump \
|
|||
|
|
-U n8n_user \
|
|||
|
|
-h localhost \
|
|||
|
|
-d n8n_db \
|
|||
|
|
-F c \
|
|||
|
|
-f ${BACKUP_DIR}/${BACKUP_NAME}/n8n_db.dump
|
|||
|
|
|
|||
|
|
# Backup n8n user folder
|
|||
|
|
tar -czf ${BACKUP_DIR}/${BACKUP_NAME}/n8n_data.tar.gz \
|
|||
|
|
-C /opt/n8n/.n8n .
|
|||
|
|
|
|||
|
|
# Backup environment file
|
|||
|
|
cp /opt/n8n/.env ${BACKUP_DIR}/${BACKUP_NAME}/
|
|||
|
|
|
|||
|
|
# Create backup manifest
|
|||
|
|
cat > ${BACKUP_DIR}/${BACKUP_NAME}/MANIFEST.txt << MANIFEST
|
|||
|
|
N8N Backup
|
|||
|
|
Date: $(date)
|
|||
|
|
Database: n8n_db.dump
|
|||
|
|
User Data: n8n_data.tar.gz
|
|||
|
|
Environment: .env
|
|||
|
|
MANIFEST
|
|||
|
|
|
|||
|
|
# Compress backup
|
|||
|
|
cd ${BACKUP_DIR}
|
|||
|
|
tar -czf ${BACKUP_NAME}.tar.gz ${BACKUP_NAME}
|
|||
|
|
rm -rf ${BACKUP_NAME}
|
|||
|
|
|
|||
|
|
# Keep last 7 daily backups
|
|||
|
|
find ${BACKUP_DIR} -name "n8n_backup_*.tar.gz" -mtime +7 -delete
|
|||
|
|
|
|||
|
|
echo "Backup completed: ${BACKUP_DIR}/${BACKUP_NAME}.tar.gz"
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
chmod +x /opt/n8n/backup.sh
|
|||
|
|
|
|||
|
|
# Create daily backup cron job
|
|||
|
|
cat > /etc/cron.d/n8n-backup << 'EOF'
|
|||
|
|
# Daily n8n backup at 2 AM
|
|||
|
|
0 2 * * * n8n /opt/n8n/backup.sh >> /opt/n8n/logs/backup.log 2>&1
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
# Test backup
|
|||
|
|
sudo -u n8n /opt/n8n/backup.sh
|
|||
|
|
|
|||
|
|
# Configure Proxmox container backup
|
|||
|
|
# On Proxmox host:
|
|||
|
|
# Datacenter → Backup → Add
|
|||
|
|
# Schedule: Weekly, Sunday 1:00 AM
|
|||
|
|
# Storage: PBS-Backups
|
|||
|
|
# Mode: Snapshot
|
|||
|
|
# Compression: ZSTD
|
|||
|
|
# Include: CT 113
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## VIII. Post-Installation Checklist
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Verification Checklist │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ □ Container CT 113 created and running │
|
|||
|
|
│ □ Static IP 192.168.2.113 configured │
|
|||
|
|
│ □ PostgreSQL installed and accessible │
|
|||
|
|
│ □ n8n service running (systemctl status n8n) │
|
|||
|
|
│ □ n8n accessible at https://n8n.yourdomain.com │
|
|||
|
|
│ □ SSL certificate valid and auto-renewing │
|
|||
|
|
│ □ Nginx reverse proxy forwarding correctly │
|
|||
|
|
│ □ Firewall rules in place │
|
|||
|
|
│ □ Owner account created in n8n │
|
|||
|
|
│ □ Daily database backups configured │
|
|||
|
|
│ □ Proxmox container backups scheduled │
|
|||
|
|
│ □ Can create and execute test workflow │
|
|||
|
|
│ □ Webhook URL working (test with curl) │
|
|||
|
|
│ □ Email notifications configured (optional) │
|
|||
|
|
│ □ GitLab integration tested (optional) │
|
|||
|
|
│ │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## IX. Testing & Validation
|
|||
|
|
|
|||
|
|
### Test 1: Basic Connectivity
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# From any machine on 192.168.2.0/24 network
|
|||
|
|
curl -I http://192.168.2.113:5678
|
|||
|
|
# Expected: HTTP/1.1 200 OK
|
|||
|
|
|
|||
|
|
# HTTPS through nginx
|
|||
|
|
curl -I https://n8n.yourdomain.com
|
|||
|
|
# Expected: HTTP/2 200 (or 301 → 200)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 2: Create Sample Workflow
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
1. Login to n8n web interface
|
|||
|
|
2. Click "+ Add workflow"
|
|||
|
|
3. Add nodes:
|
|||
|
|
├─ Schedule Trigger (every 1 hour)
|
|||
|
|
├─ HTTP Request (GET https://api.github.com/zen)
|
|||
|
|
└─ Send Email (to your address)
|
|||
|
|
4. Configure email credentials
|
|||
|
|
5. Execute workflow manually
|
|||
|
|
6. Check email received
|
|||
|
|
7. Enable workflow
|
|||
|
|
8. Monitor executions tab
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 3: GitLab Integration
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
1. In GitLab (VM 101):
|
|||
|
|
└─ Settings → Access Tokens
|
|||
|
|
Create token with 'api' scope
|
|||
|
|
|
|||
|
|
2. In n8n:
|
|||
|
|
└─ Credentials → Add → GitLab API
|
|||
|
|
Enter: GitLab URL and Access Token
|
|||
|
|
|
|||
|
|
3. Create workflow:
|
|||
|
|
├─ Webhook Trigger (on /webhook/gitlab)
|
|||
|
|
├─ GitLab node (Get issue details)
|
|||
|
|
└─ Log to file
|
|||
|
|
|
|||
|
|
4. Configure GitLab webhook:
|
|||
|
|
└─ Project → Settings → Webhooks
|
|||
|
|
URL: https://n8n.yourdomain.com/webhook/gitlab
|
|||
|
|
Events: Issues
|
|||
|
|
|
|||
|
|
5. Test: Create issue in GitLab
|
|||
|
|
6. Verify: Check n8n execution log
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 4: Database Performance
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# On CT 113
|
|||
|
|
sudo -u postgres psql -d n8n_db -c "
|
|||
|
|
SELECT
|
|||
|
|
schemaname,
|
|||
|
|
tablename,
|
|||
|
|
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) AS size
|
|||
|
|
FROM pg_tables
|
|||
|
|
WHERE schemaname = 'public'
|
|||
|
|
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC
|
|||
|
|
LIMIT 10;
|
|||
|
|
"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Test 5: Backup & Restore
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Test backup
|
|||
|
|
sudo -u n8n /opt/n8n/backup.sh
|
|||
|
|
|
|||
|
|
# Simulate disaster: Stop n8n, drop database
|
|||
|
|
systemctl stop n8n
|
|||
|
|
sudo -u postgres psql -c "DROP DATABASE n8n_db;"
|
|||
|
|
|
|||
|
|
# Restore from backup
|
|||
|
|
sudo -u postgres psql -c "CREATE DATABASE n8n_db OWNER n8n_user;"
|
|||
|
|
LATEST_BACKUP=$(ls -t /opt/n8n/backups/*.tar.gz | head -1)
|
|||
|
|
tar -xzf $LATEST_BACKUP -C /tmp/
|
|||
|
|
PGPASSWORD='YourSecurePassword123!' pg_restore \
|
|||
|
|
-U n8n_user \
|
|||
|
|
-d n8n_db \
|
|||
|
|
/tmp/*/n8n_db.dump
|
|||
|
|
|
|||
|
|
# Restart n8n
|
|||
|
|
systemctl start n8n
|
|||
|
|
# Verify workflows still exist
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## X. Monitoring & Maintenance
|
|||
|
|
|
|||
|
|
### Health Monitoring
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Create monitoring script
|
|||
|
|
cat > /usr/local/bin/n8n-health-check << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# N8N Health Check Script
|
|||
|
|
|
|||
|
|
# Check if n8n service is running
|
|||
|
|
if ! systemctl is-active --quiet n8n; then
|
|||
|
|
echo "CRITICAL: n8n service is not running"
|
|||
|
|
exit 2
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check if n8n responds to HTTP
|
|||
|
|
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:5678/healthz)
|
|||
|
|
if [ "$HTTP_CODE" != "200" ]; then
|
|||
|
|
echo "WARNING: n8n healthcheck returned $HTTP_CODE"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check PostgreSQL
|
|||
|
|
if ! PGPASSWORD='YourSecurePassword123!' psql -U n8n_user -d n8n_db -h localhost -c "SELECT 1;" > /dev/null 2>&1; then
|
|||
|
|
echo "CRITICAL: PostgreSQL connection failed"
|
|||
|
|
exit 2
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
# Check disk space
|
|||
|
|
DISK_USAGE=$(df -h /opt/n8n | awk 'NR==2 {print $5}' | sed 's/%//')
|
|||
|
|
if [ "$DISK_USAGE" -gt 80 ]; then
|
|||
|
|
echo "WARNING: Disk usage at ${DISK_USAGE}%"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
|
|||
|
|
echo "OK: All checks passed"
|
|||
|
|
exit 0
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
chmod +x /usr/local/bin/n8n-health-check
|
|||
|
|
|
|||
|
|
# Schedule health check every 5 minutes
|
|||
|
|
cat > /etc/cron.d/n8n-health << 'EOF'
|
|||
|
|
*/5 * * * * root /usr/local/bin/n8n-health-check >> /var/log/n8n-health.log 2>&1
|
|||
|
|
EOF
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Log Rotation
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Configure logrotate
|
|||
|
|
cat > /etc/logrotate.d/n8n << 'EOF'
|
|||
|
|
/opt/n8n/logs/*.log {
|
|||
|
|
daily
|
|||
|
|
rotate 14
|
|||
|
|
compress
|
|||
|
|
delaycompress
|
|||
|
|
missingok
|
|||
|
|
notifempty
|
|||
|
|
create 0640 n8n n8n
|
|||
|
|
sharedscripts
|
|||
|
|
postrotate
|
|||
|
|
systemctl reload n8n > /dev/null 2>&1 || true
|
|||
|
|
endscript
|
|||
|
|
}
|
|||
|
|
EOF
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Update Procedure
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Create update script
|
|||
|
|
cat > /opt/n8n/update-n8n.sh << 'EOF'
|
|||
|
|
#!/bin/bash
|
|||
|
|
# N8N Update Script
|
|||
|
|
|
|||
|
|
set -e
|
|||
|
|
|
|||
|
|
echo "Starting n8n update process..."
|
|||
|
|
|
|||
|
|
# Backup before update
|
|||
|
|
echo "Creating backup..."
|
|||
|
|
/opt/n8n/backup.sh
|
|||
|
|
|
|||
|
|
# Stop n8n service
|
|||
|
|
echo "Stopping n8n..."
|
|||
|
|
systemctl stop n8n
|
|||
|
|
|
|||
|
|
# Update n8n
|
|||
|
|
echo "Updating n8n..."
|
|||
|
|
npm update -g n8n
|
|||
|
|
|
|||
|
|
# Clear npm cache
|
|||
|
|
npm cache clean --force
|
|||
|
|
|
|||
|
|
# Start n8n service
|
|||
|
|
echo "Starting n8n..."
|
|||
|
|
systemctl start n8n
|
|||
|
|
|
|||
|
|
# Wait for service to be ready
|
|||
|
|
sleep 10
|
|||
|
|
|
|||
|
|
# Check health
|
|||
|
|
if /usr/local/bin/n8n-health-check; then
|
|||
|
|
echo "Update completed successfully!"
|
|||
|
|
n8n --version
|
|||
|
|
else
|
|||
|
|
echo "ERROR: Health check failed after update!"
|
|||
|
|
echo "Restoring from backup may be necessary"
|
|||
|
|
exit 1
|
|||
|
|
fi
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
chmod +x /opt/n8n/update-n8n.sh
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Maintenance Schedule
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Maintenance Calendar │
|
|||
|
|
├────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ Daily: │
|
|||
|
|
│ └─ 02:00 AM - Database backup │
|
|||
|
|
│ │
|
|||
|
|
│ Weekly: │
|
|||
|
|
│ └─ Sunday 01:00 AM - Proxmox container backup │
|
|||
|
|
│ │
|
|||
|
|
│ Monthly: │
|
|||
|
|
│ ├─ Review execution logs │
|
|||
|
|
│ ├─ Check disk space usage │
|
|||
|
|
│ ├─ Update n8n to latest version │
|
|||
|
|
│ ├─ Review and optimize workflows │
|
|||
|
|
│ └─ Test backup restoration │
|
|||
|
|
│ │
|
|||
|
|
│ Quarterly: │
|
|||
|
|
│ ├─ Review security headers │
|
|||
|
|
│ ├─ Update SSL certificates (automatic via Let's Encrypt) │
|
|||
|
|
│ ├─ Audit user access │
|
|||
|
|
│ └─ PostgreSQL VACUUM ANALYZE │
|
|||
|
|
│ │
|
|||
|
|
└────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XI. Troubleshooting Guide
|
|||
|
|
|
|||
|
|
### Common Issues & Solutions
|
|||
|
|
|
|||
|
|
#### Issue 1: n8n Won't Start
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Check service status
|
|||
|
|
systemctl status n8n
|
|||
|
|
|
|||
|
|
# Check logs
|
|||
|
|
journalctl -u n8n -n 50 --no-pager
|
|||
|
|
|
|||
|
|
# Common causes:
|
|||
|
|
# 1. PostgreSQL not running
|
|||
|
|
systemctl status postgresql
|
|||
|
|
systemctl start postgresql
|
|||
|
|
|
|||
|
|
# 2. Database connection error
|
|||
|
|
PGPASSWORD='YourSecurePassword123!' psql -U n8n_user -d n8n_db -h localhost
|
|||
|
|
|
|||
|
|
# 3. Port already in use
|
|||
|
|
ss -tulpn | grep 5678
|
|||
|
|
|
|||
|
|
# 4. Permission issues
|
|||
|
|
chown -R n8n:n8n /opt/n8n
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Issue 2: Can't Access via HTTPS
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Check nginx status
|
|||
|
|
systemctl status nginx
|
|||
|
|
|
|||
|
|
# Test nginx configuration
|
|||
|
|
nginx -t
|
|||
|
|
|
|||
|
|
# Check SSL certificate
|
|||
|
|
certbot certificates
|
|||
|
|
|
|||
|
|
# Renew if needed
|
|||
|
|
certbot renew --dry-run
|
|||
|
|
|
|||
|
|
# Check firewall
|
|||
|
|
ufw status
|
|||
|
|
# Ensure 443 is open on nginx container
|
|||
|
|
|
|||
|
|
# Test backend connectivity
|
|||
|
|
curl http://192.168.2.113:5678
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Issue 3: Workflows Timeout
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Increase timeout in /opt/n8n/.env
|
|||
|
|
EXECUTIONS_TIMEOUT=600
|
|||
|
|
EXECUTIONS_TIMEOUT_MAX=7200
|
|||
|
|
|
|||
|
|
# Restart n8n
|
|||
|
|
systemctl restart n8n
|
|||
|
|
|
|||
|
|
# Also check nginx timeout in proxy config
|
|||
|
|
# proxy_read_timeout 600;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Issue 4: Database Connection Pool Exhausted
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Edit /etc/postgresql/16/main/postgresql.conf
|
|||
|
|
max_connections = 50
|
|||
|
|
|
|||
|
|
# Restart PostgreSQL
|
|||
|
|
systemctl restart postgresql
|
|||
|
|
|
|||
|
|
# Monitor connections
|
|||
|
|
sudo -u postgres psql -c "
|
|||
|
|
SELECT count(*)
|
|||
|
|
FROM pg_stat_activity
|
|||
|
|
WHERE datname = 'n8n_db';
|
|||
|
|
"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### Issue 5: High Memory Usage
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Check memory usage
|
|||
|
|
free -h
|
|||
|
|
top -o %MEM
|
|||
|
|
|
|||
|
|
# Reduce n8n memory if needed in /opt/n8n/.env
|
|||
|
|
N8N_PAYLOAD_SIZE_MAX=8
|
|||
|
|
|
|||
|
|
# Restart n8n
|
|||
|
|
systemctl restart n8n
|
|||
|
|
|
|||
|
|
# Consider increasing container RAM
|
|||
|
|
# On Proxmox: pct set 113 -memory 6144
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XII. Security Hardening
|
|||
|
|
|
|||
|
|
### Security Checklist
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Security Hardening Checklist │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ □ Use strong, unique passwords (20+ characters) │
|
|||
|
|
│ □ Enable HTTPS only (HTTP → HTTPS redirect) │
|
|||
|
|
│ □ Configure HSTS header (max-age=31536000) │
|
|||
|
|
│ □ Implement rate limiting in nginx │
|
|||
|
|
│ □ Use unprivileged LXC container │
|
|||
|
|
│ □ Firewall blocks direct access to port 5678 │
|
|||
|
|
│ □ PostgreSQL listens on localhost only │
|
|||
|
|
│ □ Regular security updates (apt update && upgrade) │
|
|||
|
|
│ □ Backup encryption for sensitive workflows │
|
|||
|
|
│ □ Multi-factor authentication (n8n Cloud feature) │
|
|||
|
|
│ □ IP whitelist for admin access (optional) │
|
|||
|
|
│ □ Credential encryption enabled (N8N_ENCRYPTION_KEY) │
|
|||
|
|
│ □ Audit logs enabled and monitored │
|
|||
|
|
│ □ Fail2ban for SSH brute-force protection │
|
|||
|
|
│ │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Additional Security Measures
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Install fail2ban (on CT 113)
|
|||
|
|
apt install -y fail2ban
|
|||
|
|
|
|||
|
|
# Configure fail2ban for SSH
|
|||
|
|
cat > /etc/fail2ban/jail.local << 'EOF'
|
|||
|
|
[sshd]
|
|||
|
|
enabled = true
|
|||
|
|
port = ssh
|
|||
|
|
logpath = /var/log/auth.log
|
|||
|
|
maxretry = 3
|
|||
|
|
bantime = 3600
|
|||
|
|
EOF
|
|||
|
|
|
|||
|
|
systemctl enable fail2ban
|
|||
|
|
systemctl start fail2ban
|
|||
|
|
|
|||
|
|
# Implement nginx rate limiting
|
|||
|
|
# Edit /etc/nginx/sites-available/n8n.yourdomain.com
|
|||
|
|
# Add before server blocks:
|
|||
|
|
limit_req_zone $binary_remote_addr zone=n8n_limit:10m rate=10r/s;
|
|||
|
|
|
|||
|
|
# Inside server block:
|
|||
|
|
limit_req zone=n8n_limit burst=20 nodelay;
|
|||
|
|
|
|||
|
|
# Reload nginx
|
|||
|
|
nginx -t && systemctl reload nginx
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XIII. Advanced Configurations
|
|||
|
|
|
|||
|
|
### High Availability Setup (Future Expansion)
|
|||
|
|
|
|||
|
|
If you need HA in the future:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ High Availability Architecture │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ Load Balancer (HAProxy/Keepalived) │
|
|||
|
|
│ │ │
|
|||
|
|
│ ┌───────────┴───────────┐ │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ ┌────▼─────┐ ┌─────▼────┐ │
|
|||
|
|
│ │ n8n-01 │ │ n8n-02 │ │
|
|||
|
|
│ │ CT: 113 │ │ CT: 114 │ │
|
|||
|
|
│ └────┬─────┘ └─────┬────┘ │
|
|||
|
|
│ │ │ │
|
|||
|
|
│ └───────────┬───────────┘ │
|
|||
|
|
│ │ │
|
|||
|
|
│ ┌────────▼────────┐ │
|
|||
|
|
│ │ PostgreSQL HA │ │
|
|||
|
|
│ │ (Replication) │ │
|
|||
|
|
│ └─────────────────┘ │
|
|||
|
|
│ │
|
|||
|
|
│ Requirements: │
|
|||
|
|
│ - Shared PostgreSQL with streaming replication │
|
|||
|
|
│ - Queue mode enabled (requires Redis) │
|
|||
|
|
│ - Session persistence at load balancer │
|
|||
|
|
│ │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Custom Node Development
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Setup development environment
|
|||
|
|
# On CT 113 or separate dev container
|
|||
|
|
|
|||
|
|
# Install n8n development tools
|
|||
|
|
npm install -g n8n-node-dev
|
|||
|
|
|
|||
|
|
# Create custom node
|
|||
|
|
n8n-node-dev new
|
|||
|
|
|
|||
|
|
# Follow prompts to create node
|
|||
|
|
# Test node locally
|
|||
|
|
# Package and install to production n8n
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XIV. Integration Examples
|
|||
|
|
|
|||
|
|
### Example 1: GitLab CI/CD Automation
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Workflow: "GitLab Deploy Notification"
|
|||
|
|
|
|||
|
|
Trigger: GitLab Webhook (on pipeline completion)
|
|||
|
|
│
|
|||
|
|
├─ Filter: status == "success"
|
|||
|
|
│
|
|||
|
|
├─ Get Deployment Details (GitLab API)
|
|||
|
|
│
|
|||
|
|
├─ Update Netbox (HTTP Request to VM 103)
|
|||
|
|
│
|
|||
|
|
├─ Send Slack Notification
|
|||
|
|
│
|
|||
|
|
└─ Create Jira Ticket (if production deploy)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Example 2: Infrastructure Monitoring
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Workflow: "Service Health Monitor"
|
|||
|
|
|
|||
|
|
Trigger: Schedule (every 5 minutes)
|
|||
|
|
│
|
|||
|
|
├─ Check GitLab Health (HTTP Request)
|
|||
|
|
│
|
|||
|
|
├─ Check nginx Status (SSH to CT 102)
|
|||
|
|
│
|
|||
|
|
├─ Check Docker Hub (HTTP Request to VM 100)
|
|||
|
|
│
|
|||
|
|
├─ Query Netbox for Status (HTTP Request)
|
|||
|
|
│
|
|||
|
|
├─ Aggregate Results
|
|||
|
|
│
|
|||
|
|
└─ If any failed:
|
|||
|
|
├─ Send Email Alert
|
|||
|
|
├─ Post to Slack
|
|||
|
|
└─ Create PagerDuty Incident
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Example 3: Automated Backups
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Workflow: "Backup Verification"
|
|||
|
|
|
|||
|
|
Trigger: Schedule (daily at 3 AM)
|
|||
|
|
│
|
|||
|
|
├─ SSH to each VM/CT
|
|||
|
|
│
|
|||
|
|
├─ Run backup script
|
|||
|
|
│
|
|||
|
|
├─ Verify backup file exists
|
|||
|
|
│
|
|||
|
|
├─ Check backup size (ensure not 0 bytes)
|
|||
|
|
│
|
|||
|
|
├─ Update Google Sheets log
|
|||
|
|
│
|
|||
|
|
└─ Send summary email
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XV. Performance Optimization
|
|||
|
|
|
|||
|
|
### Tuning PostgreSQL for n8n
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- Run these on PostgreSQL for better performance
|
|||
|
|
|
|||
|
|
-- Increase work memory for complex queries
|
|||
|
|
ALTER SYSTEM SET work_mem = '50MB';
|
|||
|
|
|
|||
|
|
-- Optimize for SSD (ZFS)
|
|||
|
|
ALTER SYSTEM SET random_page_cost = 1.1;
|
|||
|
|
|
|||
|
|
-- Enable parallel query execution
|
|||
|
|
ALTER SYSTEM SET max_parallel_workers_per_gather = 2;
|
|||
|
|
ALTER SYSTEM SET max_parallel_workers = 4;
|
|||
|
|
|
|||
|
|
-- Reload configuration
|
|||
|
|
SELECT pg_reload_conf();
|
|||
|
|
|
|||
|
|
-- Create indexes for common queries
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_execution_data_workflow_id
|
|||
|
|
ON public.execution_entity (workflow_id);
|
|||
|
|
|
|||
|
|
CREATE INDEX IF NOT EXISTS idx_execution_data_finished
|
|||
|
|
ON public.execution_entity (finished);
|
|||
|
|
|
|||
|
|
-- Vacuum and analyze
|
|||
|
|
VACUUM ANALYZE;
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### n8n Performance Settings
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Edit /opt/n8n/.env
|
|||
|
|
|
|||
|
|
# Increase concurrent executions
|
|||
|
|
EXECUTIONS_PROCESS=main
|
|||
|
|
EXECUTIONS_MODE=regular
|
|||
|
|
|
|||
|
|
# Queue mode for high throughput (requires Redis)
|
|||
|
|
# EXECUTIONS_MODE=queue
|
|||
|
|
# QUEUE_BULL_REDIS_HOST=localhost
|
|||
|
|
# QUEUE_BULL_REDIS_PORT=6379
|
|||
|
|
|
|||
|
|
# Increase payload limits
|
|||
|
|
N8N_PAYLOAD_SIZE_MAX=32
|
|||
|
|
|
|||
|
|
# Cache settings
|
|||
|
|
CACHE_TTL=3600
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XVI. Cost Analysis & Resource Planning
|
|||
|
|
|
|||
|
|
### Resource Usage Projection
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ Resource Usage Forecast │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ Current (0-10 workflows): │
|
|||
|
|
│ ├─ CPU: 5-10% avg (0.1-0.2 vCPU) │
|
|||
|
|
│ ├─ RAM: 600-800 MB │
|
|||
|
|
│ └─ Disk: 5 GB │
|
|||
|
|
│ │
|
|||
|
|
│ Growth (10-50 workflows): │
|
|||
|
|
│ ├─ CPU: 15-25% avg (0.3-0.5 vCPU) │
|
|||
|
|
│ ├─ RAM: 1.5-2 GB │
|
|||
|
|
│ └─ Disk: 15 GB │
|
|||
|
|
│ │
|
|||
|
|
│ Heavy Use (50-100 workflows): │
|
|||
|
|
│ ├─ CPU: 30-50% avg (0.6-1.0 vCPU) │
|
|||
|
|
│ ├─ RAM: 3-4 GB │
|
|||
|
|
│ └─ Disk: 30 GB │
|
|||
|
|
│ │
|
|||
|
|
│ Scaling Recommendations: │
|
|||
|
|
│ - At 50 workflows: Increase RAM to 6 GB │
|
|||
|
|
│ - At 100 workflows: Increase vCPU to 4 cores │
|
|||
|
|
│ - At 200 workflows: Consider queue mode + Redis │
|
|||
|
|
│ - At 500+ workflows: Migrate to dedicated VM or HA setup │
|
|||
|
|
│ │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XVII. Documentation & Knowledge Base
|
|||
|
|
|
|||
|
|
### Essential Resources
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
┌─────────────────────────────────────────────────────────────────┐
|
|||
|
|
│ N8N Documentation Links │
|
|||
|
|
├─────────────────────────────────────────────────────────────────┤
|
|||
|
|
│ │
|
|||
|
|
│ Official Documentation: │
|
|||
|
|
│ └─ https://docs.n8n.io/ │
|
|||
|
|
│ │
|
|||
|
|
│ Community Forum: │
|
|||
|
|
│ └─ https://community.n8n.io/ │
|
|||
|
|
│ │
|
|||
|
|
│ GitHub Repository: │
|
|||
|
|
│ └─ https://github.com/n8n-io/n8n │
|
|||
|
|
│ │
|
|||
|
|
│ Workflow Templates: │
|
|||
|
|
│ └─ https://n8n.io/workflows │
|
|||
|
|
│ │
|
|||
|
|
│ YouTube Channel: │
|
|||
|
|
│ └─ https://www.youtube.com/@n8n-io │
|
|||
|
|
│ │
|
|||
|
|
│ Integration Nodes: │
|
|||
|
|
│ └─ https://docs.n8n.io/integrations/ │
|
|||
|
|
│ │
|
|||
|
|
└─────────────────────────────────────────────────────────────────┘
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Internal Documentation
|
|||
|
|
|
|||
|
|
Create these documents in your homelab repo:
|
|||
|
|
|
|||
|
|
1. **/home/jramos/homelab/docs/n8n-workflows.md**
|
|||
|
|
- Document all active workflows
|
|||
|
|
- Purpose, trigger, dependencies
|
|||
|
|
- Maintenance notes
|
|||
|
|
|
|||
|
|
2. **/home/jramos/homelab/docs/n8n-credentials.md** (encrypted)
|
|||
|
|
- Credential inventory
|
|||
|
|
- Service API endpoints
|
|||
|
|
- Renewal/rotation schedule
|
|||
|
|
|
|||
|
|
3. **/home/jramos/homelab/docs/n8n-runbook.md**
|
|||
|
|
- Emergency procedures
|
|||
|
|
- Escalation contacts
|
|||
|
|
- Restore procedures
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XVIII. Migration Path from SQLite (If Needed)
|
|||
|
|
|
|||
|
|
If you start with SQLite and later migrate to PostgreSQL:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Export from SQLite
|
|||
|
|
n8n export:workflow --all --output=/tmp/workflows.json
|
|||
|
|
n8n export:credentials --all --output=/tmp/credentials.json
|
|||
|
|
|
|||
|
|
# Stop n8n
|
|||
|
|
systemctl stop n8n
|
|||
|
|
|
|||
|
|
# Update .env to use PostgreSQL
|
|||
|
|
# (already configured in Phase 5)
|
|||
|
|
|
|||
|
|
# Import to PostgreSQL
|
|||
|
|
n8n import:workflow --input=/tmp/workflows.json
|
|||
|
|
n8n import:credentials --input=/tmp/credentials.json
|
|||
|
|
|
|||
|
|
# Start n8n
|
|||
|
|
systemctl start n8n
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XIX. Final Architecture Diagram
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
╔══════════════════════════════════════════════════════════════════╗
|
|||
|
|
║ ║
|
|||
|
|
║ N8N HOMELAB INFRASTRUCTURE - FINAL STATE ║
|
|||
|
|
║ ║
|
|||
|
|
╠══════════════════════════════════════════════════════════════════╣
|
|||
|
|
║ ║
|
|||
|
|
║ Internet ║
|
|||
|
|
║ │ ║
|
|||
|
|
║ ▼ ║
|
|||
|
|
║ ┌──────────────────┐ ║
|
|||
|
|
║ │ Router/Firewall │ ║
|
|||
|
|
║ │ 192.168.2.1 │ ║
|
|||
|
|
║ │ Port 443 → 101 │ ║
|
|||
|
|
║ └────────┬─────────┘ ║
|
|||
|
|
║ │ ║
|
|||
|
|
║ ┌───────────────────────┼─────────────────────────┐ ║
|
|||
|
|
║ │ Proxmox Node: serviceslab │ ║
|
|||
|
|
║ │ 192.168.2.100/24 (vmbr0) │ ║
|
|||
|
|
║ │ │ │ ║
|
|||
|
|
║ │ ┌───────────────────┼───────────────────────┐ │ ║
|
|||
|
|
║ │ │ │ │ │ ║
|
|||
|
|
║ │ │ ┌────────────────▼──────┐ ┌──────────▼┐ │ ║
|
|||
|
|
║ │ │ │ nginx (CT 102) │ │ n8n │ │ ║
|
|||
|
|
║ │ │ │ 192.168.2.101 │ │ (CT 113) │ │ ║
|
|||
|
|
║ │ │ ├───────────────────────┤ │ .113 │ │ ║
|
|||
|
|
║ │ │ │ - SSL Termination │ │ │ │ ║
|
|||
|
|
║ │ │ │ - Reverse Proxy │───┤ n8n App │ │ ║
|
|||
|
|
║ │ │ │ - Let's Encrypt │ │ :5678 │ │ ║
|
|||
|
|
║ │ │ │ - Rate Limiting │ │ │ │ ║
|
|||
|
|
║ │ │ └───────────────────────┘ │ Postgres │ │ ║
|
|||
|
|
║ │ │ │ :5432 │ │ ║
|
|||
|
|
║ │ │ └─────┬─────┘ │ ║
|
|||
|
|
║ │ │ │ │ ║
|
|||
|
|
║ │ │ ┌─────────────────────────────────┼─────┐ │ ║
|
|||
|
|
║ │ │ │ Integration Services │ │ │ ║
|
|||
|
|
║ │ │ │ │ │ │ ║
|
|||
|
|
║ │ │ │ ┌──────────┐ ┌──────────┐ │ │ │ ║
|
|||
|
|
║ │ │ │ │ GitLab │ │ Docker │ │ │ │ ║
|
|||
|
|
║ │ │ │ │ VM 101 │ │ Hub │ │ │ │ ║
|
|||
|
|
║ │ │ │ │ 17GB RAM │ │ VM 100 │ │ │ │ ║
|
|||
|
|
║ │ │ │ └────┬─────┘ └────┬─────┘ │ │ │ ║
|
|||
|
|
║ │ │ │ │ │ │ │ │ ║
|
|||
|
|
║ │ │ │ ┌────▼─────┐ ┌────▼─────┐ │ │ │ ║
|
|||
|
|
║ │ │ │ │ Netbox │ │ Ansible │ │ │ │ ║
|
|||
|
|
║ │ │ │ │ CT 103 │ │ VM 106 │◄── ─┼─────┘ │ ║
|
|||
|
|
║ │ │ │ │ IPAM │ │ Control │ │ │ ║
|
|||
|
|
║ │ │ │ └──────────┘ └──────────┘ │ │ ║
|
|||
|
|
║ │ │ └───────────────────────────────────────┘ │ ║
|
|||
|
|
║ │ │ │ ║
|
|||
|
|
║ │ │ ┌──────────────────────────────────────┐ │ ║
|
|||
|
|
║ │ │ │ Storage: Vault (ZFS) │ │ ║
|
|||
|
|
║ │ │ │ 4.36 TB Total / 124 GB Used │ │ ║
|
|||
|
|
║ │ │ └──────────────────────────────────────┘ │ ║
|
|||
|
|
║ │ │ │ ║
|
|||
|
|
║ │ └─────────────────────────────────────────────┘ ║
|
|||
|
|
║ │ ║
|
|||
|
|
║ │ Backups: PBS (192.168.2.151) ║
|
|||
|
|
║ └─────────────────────────────────────────────────────────── ║
|
|||
|
|
║ ║
|
|||
|
|
╚══════════════════════════════════════════════════════════════════╝
|
|||
|
|
|
|||
|
|
Workflow Examples:
|
|||
|
|
─────────────────
|
|||
|
|
• GitLab Pipeline → n8n → Slack Notification
|
|||
|
|
• Schedule → n8n → Ansible Playbook → Email Report
|
|||
|
|
• Webhook → n8n → Update Netbox → GitLab Issue
|
|||
|
|
• Cron → n8n → Backup Verification → Dashboard Update
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## XX. Conclusion & Next Steps
|
|||
|
|
|
|||
|
|
### Summary
|
|||
|
|
|
|||
|
|
You now have a comprehensive blueprint for deploying n8n in your Proxmox homelab. The LXC container approach provides:
|
|||
|
|
|
|||
|
|
- **Efficiency**: Minimal resource overhead (~600 MB RAM, < 5 GB disk)
|
|||
|
|
- **Performance**: Near-native execution speed
|
|||
|
|
- **Reliability**: PostgreSQL backend with automated backups
|
|||
|
|
- **Security**: Reverse proxy with SSL, firewall rules, unprivileged container
|
|||
|
|
- **Scalability**: Easy to upgrade resources as workflow count grows
|
|||
|
|
- **Integration**: Seamless connection to your existing infrastructure
|
|||
|
|
|
|||
|
|
### Immediate Next Steps
|
|||
|
|
|
|||
|
|
1. **Create CT 113** using Phase 1 instructions
|
|||
|
|
2. **Install PostgreSQL** (Phase 3)
|
|||
|
|
3. **Deploy n8n** (Phase 4-6)
|
|||
|
|
4. **Configure nginx proxy** (Phase 7)
|
|||
|
|
5. **Test connectivity** (Phase 9)
|
|||
|
|
6. **Setup backups** (Phase 10)
|
|||
|
|
|
|||
|
|
### Week 1 Goals
|
|||
|
|
|
|||
|
|
- [ ] Complete installation (Phases 1-7)
|
|||
|
|
- [ ] Create first workflow (scheduled health check)
|
|||
|
|
- [ ] Integrate with GitLab
|
|||
|
|
- [ ] Configure backups
|
|||
|
|
- [ ] Test disaster recovery
|
|||
|
|
|
|||
|
|
### Month 1 Goals
|
|||
|
|
|
|||
|
|
- [ ] Deploy 5-10 production workflows
|
|||
|
|
- [ ] Setup monitoring and alerting
|
|||
|
|
- [ ] Document all workflows
|
|||
|
|
- [ ] Optimize PostgreSQL performance
|
|||
|
|
- [ ] Implement advanced security measures
|
|||
|
|
|
|||
|
|
### Future Considerations
|
|||
|
|
|
|||
|
|
**3 Months:**
|
|||
|
|
- Evaluate workflow performance
|
|||
|
|
- Consider queue mode if > 50 workflows
|
|||
|
|
- Implement custom nodes if needed
|
|||
|
|
|
|||
|
|
**6 Months:**
|
|||
|
|
- Review HA requirements
|
|||
|
|
- Integrate with additional services
|
|||
|
|
- Expand automation scope
|
|||
|
|
|
|||
|
|
**1 Year:**
|
|||
|
|
- Consider n8n Cloud migration (if needed)
|
|||
|
|
- Evaluate container→VM migration
|
|||
|
|
- Implement disaster recovery testing
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Appendix A: Quick Reference Commands
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Container Management
|
|||
|
|
pct list # List all containers
|
|||
|
|
pct start 113 # Start n8n container
|
|||
|
|
pct stop 113 # Stop n8n container
|
|||
|
|
pct enter 113 # Enter container shell
|
|||
|
|
|
|||
|
|
# Service Management
|
|||
|
|
systemctl status n8n # Check n8n status
|
|||
|
|
systemctl restart n8n # Restart n8n
|
|||
|
|
journalctl -u n8n -f # Follow n8n logs
|
|||
|
|
|
|||
|
|
# Database
|
|||
|
|
sudo -u postgres psql -d n8n_db # Connect to database
|
|||
|
|
/opt/n8n/backup.sh # Run backup
|
|||
|
|
|
|||
|
|
# Health Checks
|
|||
|
|
/usr/local/bin/n8n-health-check # Run health check
|
|||
|
|
curl http://localhost:5678/healthz # Test n8n API
|
|||
|
|
|
|||
|
|
# Updates
|
|||
|
|
/opt/n8n/update-n8n.sh # Update n8n
|
|||
|
|
apt update && apt upgrade -y # Update system packages
|
|||
|
|
|
|||
|
|
# Backups
|
|||
|
|
ls -lh /opt/n8n/backups/ # List backups
|
|||
|
|
tar -tzf backup.tar.gz | head # View backup contents
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Appendix B: Environment Variables Reference
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# Core Configuration
|
|||
|
|
DB_TYPE=postgresdb # Database type
|
|||
|
|
N8N_PROTOCOL=https # Protocol (http/https)
|
|||
|
|
N8N_HOST=n8n.yourdomain.com # Public hostname
|
|||
|
|
N8N_PORT=5678 # n8n listen port
|
|||
|
|
WEBHOOK_URL=https://... # Webhook base URL
|
|||
|
|
|
|||
|
|
# Database
|
|||
|
|
DB_POSTGRESDB_HOST=localhost
|
|||
|
|
DB_POSTGRESDB_PORT=5432
|
|||
|
|
DB_POSTGRESDB_DATABASE=n8n_db
|
|||
|
|
DB_POSTGRESDB_USER=n8n_user
|
|||
|
|
DB_POSTGRESDB_PASSWORD=...
|
|||
|
|
|
|||
|
|
# Execution
|
|||
|
|
EXECUTIONS_TIMEOUT=300 # Default timeout (seconds)
|
|||
|
|
EXECUTIONS_TIMEOUT_MAX=3600 # Maximum timeout
|
|||
|
|
EXECUTIONS_DATA_SAVE_ON_ERROR=all # Save failed executions
|
|||
|
|
EXECUTIONS_DATA_SAVE_ON_SUCCESS=all # Save successful
|
|||
|
|
|
|||
|
|
# Performance
|
|||
|
|
N8N_PAYLOAD_SIZE_MAX=16 # Max payload size (MB)
|
|||
|
|
EXECUTIONS_PROCESS=main # Execution mode
|
|||
|
|
|
|||
|
|
# Timezone
|
|||
|
|
GENERIC_TIMEZONE=America/New_York
|
|||
|
|
|
|||
|
|
# Security
|
|||
|
|
N8N_ENCRYPTION_KEY=... # Credential encryption key
|
|||
|
|
N8N_JWT_AUTH_ACTIVE=true # Use JWT auth
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Appendix C: Support & Contact
|
|||
|
|
|
|||
|
|
### Getting Help
|
|||
|
|
|
|||
|
|
1. **N8N Community Forum**: https://community.n8n.io/
|
|||
|
|
2. **GitHub Issues**: https://github.com/n8n-io/n8n/issues
|
|||
|
|
3. **Discord**: https://discord.gg/n8n
|
|||
|
|
4. **Documentation**: https://docs.n8n.io/
|
|||
|
|
|
|||
|
|
### This Document
|
|||
|
|
|
|||
|
|
- **Location**: /home/jramos/homelab/N8N-SETUP-PLAN.md
|
|||
|
|
- **Version**: 1.0
|
|||
|
|
- **Created**: 2025-11-29
|
|||
|
|
- **Last Updated**: 2025-11-29
|
|||
|
|
- **Author**: The Scribe (Homelab Infrastructure)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
**Remember**: This is a living document. Update it as your infrastructure evolves, workflows expand, and requirements change. Good infrastructure documentation is your future self's best friend.
|
|||
|
|
|
|||
|
|
Now, let's build something remarkable with n8n.
|
|||
|
|
|
|||
|
|
*— The Scribe*
|