Skip to content

n8n Setup Handoff

Written by: [Claude Code], 2026-04-14

Status: COMPLETE


Part 1: API Key ✅

  • Status: Working
  • Key label: forge-automation
  • Key stored: /home/justinwieb/forge/.env as N8N_API_KEY=n8n_api_98szbI8281snxfQzORSg6
  • How it was set up: Enabled N8N_PUBLIC_API_ENABLED=true in /opt/n8n/docker-compose.yml on CT 106, restarted n8n, then inserted the key directly into the SQLite database at /var/lib/docker/volumes/n8n_n8n_data/_data/database.sqlite. Note: n8n 2.11.4 stores the API key as plaintext in the user_api_keys table (not hashed).
  • Test: curl -H "X-N8N-API-KEY: n8n_api_98szbI8281snxfQzORSg6" http://192.168.86.82:5678/api/v1/workflows → returns workflow list

Part 2: SSH Credentials ✅

  • Status: Working
  • Approach: Used n8n's built-in SSH node with private key credential (cleaner than setting up SSH keys inside the Docker container)
  • Key generated: ed25519 key pair at /tmp/n8n_forge_key (DELETED after setup, key is now only in n8n's encrypted DB)
  • Public key added to: /home/justinwieb/.ssh/authorized_keys on UDev
  • n8n credential: UDev SSH (justinwieb) (ID: ZZFiC6ljPZ3DWUDF, type: sshPrivateKey)
  • Connects as: [email protected] (port 22)

Note on docker exec: The n8n LXC container (CT 106) has an AppArmor restriction that blocks docker exec commands. This is expected behavior for unprivileged LXC. Use n8n's SSH node (which runs inside the container) instead of Execute Command node for anything that needs to reach UDev.


Part 3: Website Health Check Workflow ✅

  • Status: ACTIVE (running every 15 minutes)
  • Workflow ID: sjBejICmqTYTY196
  • Workflow name: "Website Health Check"
  • URL: http://192.168.86.82:5678/workflow/sjBejICmqTYTY196

Flow:

Schedule (every 15m)
  → HTTP GET https://shopnovadesign.com (full response)
  → HTTP GET https://justinkrystal.com (full response)
  → Code: check statusCode on both
  → IF any status < 200 or >= 400
    → TRUE (site down): SSH to UDev → run task-creator.sh (critical priority)
    → FALSE (all good): NoOp (silent pass)

What happens when a site is down: - SSHes to [email protected] - Runs: /home/justinwieb/forge/infra/n8n/task-creator.sh --name site-down --model haiku --priority critical --prompt "Sites down: [site name] -- check and alert" --created-by n8n - Task lands in /home/justinwieb/forge/tasks/pending/site-down.json - Dispatcher picks it up automatically

Known limitation: If a site is completely unreachable (DNS failure, connection refused), the HTTP Request node will throw an error and stop the workflow rather than continuing to the IF check. To handle this: add error handling on the HTTP nodes (in the n8n UI: right-click node → "Add Error Output"). For now this is acceptable, a crashed workflow will show up in n8n's execution history.


Available Infrastructure for Future Workflows

Service URL Auth
n8n API http://192.168.86.82:5678/api/v1 X-N8N-API-KEY: <N8N_API_KEY>
UDev SSH 192.168.86.50:22 n8n credential "UDev SSH (justinwieb)"
Home Assistant http://192.168.86.70:8123 HA_TOKEN in /home/justinwieb/forge/.env
Frigate http://192.168.86.84:5000/api/ No auth required (local only)

Part 4: How to Add More Workflows

Pattern: External Event → Forge Task

Every n8n workflow that creates a Forge task follows the same pattern:

  1. Trigger node (Schedule, Webhook, Cron, etc.)
  2. Processing nodes (HTTP Request, Code, IF, etc.)
  3. SSH node (credential: "UDev SSH (justinwieb)") running:
    /home/justinwieb/forge/infra/n8n/task-creator.sh \
      --name <task-name> \
      --model <haiku|sonnet|opus> \
      --priority <critical|high|normal|low> \
      --prompt "your task description" \
      --created-by n8n
    

Adding a New Trigger via UI

  1. Go to http://192.168.86.82:5678
  2. Click + New Workflow
  3. Add trigger node (Cron, Webhook, HTTP, etc.)
  4. Add processing nodes
  5. Add SSH node at the end
  6. Authentication: Private Key
  7. Credential: UDev SSH (justinwieb)
  8. Resource: Command
  9. Command: the task-creator.sh invocation above
  10. Activate the workflow (toggle in top right)

Adding via API

# Create workflow
curl -s -X POST \
  -H "X-N8N-API-KEY: $(grep N8N_API_KEY /home/justinwieb/forge/.env | cut -d= -f2)" \
  -H "Content-Type: application/json" \
  http://192.168.86.82:5678/api/v1/workflows \
  -d '{ "name": "...", "nodes": [...], "connections": {...}, "settings": {"executionOrder": "v1"} }'

# Activate it (use the returned ID)
curl -s -X POST \
  -H "X-N8N-API-KEY: $(grep N8N_API_KEY /home/justinwieb/forge/.env | cut -d= -f2)" \
  http://192.168.86.82:5678/api/v1/workflows/<ID>/activate

Where Credentials Are Stored

  • n8n credentials (SSH keys, API tokens for external services): stored in n8n's encrypted SQLite DB. Managed via UI → Settings → Credentials or via API /api/v1/credentials.
  • n8n API key: /home/justinwieb/forge/.env as N8N_API_KEY
  • n8n URL: N8N_URL=http://192.168.86.82:5678 in .env

Testing Workflows

# Manually trigger a workflow execution via API
curl -s -X POST \
  -H "X-N8N-API-KEY: n8n_api_98szbI8281snxfQzORSg6" \
  http://192.168.86.82:5678/api/v1/workflows/<ID>/run

# Check recent executions
curl -s -H "X-N8N-API-KEY: n8n_api_98szbI8281snxfQzORSg6" \
  "http://192.168.86.82:5678/api/v1/executions?workflowId=<ID>&limit=5"

In the UI: open the workflow → click Test workflow button.


What's Ready for Future Workflows

  • API access working
  • SSH to UDev working (via n8n SSH node)
  • task-creator.sh integration tested
  • Health check workflow running
  • Home Assistant integration (need to add HA token as n8n credential)
  • Frigate event triggers (need Frigate webhook or polling workflow)
  • Email monitoring (business email only, needs IMAP credential)
  • Shopify webhooks (needs Shopify API credential)