2025-11-30 13:24:29 -07:00
# 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
2025-11-30 17:37:00 -07:00
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 Proxy Manager (NPM) container for SSL termination and secure external access.
2025-11-30 13:24:29 -07:00
---
## 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 │
├────────┼─────────────────────┼───────┼──────────┼──────────┼────────────┤
2025-11-30 17:37:00 -07:00
│ 102 │ nginx-proxy-mgr │ 2 │ 4.0 │ 10G │ 192.168. │
│ │ (NPM - Reverse Proxy)│ │ │ │ 2.101/24 │
2025-11-30 13:24:29 -07:00
│ │ │ │ │ │ │
│ 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.
2025-11-30 17:37:00 -07:00
5. **Consistency ** : Your existing Nginx Proxy Manager (CT 102) is already an LXC container.
2025-11-30 13:24:29 -07:00
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 │
2025-11-30 17:37:00 -07:00
│ OS Template: Debian 12 (bookworm) │
2025-11-30 13:24:29 -07:00
│ │
│ 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 │
└──────────┬───────────┘
│
┌──────────────────┼──────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
2025-11-30 17:37:00 -07:00
│ NPM │ │ n8n │ │ GitLab │
2025-11-30 13:24:29 -07:00
│ 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 │
2025-11-30 17:37:00 -07:00
│ 192.168.2.101 │ Nginx Proxy Manager│ Reverse Proxy │
2025-11-30 13:24:29 -07:00
│ 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) │
│ │
2025-11-30 17:37:00 -07:00
│ Nginx Proxy Manager (CT 102): │
2025-11-30 13:24:29 -07:00
│ 443/tcp ──► HTTPS (proxies to n8n:5678) │
│ 80/tcp ──► HTTP (redirects to HTTPS) │
2025-11-30 17:37:00 -07:00
│ 81/tcp ──► NPM Admin UI (LAN only) │
2025-11-30 13:24:29 -07:00
│ │
│ External Access: │
2025-11-30 17:37:00 -07:00
│ https://n8n.yourdomain.com ──► NPM:443 ──► n8n:5678 │
2025-11-30 13:24:29 -07:00
└────────────────────────────────────────────────────────────────┘
```
### Firewall Rules
```
# Proxmox Firewall Configuration for CT 113 (n8n)
Direction Protocol Source Dest Port Action Comment
─────────────────────────────────────────────────────────────────
2025-11-30 17:37:00 -07:00
IN TCP 192.168.2.101 5678 ACCEPT NPM proxy
2025-11-30 13:24:29 -07:00
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
2025-11-30 17:37:00 -07:00
### A. Nginx Proxy Manager (CT 102)
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
Your existing Nginx Proxy Manager container will handle:
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
1. **SSL/TLS Termination ** - Let's Encrypt certificates (via NPM UI)
2025-11-30 13:24:29 -07:00
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
2025-11-30 17:37:00 -07:00
6. **Web-based Management ** - No manual config file editing required
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**Nginx Proxy Manager Overview:**
Nginx Proxy Manager (NPM) is a Docker-based reverse proxy management tool that provides:
- **Web UI**: Accessible at `http://192.168.2.101:81`
- **Let's Encrypt Integration**: One-click SSL certificate generation and renewal
- **GUI Configuration**: Point-and-click proxy host creation
- **Built-in Access Control**: IP whitelisting and basic authentication
- **Real-time Monitoring**: View proxy status and logs through dashboard
**GitHub**: https://github.com/NginxProxyManager/nginx-proxy-manager
**Configuration for n8n (via NPM Web UI):**
Instead of manually editing nginx configuration files, you'll configure the n8n proxy through NPM's web interface in Phase 7. Basic setup:
1. **Access NPM Admin UI ** : `http://192.168.2.101:81`
2. **Create Proxy Host ** with these settings:
- Domain: `n8n.yourdomain.com`
- Forward to: `192.168.2.113:5678`
- Enable WebSockets support
3. **Configure SSL ** : Request Let's Encrypt certificate via UI
4. **Advanced Settings ** (optional custom nginx config):
2025-11-30 13:24:29 -07:00
```nginx
2025-11-30 17:37:00 -07:00
# Custom Nginx directives for n8n (added via NPM Advanced tab)
client_max_body_size 50M;
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# Extended timeouts for long-running workflows
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# Additional security headers
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# WebSocket keep-alive
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
2025-11-30 13:24:29 -07:00
```
2025-11-30 17:37:00 -07:00
**NPM Architecture:**
- **Admin UI**: Port 81 (LAN access only)
- **Proxy Traffic**: Ports 80/443
- **Docker-based**: Runs in containers on CT 102
- **Auto-renewal**: Let's Encrypt certificates renew automatically
2025-11-30 13:24:29 -07:00
### 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
2025-11-30 17:37:00 -07:00
# Install basic prerequisites
2025-11-30 13:24:29 -07:00
apt install -y \
curl \
wget \
git \
gnupg2 \
ca-certificates \
lsb-release \
ufw
2025-11-30 17:37:00 -07:00
# Add PostgreSQL Official Repository
# Note: PostgreSQL 16 is not in standard Debian repositories
echo "Setting up PostgreSQL 16 from official repository..."
# Add PostgreSQL GPG key
curl -fsSL https://www.postgresql.org/media/keys/ACCC4CF8.asc | \
gpg --dearmor -o /etc/apt/trusted.gpg.d/postgresql.gpg
# Add PostgreSQL APT repository
sh -c 'echo "deb https://apt.postgresql.org/pub/repos/apt $(lsb_release -cs)-pgdg main" > /etc/apt/sources.list.d/pgdg.list'
# Update package list with new repository
apt update
# Install PostgreSQL 16
apt install -y postgresql-16 postgresql-contrib-16
# Verify installation
psql --version
2025-11-30 13:24:29 -07:00
# 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
```
2025-11-30 17:37:00 -07:00
### Phase 7: Nginx Proxy Manager Configuration (10 minutes)
Unlike traditional nginx configuration, NPM uses a web-based GUI for all proxy management. No SSH required.
**Prerequisites:**
- NPM is installed and running on CT 102
- NPM admin UI accessible at `http://192.168.2.101:81`
- DNS A record for `n8n.yourdomain.com` pointing to your public IP
#### Step 1: Access NPM Admin Interface
From your workstation browser:
- Navigate to: `http://192.168.2.101:81`
- **First-time login credentials:**
- Email: `admin@example.com`
- Password: `changeme`
- **IMPORTANT:** You will be prompted to change these immediately
#### Step 2: Create Proxy Host for n8n
1. **Navigate to Proxy Hosts ** :
- Click "Hosts" → "Proxy Hosts" in the NPM dashboard
- Click "Add Proxy Host" button
2. **Configure Details Tab ** :
```
Domain Names: n8n.yourdomain.com
Scheme: http
Forward Hostname/IP: 192.168.2.113
Forward Port: 5678
Options:
☑ Cache Assets
☑ Block Common Exploits
☑ Websockets Support (CRITICAL for n8n!)
☐ Access List (optional - configure if needed)
```
3. **Configure SSL Tab ** :
```
SSL Certificate: Request a new SSL Certificate
☑ Force SSL
☑ HTTP/2 Support
☑ HSTS Enabled
☐ HSTS Subdomains (not needed for n8n)
Email Address: your-email@domain .com
☑ I Agree to the Let's Encrypt Terms of Service
```
4. **Configure Advanced Tab (Optional) ** :
```nginx
# Custom Nginx Configuration
# Paste the following for optimal n8n performance:
client_max_body_size 50M;
# Extended timeouts for long-running workflows
proxy_connect_timeout 300;
proxy_send_timeout 300;
proxy_read_timeout 300;
send_timeout 300;
# Additional security headers
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "no-referrer-when-downgrade" always;
# WebSocket keep-alive
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
```
5. **Save Configuration ** :
- Click "Save" button
- NPM will automatically:
- Generate nginx configuration
- Request Let's Encrypt certificate
- Configure SSL settings
- Reload nginx
- Enable automatic certificate renewal (every 60 days)
#### Step 3: Verify Configuration
2025-11-30 13:24:29 -07:00
```bash
2025-11-30 17:37:00 -07:00
# Test n8n accessibility through NPM
curl -I https://n8n.yourdomain.com
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# Expected response:
HTTP/2 200
server: nginx
content-type: text/html; charset=utf-8
strict-transport-security: max-age=31536000
x-frame-options: SAMEORIGIN
...
```
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
#### Step 4: Verify DNS and Port Forwarding
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**DNS Configuration:**
Ensure your domain's DNS has an A record pointing to your public IP:
```
Type: A
Host: n8n
Points to: <your-public-ip>
TTL: 3600
```
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**Router Port Forwarding** (if behind NAT):
```
External Port 80 → 192.168.2.101:80
External Port 443 → 192.168.2.101:443
```
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
#### NPM Monitoring & Management
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**View Logs**:
- Click on proxy host → "Actions" → "View Logs"
- Real-time request logging and error tracking
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**Certificate Renewal**:
- Automatic renewal via NPM (every 60 days)
- Manual renewal: Edit proxy host → SSL tab → "Renew Certificate"
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**Disable/Enable Proxy**:
- Toggle switch next to proxy host name
- No need to restart services
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
#### Troubleshooting NPM
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
**Issue: NPM Web UI not accessible**
```bash
# Check NPM container status on CT 102
pct enter 102
docker ps | grep nginx-proxy-manager
docker logs nginx-proxy-manager
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# Restart NPM if needed
docker restart nginx-proxy-manager
2025-11-30 13:24:29 -07:00
```
2025-11-30 17:37:00 -07:00
**Issue: SSL certificate generation fails**
- Verify DNS propagation: `nslookup n8n.yourdomain.com`
- Check port 80/443 accessibility from internet
- Review Let's Encrypt rate limits (5 certs/week per domain)
- Check NPM logs for specific error messages
**Issue: n8n not accessible through NPM**
- Verify n8n is running: `curl http://192.168.2.113:5678`
- Check NPM proxy host configuration (correct IP/port)
- Verify firewall allows 192.168.2.101 → 192.168.2.113:5678
- Review NPM access logs for 502/504 errors
2025-11-30 13:24:29 -07:00
### 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'
2025-11-30 17:37:00 -07:00
ufw allow from 192.168.2.101 to any port 5678 comment 'NPM reverse proxy'
2025-11-30 13:24:29 -07:00
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
2025-11-30 17:37:00 -07:00
# HTTPS through NPM
2025-11-30 13:24:29 -07:00
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
2025-11-30 17:37:00 -07:00
# Check NPM status (on CT 102)
pct enter 102
docker ps | grep nginx-proxy-manager
docker logs nginx-proxy-manager
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# View NPM proxy host configuration
# Access http://192.168.2.101:81 and check proxy host settings
2025-11-30 13:24:29 -07:00
# Check SSL certificate
2025-11-30 17:37:00 -07:00
# NPM Admin UI → SSL Certificates tab shows all certs and expiry dates
2025-11-30 13:24:29 -07:00
2025-11-30 17:37:00 -07:00
# Renew if needed (NPM auto-renews, but can manually trigger)
# NPM UI → Proxy Host → Edit → SSL → Renew Certificate button
2025-11-30 13:24:29 -07:00
# Check firewall
ufw status
2025-11-30 17:37:00 -07:00
# Ensure 443 is open on NPM container (CT 102)
2025-11-30 13:24:29 -07:00
# 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
2025-11-30 17:37:00 -07:00
# Also check NPM timeout in proxy host Advanced settings
2025-11-30 13:24:29 -07:00
# 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) │
2025-11-30 17:37:00 -07:00
│ □ Implement rate limiting in NPM (if available) │
2025-11-30 13:24:29 -07:00
│ □ 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
2025-11-30 17:37:00 -07:00
# Implement NPM rate limiting
# Navigate to NPM Admin UI → Proxy Host → n8n → Advanced tab
# Add custom configuration:
2025-11-30 13:24:29 -07:00
limit_req_zone $binary_remote_addr zone=n8n_limit:10m rate=10r/s;
2025-11-30 17:37:00 -07:00
# In location block (Advanced config):
2025-11-30 13:24:29 -07:00
limit_req zone=n8n_limit burst=20 nodelay;
2025-11-30 17:37:00 -07:00
# Save configuration (NPM auto-reloads)
2025-11-30 13:24:29 -07:00
```
---
## 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)
│
2025-11-30 17:37:00 -07:00
├─ Check NPM Status (http://192.168.2.101:81)
2025-11-30 13:24:29 -07:00
│
├─ 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) │ ║
║ │ │ │ ║
║ │ ┌───────────────────┼───────────────────────┐ │ ║
║ │ │ │ │ │ ║
║ │ │ ┌────────────────▼──────┐ ┌──────────▼┐ │ ║
2025-11-30 17:37:00 -07:00
║ │ │ │ NPM (CT 102) │ │ n8n │ │ ║
2025-11-30 13:24:29 -07:00
║ │ │ │ 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)
2025-11-30 17:37:00 -07:00
4. **Configure NPM proxy ** (Phase 7)
2025-11-30 13:24:29 -07:00
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*