diff --git a/ansible/inventory/host_vars/nuremberg-a.yml b/ansible/inventory/host_vars/nuremberg-a.yml index 25e7d74..27a2008 100644 --- a/ansible/inventory/host_vars/nuremberg-a.yml +++ b/ansible/inventory/host_vars/nuremberg-a.yml @@ -7,6 +7,7 @@ ansible_python_interpreter: /usr/bin/python3 docker_services: - poste-io + - n8n # Mail ports (25,80,110,143,443,465,587,993,995) exposed via Docker # port mappings in ansible/services/poste-io/docker-compose.yml. diff --git a/ansible/services/README.md b/ansible/services/README.md index c649c4d..c709a94 100644 --- a/ansible/services/README.md +++ b/ansible/services/README.md @@ -25,6 +25,7 @@ There is **no** per-host subdirectory — services are named by what they are, a | bitwarden | Docker | helsinki-a | Vaultwarden + MariaDB | | forgejo | Docker | helsinki-a | Git forge | | poste-io | Docker | nuremberg-a | Mail | +| n8n | Docker | nuremberg-a | Workflow automation | | jellyseerr | Docker | london-b | Plex request manager | | navidrome | Docker | london-b | Music streaming | | bookshelf | Docker | london-b | Ebook/audiobook manager (Readarr revival) | diff --git a/ansible/services/caddy/Caddyfile b/ansible/services/caddy/Caddyfile index c8a7e32..26d3c9a 100644 --- a/ansible/services/caddy/Caddyfile +++ b/ansible/services/caddy/Caddyfile @@ -155,6 +155,14 @@ music.pez.sh { ## NUREMBERG-A SERVICES ## +# n8n (own auth) +n8n.pez.sh { + tracing { + span n8n + } + reverse_proxy 100.70.180.24:5678 +} + ## HELSINKI-A SERVICES ## # Bitwarden (requires HTTPS tweaking) diff --git a/ansible/services/n8n/README.md b/ansible/services/n8n/README.md new file mode 100644 index 0000000..e67ca96 --- /dev/null +++ b/ansible/services/n8n/README.md @@ -0,0 +1,10 @@ +# n8n + +Workflow automation / orchestration. + +- **Host:** nuremberg-a +- **URL:** https://n8n.pez.sh +- **Port:** 5678 (bound to the Tailscale IP `100.70.180.24` only; exposed publicly via Caddy on helsinki-a) +- **Auth:** n8n's own user management (login on first run) +- **Data:** `n8n_data` named volume (`/home/node/.n8n`) +- **Files:** `./local-files` mounted at `/files` inside the container diff --git a/ansible/services/n8n/docker-compose.yml b/ansible/services/n8n/docker-compose.yml new file mode 100644 index 0000000..73a5b06 --- /dev/null +++ b/ansible/services/n8n/docker-compose.yml @@ -0,0 +1,28 @@ +--- +# n8n - Workflow automation +# Host: nuremberg-a (100.70.180.24) +# Port bound to the Tailscale IP only; public access is via Caddy on helsinki-a. +# n8n manages its own auth (user management / login). + +services: + n8n: + image: docker.n8n.io/n8nio/n8n + container_name: n8n + restart: always + ports: + - "100.70.180.24:5678:5678" + environment: + - N8N_ENFORCE_SETTINGS_FILE_PERMISSIONS=true + - N8N_HOST=n8n.pez.sh + - N8N_PORT=5678 + - N8N_PROTOCOL=http + - NODE_ENV=production + - WEBHOOK_URL=https://n8n.pez.sh/ + - GENERIC_TIMEZONE=Europe/London + - TZ=Europe/London + volumes: + - n8n_data:/home/node/.n8n + - ./local-files:/files + +volumes: + n8n_data: diff --git a/ansible/services/n8n/local-files/.gitkeep b/ansible/services/n8n/local-files/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/docs/services.md b/docs/services.md index 645e019..12dfc4c 100644 --- a/docs/services.md +++ b/docs/services.md @@ -89,9 +89,12 @@ Dedicated mail server on Hetzner Cloud. Isolated to protect IP reputation. | Service | Port | Deployment | Auth | URL | |---------|------|-----------|------|-----| | poste.io | 25, 80, 110, 143, 443, 465, 587, 993, 995 | Docker | Own auth | (webmail via direct host access) | +| n8n | 5678 | Docker | Own auth | https://n8n.pez.sh | poste.io bundles everything — postfix, dovecot, rspamd, webmail — into a single container. Makes updates straightforward. +n8n (workflow automation) binds 5678 to the Tailscale IP only; public access is proxied by Caddy on helsinki-a. It manages its own user auth. + ## copenhagen-a — Gaming Game servers. Not publicly exposed via Caddy — accessed directly over the public IP/Tailscale. diff --git a/terraform/hetzner/dns.tf b/terraform/hetzner/dns.tf index 1e4b992..76ba482 100644 --- a/terraform/hetzner/dns.tf +++ b/terraform/hetzner/dns.tf @@ -15,7 +15,7 @@ resource "hcloud_zone_rrset" "A_helsinki_a" { for_each = toset([ "@", "apps", "auth", "bitwarden", "download", "git", "helsinki-a", "jellyfin", "jellyfin-requests", "ldap", "lidarr", "london-a", "music", "naveen", - "plex", "prowlarr", "radarr", "readarr", "request", + "n8n", "plex", "prowlarr", "radarr", "readarr", "request", "sonarr", "soulseek", "status", ]) zone = hcloud_zone.pezsh.name