LemonSec/MIGRATE-FROM-NPM.md

6.2 KiB

Migrating from Nginx Proxy Manager (NPM)

Concept Mapping

NPM Feature Traefik Equivalent
Proxy Hosts Routers + Services
SSL Certificates certresolver (automatic)
Custom Locations Middlewares
Access Lists Authelia / Basic Auth
404 Page Custom error middleware
Redirection Hosts Redirect middleware
Streams TCP Routers

Migration Steps

1. Document Current NPM Setup

In NPM UI, go through each Proxy Host and note:

  • Domain names
  • Forward hostname/IP and port
  • Scheme (http/https)
  • Custom locations
  • Access lists
  • SSL settings
  • Advanced configuration

2. Export NPM Config (Optional Backup)

NPM → SettingsBackupDownload

This creates a JSON backup of all hosts.

3. Create docker-compose.override.yml

This is where your migrated hosts go:

version: "3.8"

networks:
  services:
    external: true

services:
  # ========================================
  # MIGRATED FROM NPM
  # ========================================
  
  # Example: Migrating "nextcloud.lemonlink.eu"
  # NPM Settings:
  # - Domain: nextcloud.lemonlink.eu
  # - Forward: 192.168.1.100:9001
  # - Scheme: http
  # - Block Common Exploits: yes
  # - SSL: yes (LE)
  
  nextcloud-migration:
    image: alpine:latest
    container_name: npm-migration-nextcloud
    restart: "no"
    command: "echo 'Migrated from NPM'"
    networks:
      - services
    labels:
      # Enable Traefik
      - "traefik.enable=true"
      
      # Router (like Proxy Host)
      - "traefik.http.routers.nextcloud.rule=Host(`nextcloud.lemonlink.eu`)"
      - "traefik.http.routers.nextcloud.entrypoints=websecure"
      - "traefik.http.routers.nextcloud.tls.certresolver=letsencrypt"
      
      # Service (Forward to)
      - "traefik.http.services.nextcloud.loadbalancer.server.url=http://192.168.1.100:9001"
      
      # Middlewares (Access Lists, Security)
      - "traefik.http.routers.nextcloud.middlewares=security-headers@file,rate-limit@file"
  
  # Add more migrations here...
  # service2-migration:
  #   ...

4. Common NPM → Traefik Patterns

Pattern 1: Basic Proxy Host

NPM:
  Domain: app.lemonlink.eu
  Forward: 192.168.1.10:8080
  SSL: yes

Traefik:
  labels:
    - "traefik.enable=true"
    - "traefik.http.routers.app.rule=Host(`app.lemonlink.eu`)"
    - "traefik.http.routers.app.entrypoints=websecure"
    - "traefik.http.routers.app.tls.certresolver=letsencrypt"
    - "traefik.http.services.app.loadbalancer.server.url=http://192.168.1.10:8080"
    - "traefik.http.routers.app.middlewares=security-headers@file,rate-limit@file"

Pattern 2: Access List (Basic Auth)

NPM:
  Access List: Family
  Users: user1 / pass1, user2 / pass2

Traefik:
  # In docker-compose.override.yml middlewares section
  # Or use Authelia (recommended)
  
  # Option A: Basic Auth (simple)
  labels:
    - "traefik.http.routers.app.middlewares=app-basicauth"
    - "traefik.http.middlewares.app-basicauth.basicauth.users=user1:$$apr1$$..."
  
  # Option B: Authelia (SSO, recommended)
  labels:
    - "traefik.http.routers.app.middlewares=authelia@docker"

Pattern 3: Custom Location

NPM:
  Location: /api
  Forward: 192.168.1.10:8080/api

Traefik:
  # Use PathPrefix rule
  labels:
    - "traefik.http.routers.app-api.rule=Host(`app.lemonlink.eu`) && PathPrefix(`/api`)"
    - "traefik.http.routers.app-api.service=api-service"
    - "traefik.http.services.api-service.loadbalancer.server.url=http://192.168.1.10:8080"

Pattern 4: Custom Nginx Config

NPM Advanced:
  proxy_set_header X-Custom-Header value;
  client_max_body_size 10G;

Traefik:
  # Add to dynamic/middlewares.yml or inline
  labels:
    - "traefik.http.middlewares.custom-headers.headers.customRequestHeaders.X-Custom-Header=value"
    - "traefik.http.routers.app.middlewares=custom-headers"
  
  # For body size, use buffering:
  - "traefik.http.services.app.loadbalancer.responseforwarding.flushinterval=100ms"

5. Gradual Migration Strategy

Don't migrate everything at once:

Week 1: Setup LemonSec

  • Deploy Traefik + Authelia + CrowdSec
  • Test with one non-critical service
  • Keep NPM running

Week 2: Migrate Low-Risk Services

  • Move internal services first
  • Test thoroughly
  • Keep Nextcloud on NPM for now

Week 3: Migrate Nextcloud

  • Schedule downtime
  • Update TrueNAS Nextcloud config
  • Test with family
  • Keep NPM as backup

Week 4: Decommission NPM

  • After 1 week stable
  • Stop NPM container
  • Remove port forwards to NPM
  • Keep config backup

6. Parallel Running

You can run both during migration:

Internet
    ↓
Router (port 443)
    ↓
    ├─► NPM (port 444) ──► Some services
    └─► Traefik (port 443) ──► New services

Change router port forward to test:

  • Port 443 → Traefik
  • Port 444 → NPM (backup access)

7. Testing Checklist

For each migrated service:

  • HTTP redirects to HTTPS
  • SSL certificate valid
  • Can login
  • All pages load
  • File uploads work
  • Mobile apps connect
  • No console errors

8. Rollback Plan

If something breaks:

# Stop Traefik
docker-compose -f docker-compose.yml -f docker-compose.override.yml down

# Restart NPM
docker start npm

# Revert router port forward to NPM
# Access via: https://old-domain:444 (if configured)

Keep NPM container stopped but available:

docker stop npm
docker rename npm npm-backup
# Don't delete until migration complete

NPM Features Not in Traefik

NPM Feature Traefik Alternative
Nice Web UI Traefik Dashboard + Portainer
One-click SSL Automatic via certresolver
Built-in auth Authelia (more powerful)
Redirection UI YAML config
Access Logs JSON logs in traefik/logs/

Benefits of Migrating

  1. Declarative: All config in Git-trackable files
  2. Automatic: SSL certificates without clicks
  3. Integrated: Built-in CrowdSec, Authelia
  4. Fast: Better performance than NPM
  5. Flexible: More routing options
  6. Modern: Active development, Traefik 3.x

Need Help?

  • Check examples/ for common patterns
  • See docs/TRUENAS-NEXTCLOUD.md for Nextcloud specifically
  • Review QUICKSTART.md for fresh setup
  • Traefik docs: https://doc.traefik.io/