#+title: N8N Setup
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="_share/media/css/computer.css" />
#+HTML_HEAD: <link rel="stylesheet" type="text/css" href="_share/media/css/org-media-sass/content-overview.css" />
#+OPTIONS: H:6

* links
- [[./toc.org][TOC - Home System]]

* important values
** login data


| key          | value                            |
|--------------+----------------------------------|
| host         | [[https://n8n.ronnyabraham.com]] |
| web email    | ronny.abraham@ymail.com          |
| web password | chukatHat6rah!                   |

| key                | value                                |
|--------------------+--------------------------------------|
| home location      | /home/ronny/n8n                      |
| license activation | df50f55c-1ba0-46b7-9648-8b22723fb921 |
| docker auth        | admin-n8n                            |
| docker pass        | 2reishit2ara                         |
| port               | 5678                                 |

* DNS Record for n8n

| Field           | Value                 | Description                   |
|-----------------+------------------------+-------------------------------|
| Record Name     | n8n.ronnyabraham.com   | Full subdomain                |
| Record Type     | A                      | IPv4 address record           |
| Value           | 94.159.253.187         | Your public IP                |
| Alias           | No                     | Not a CNAME                   |
| TTL (seconds)   | 300                    | 5 minutes cache time          |
| Routing Policy  | Simple                 | Standard routing              |

* N8N mount setup
- Left box :: /mnt/storage/n8n — the actual directory on your external drive
- Top-right box :: /srv/n8n — where the system accesses it via a bind mount
- Middle-right box :: Docker host — this is your Pi's environment
- Bottom-right box :: /home/node/.n8n — inside the container, this is where n8n looks for its data

#+caption: n8n setup
#+attr_html: :width 1000px
[[./_share/media/img/n8n-diagram.png]]

** permission setup
#+begin_src bash
sudo chown -R ronny:ronny /mnt/storage/n8n
sudo mount -a
sudo chown -R ronny:ronny /srv/n8n
chmod 700 /srv/n8n
#+end_src

** fstab
#+begin_src bash
/mnt/storage/n8n /srv/n8n none bind 0 0
#+end_src


* scripts

** docker-compose.yml
#+INCLUDE: "docker.org::#docker-n8n" :only-contents t

** nginx
#+INCLUDE: "nginx.org::#n8n-conf" :only-contents t


* Potential Issue
** Why `curl http://localhost:5678` might fail even when Nginx works

n8n uses the `N8N​_HOST` environment variable to validate incoming requests. If a request arrives with a `Host` header that does not match `N8N​_HOST`, n8n may reject it or reset the connection.

This is often encountered when using `curl` directly against `localhost`.

**Request Behavior**

| Command                                                           | Result | Reason                                                      |
|-------------------------------------------------------------------+--------+-------------------------------------------------------------|
| curl -I http://localhost:5678                                     | Fail   | Host header is "localhost" which doesn't match n8n setting  |
| curl -I http://localhost:5678 -H "Host: n8n.ronnyabraham.com"     | Pass   | Host header matches expected `N8N​_HOST` value               |
| curl -I https://n8n.ronnyabraham.com                              | Pass   | Routed via Nginx which forwards the correct Host header     |

**Explanation**

n8n enforces `N8N​_HOST` to ensure external requests match the configured hostname. When accessed locally via `curl`, the default Host header is `"localhost"`, which does not align with the configured hostname (`n8n.ronnyabraham.com`). This causes the connection to be reset or denied.

To test the service directly from the host machine, you must manually set the correct Host header using `-H "Host: n8n.ronnyabraham.com"`.

Alternatively, access the service through its public HTTPS URL, which is routed through Nginx and includes the correct headers automatically.



* Options

** .env + secrets the clean way
- Store sensitive values in a `.env` file instead of `docker-compose.yml`
- Keeps secrets out of version control
- Easier to manage and change later

Example `.env` file:
#+begin_src env
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=your_strong_password
N8N_HOST=n8n.ronnyabraham.com
N8N_PROTOCOL=https
N8N_PORT=5678
#+end_src

In `docker-compose.yml`:
#+begin_src yaml
environment:
  - N8N_BASIC_AUTH_USER=${N8N_BASIC_AUTH_USER}
  - N8N_BASIC_AUTH_PASSWORD=${N8N_BASIC_AUTH_PASSWORD}
  - N8N_HOST=${N8N_HOST}
  - N8N_PORT=${N8N_PORT}
  - N8N_PROTOCOL=${N8N_PROTOCOL}
#+end_src

** Workflow backups to external drives
- Backup `/srv/n8n` regularly
- Prevents data loss from crashes or SD card issues

Example backup script:
#+begin_src bash
rsync -avh /srv/n8n /mnt/backup/n8n-backup-$(date +%F)
#+end_src

To schedule it:
#+begin_src bash
crontab -e
# Add:
0 3 * * * /home/ronny/scripts/backup-n8n.sh
#+end_src

** Remote editing with VS Code or SSH
- Manage Pi remotely from your laptop

*** Option A: VS Code Remote SSH
Install extension: `Remote - SSH`

Sample SSH config:
#+begin_src conf
Host raspberrypi
  HostName 192.168.1.42
  User ronny
#+end_src

Use: `Remote-SSH: Connect to Host...`

*** Option B: Plain SSH from terminal
#+begin_src bash
ssh ronny@192.168.1.42
nano ~/n8n/docker-compose.yml
#+end_src
