Files
nuc/docs/architecture.md
Alejandro Gutiérrez 390eda1595 Initial commit - NUC server configuration and docs
- CLAUDE.md: Server instructions and service reference
- docs/: Persistent documentation (architecture, guides)
- .artifacts/: Session-generated notes
- playwriter-browser/: Remote browser container config

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 20:49:20 +00:00

17 KiB

NUC Infrastructure Architecture

Date: 2026-02-01 Context: Secure self-hosted infrastructure with Tailscale Funnel for public access and Tailscale mesh for private admin access. Designed to bypass Spanish ISP blocks and handle dynamic IPs.


Architecture Diagram

┌─────────────────────────────────────────────────────────────────────────────┐
│                              INTERNET                                        │
└─────────────────────────────────────────────────────────────────────────────┘
                    │                                    │
                    │ Public Traffic                     │ Admin Traffic
                    ▼                                    ▼
┌───────────────────────────────┐        ┌─────────────────────────────────────┐
│      whyrating.com            │        │         TAILSCALE MESH              │
│           │                   │        │     (encrypted, private)            │
│           ▼                   │        │                                     │
│  ┌─────────────────────┐      │        │   ┌───────────┐    ┌───────────┐   │
│  │   Namecheap DNS     │      │        │   │  Your Mac │◄──►│    NUC    │   │
│  │   (301 redirect)    │      │        │   │100.x.x.2  │    │100.x.x.1  │   │
│  └──────────┬──────────┘      │        │   └───────────┘    └───────────┘   │
│             │                 │        │         ▲                ▲         │
│             ▼                 │        │         │    Anywhere    │         │
│  ┌─────────────────────┐      │        │         │    in world    │         │
│  │  Tailscale Funnel   │      │        └─────────┴────────────────┴─────────┘
│  │ nuc-tailscale.ts.net│◄─────┼────────────────────────┘
│  └──────────┬──────────┘      │
│             │ HTTPS/443       │
└─────────────┼─────────────────┘
              │
              ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│                                 NUC SERVER                                   │
│                              192.168.1.3                                     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                         SECURITY LAYER                               │    │
│  │  ┌─────────────┐                                                     │    │
│  │  │  CrowdSec   │  ← Blocks malicious IPs, DDoS protection            │    │
│  │  │   :8083     │                                                     │    │
│  │  └─────────────┘                                                     │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                    │                                         │
│                                    ▼                                         │
│  ┌─────────────────────────────────────────────────────────────────────┐    │
│  │                      COOLIFY (Docker Orchestrator)                   │    │
│  │                                                                      │    │
│  │   ┌─────────────────────────────────────────────────────────────┐   │    │
│  │   │                    TRAEFIK (Reverse Proxy)                   │   │    │
│  │   │                     Routes by domain                         │   │    │
│  │   └───────────┬─────────────────┬─────────────────┬─────────────┘   │    │
│  │               │                 │                 │                  │    │
│  │               ▼                 ▼                 ▼                  │    │
│  │   ┌─────────────────────────────────────────────────────────────┐   │    │
│  │   │                    PUBLIC WEBSITES                          │   │    │
│  │   │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │   │    │
│  │   │  │Homepage │  │ App A   │  │ App B   │  │ App C   │        │   │    │
│  │   │  │ :3000   │  │ :3001   │  │ :3002   │  │ :3003   │        │   │    │
│  │   │  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │   │    │
│  │   │            (internal ports only, not exposed)               │   │    │
│  │   └─────────────────────────────────────────────────────────────┘   │    │
│  │                                                                      │    │
│  │   ┌─────────────────────────────────────────────────────────────┐   │    │
│  │   │              PRIVATE SERVICES (Tailscale only)              │   │    │
│  │   │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │   │    │
│  │   │  │Coolify  │  │ Gitea   │  │ MinIO   │  │Postgres │        │   │    │
│  │   │  │ :8000   │  │ :3030   │  │ :9001   │  │ :5432   │        │   │    │
│  │   │  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │   │    │
│  │   │                                                             │   │    │
│  │   │  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐        │   │    │
│  │   │  │Authentik│  │   n8n   │  │Vaultwrdn│  │ Outline │        │   │    │
│  │   │  │ :9090   │  │ :5678   │  │ :8222   │  │ :3080   │        │   │    │
│  │   │  └─────────┘  └─────────┘  └─────────┘  └─────────┘        │   │    │
│  │   └─────────────────────────────────────────────────────────────┘   │    │
│  └─────────────────────────────────────────────────────────────────────┘    │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘

Traffic Flows

Public Website Access

User → whyrating.com → Namecheap 301 → nuc-tailscale.ts.net → Tailscale Funnel
     → CrowdSec → Traefik → Container (internal port)

Admin Access (Remote)

Your Mac → Tailscale mesh (encrypted) → NUC Tailscale IP (100.x.x.x)
         → Direct access to any port (8000, 22, etc.)

