# 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*