Admin Access (Home Network)

Your Mac → Local network → 192.168.1.3 → Any port

Component Summary

Component Port Access Purpose
Tailscale Funnel 443 Public Single internet entry point
CrowdSec 8083 Private DDoS/attack protection
Traefik 80/443 Internal Routes domains to containers
Homepage 3000 Via Funnel Public dashboard
Coolify 8000 Tailscale only Container management
Databases various Tailscale only Data storage

Security Layers

┌─────────────────────────────────────────────────────────┐
│ Layer 1: TAILSCALE FUNNEL                               │
│ • Only entry point from internet                        │
│ • HTTPS termination                                     │
│ • No open ports on router                               │
├─────────────────────────────────────────────────────────┤
│ Layer 2: CROWDSEC                                       │
│ • Crowdsourced threat intelligence                      │
│ • Blocks known malicious IPs                            │
│ • DDoS mitigation                                       │
├─────────────────────────────────────────────────────────┤
│ Layer 3: TRAEFIK                                        │
│ • Domain-based routing                                  │
│ • Only forwards to valid services                       │
│ • Rate limiting (configurable)                          │
├─────────────────────────────────────────────────────────┤
│ Layer 4: DOCKER NETWORK ISOLATION                       │
│ • Containers can't access each other unless configured  │
│ • Databases on separate network from public apps        │
├─────────────────────────────────────────────────────────┤
│ Layer 5: TAILSCALE MESH (Admin)                         │
│ • All admin traffic encrypted                           │
│ • No admin ports exposed to internet                    │
│ • Device authentication required                        │
└─────────────────────────────────────────────────────────┘

Dynamic IP Handling

ISP Changes IP
      │
      ▼
┌─────────────┐    auto-update    ┌──────────────────────┐
│ NUC detects │ ────────────────► │ Tailscale Coord      │
│ new IP      │                   │ Server               │
└─────────────┘                   └──────────┬───────────┘
                                             │
      ┌──────────────────────────────────────┘
      │ broadcasts new location
      ▼
┌─────────────────────────────────────────────────────────┐
│                    UNCHANGED                            │
│  • Tailscale IP: 100.x.x.x (stable)                    │
│  • Funnel URL: nuc-tailscale.tail58f5ad.ts.net (stable)│
│  • whyrating.com redirect (stable)                      │
│  • All tunnels auto-reconnect (~10-30 sec)             │
└─────────────────────────────────────────────────────────┘

Key Point: Your ISP can change your public IP anytime - Tailscale handles this automatically. No DDNS needed.


Access Reference

From To Method
Public users Websites whyrating.com or .ts.net URL
You (remote) NUC admin ssh nuc-tailscale or http://100.x.x.x:8000
You (home) NUC admin ssh nuc or http://192.168.1.3:8000
You (remote) Router SSH jump: ssh -J nuc-tailscale root@192.168.1.1

URLs

Service Public URL Private URL (Tailscale)
Main site whyrating.com -
Direct Funnel nuc-tailscale.tail58f5ad.ts.net -
Coolify - http://nuc-tailscale:8000
Homepage Via Funnel :3000 http://nuc-tailscale:3000
Gitea - http://nuc-tailscale:3030

What's NOT Exposed to Internet

  • SSH (22)
  • Coolify (8000)
  • Databases (5432, 3306)
  • MinIO (9000/9001)
  • Authentik (9090)
  • Router admin (192.168.1.1)
  • Any direct ports on router

Coolify Deployment Best Practices

For Public Apps:

services:
  myapp:
    image: myapp:latest
    # NO ports: section - Traefik routes internally
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.myapp.rule=Host(`myapp.whyrating.com`)"
    networks:
      - coolify

For Private Apps:

services:
  mydb:
    image: postgres:16
    # No traefik labels
    # No exposed ports
    networks:
      - internal  # Separate from coolify network

Quick Commands

# Check Tailscale status
tailscale status

# Check Funnel status
ssh nuc "tailscale funnel status"

# Access Coolify remotely
open http://nuc-tailscale:8000

# SSH to NUC from anywhere
ssh nuc-tailscale

# Check CrowdSec decisions
ssh nuc "docker exec crowdsec-* cscli decisions list"

  • .artifacts/2026-02-01_19-11_domain-pre-purchase-check-guide.md - Domain checking before purchase
  • .artifacts/domain-check.sh - Script to check domains for blocks
  • CLAUDE.md - Full NUC server documentation

Why This Architecture?

  1. Spanish ISP Blocks - Cloudflare shared IPs are blocked during LaLiga matches. Tailscale Funnel uses different infrastructure.

  2. Dynamic IP - No need for DDNS or port forwarding. Tailscale handles IP changes automatically.

  3. Security - Zero ports exposed on router. All admin via encrypted Tailscale mesh.

  4. Simplicity - Single entry point (Funnel), single orchestrator (Coolify), single security layer (CrowdSec).