Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Server & Netzwerk 04.08.2026 · 10 min Lesezeit

Pangolin mit Docker installieren: Identity-aware Tunnel-Reverse-Proxy auf WireGuard-Basis

Pangolin ist die selbstgehostete Cloudflare-Tunnel-Alternative mit 21k+ Stars: Identity-aware Reverse Proxy auf WireGuard-Basis, der interne Dienste ohne Portfreigabe sicher nach außen bringt – mit Web-UI, RBAC und automatischem TLS über Traefik.

Illustration zur Installation von Pangolin mit Docker als Identity aware Tunnel Reverse Proxy auf WireGuard Basis. Die Grafik zeigt eine sichere Self Hosting Infrastruktur mit verschlüsselten WireGuard Tunneln, Single Sign On, Reverse Proxy, Docker Contai KI-generiert

Wer interne Dienste – etwa Home Assistant, Nextcloud oder ein Firmen-Dashboard – sicher von außen erreichbar machen will, steht vor einer bekannten Herausforderung: Portweiterleitung am Router öffnet Angriffsfläche, Cloudflare Tunnel ist komfortabel aber proprietär. Pangolin löst dieses Problem als vollständig selbstgehostete Alternative: Der Identity-aware Reverse Proxy verbindet einen öffentlichen VPS mit internen Servern hinter NAT über WireGuard-Tunnel – ohne eine einzige Portfreigabe am Heimrouter. Das Ergebnis ist ein zentrales Zugangssystem mit Web-Dashboard, rollenbasierter Zugriffskontrolle (RBAC) und automatischem Let's-Encrypt-TLS. Mit Version 1.19.1, 21.100+ GitHub-Stars und 78 Releases (Stand Juni 2026) ist das Projekt von Fossorial produktionsreif und wird aktiv weiterentwickelt.

Voraussetzungen

  1. VPS oder Cloud-Server mit öffentlicher IPv4-Adresse und Linux (Ubuntu 22.04 oder 24.04 empfohlen)
  2. Docker Engine 24+ und Docker Compose v2 installiert – falls nicht vorhanden, folge der Anleitung Docker und Docker Compose auf Linux installieren
  3. Eigene Domain mit Zugriff auf die DNS-Einstellungen (A-Record auf Server-IP gesetzt)
  4. Ports offen in der VPS-Firewall: 80/tcp, 443/tcp, 51820/udp, 21820/udp
  5. Mindestens 512 MB RAM (empfohlen: 1 GB+), 1 vCPU, 5 GB freier Speicher
  6. Interner Host für den Newt-Client (Heimserver, NAS, Raspberry Pi o. ä.)
  7. openssl und curl auf dem VPS verfügbar

Schritt 1: Projektordner und Verzeichnisstruktur anlegen

Pangolin erwartet eine feste Verzeichnisstruktur unterhalb des Projektordners. Lege alle benötigten Ordner vorab an – fehlende Verzeichnisse führen sonst beim Start zu Berechtigungsfehlern.

mkdir -p /opt/pangolin/config/db
mkdir -p /opt/pangolin/config/letsencrypt
mkdir -p /opt/pangolin/config/traefik/logs
cd /opt/pangolin

Die vollständige Verzeichnisstruktur sieht danach so aus:

/opt/pangolin/
├── compose.yaml
├── config/
│   ├── config.yml          # Pangolin-Hauptkonfiguration (noch anzulegen)
│   ├── db/                 # SQLite-Datenbank (automatisch erstellt)
│   ├── letsencrypt/        # ACME-Zertifikate (automatisch befüllt)
│   └── traefik/
│       ├── logs/           # Traefik Access-/Error-Logs
│       ├── traefik_config.yml   # Traefik statische Konfiguration
│       └── dynamic_config.yml  # Traefik dynamische Routen

Verifizieren: Prüfe die Ordnerstruktur mit find /opt/pangolin -type d. Alle Verzeichnisse aus der obigen Liste müssen vorhanden sein.

Schritt 2: Server-Secret generieren und config.yml anlegen

Pangolin verwendet keine klassischen Docker-Umgebungsvariablen für die Hauptkonfiguration. Alle Einstellungen stehen in config/config.yml. Das wichtigste Pflichtfeld ist server.secret – ein zufälliger Schlüssel, der alle Sessions absichert. Erzeuge ihn einmalig und ändere ihn danach nie wieder:

openssl rand -hex 32

Notiere die Ausgabe (z. B. a3f8...) und trage sie in die folgende Konfigurationsdatei ein. Ersetze dabei alle Vorkommen von pangolin.example.com und example.com durch deine tatsächliche Domain sowie admin@example.com durch deine E-Mail-Adresse:

# /opt/pangolin/config/config.yml
app:
  dashboard_url: "https://pangolin.example.com"
  log_level: "info"

server:
  secret: "HIER-openssl-rand-hex-32-Ausgabe-einfuegen"
  internal_hostname: "pangolin"
  session_cookie_name: "p_session_token"
  trust_proxy: 1
  cors:
    origins: ["https://pangolin.example.com"]

gerbil:
  base_endpoint: "pangolin.example.com"
  start_port: 51820
  clients_start_port: 21820

domains:
  domain1:
    base_domain: "example.com"
    cert_resolver: "letsencrypt"

flags:
  require_email_verification: false
  disable_signup_without_invite: false
  allow_raw_resources: true

Wichtig: YAML verwendet ausschließlich Leerzeichen zur Einrückung, niemals Tabs. Die dashboard_url muss exakt mit dem Hostnamen übereinstimmen, über den du das Dashboard aufrufst – kein abschließender Schrägstrich.

Verifizieren: Prüfe die YAML-Syntax mit python3 -c "import yaml; yaml.safe_load(open('config/config.yml'))" && echo "YAML OK". Ausgabe muss YAML OK lauten.

Schritt 3: Traefik-Konfiguration anlegen

Traefik benötigt zwei Dateien: eine statische Hauptkonfiguration und eine dynamische Routen-Konfiguration. Die statische Konfiguration definiert Entry Points und den ACME-Resolver für Let's Encrypt:

# /opt/pangolin/config/traefik/traefik_config.yml
api:
  dashboard: true
  insecure: true

entryPoints:
  web:
    address: ":80"
  websecure:
    address: ":443"

providers:
  file:
    filename: /etc/traefik/dynamic_config.yml

certificatesResolvers:
  letsencrypt:
    acme:
      email: admin@example.com
      storage: /letsencrypt/acme.json
      httpChallenge:
        entryPoint: web

log:
  filePath: /var/log/traefik/traefik.log
  level: INFO

accessLog:
  filePath: /var/log/traefik/access.log

Die dynamische Konfiguration legt die Route zum Pangolin-Dashboard an:

# /opt/pangolin/config/traefik/dynamic_config.yml
http:
  routers:
    pangolin:
      entryPoints: ["websecure"]
      rule: "Host(`pangolin.example.com`)"
      service: pangolin
      tls:
        certResolver: letsencrypt

  services:
    pangolin:
      loadBalancer:
        servers:
          - url: "http://pangolin:3000"

Verifizieren: Beide Dateien müssen vorhanden sein: ls -la /opt/pangolin/config/traefik/ zeigt traefik_config.yml, dynamic_config.yml und das Unterverzeichnis logs/.

Schritt 4: compose.yaml anlegen

Der Stack besteht aus drei eng verzahnten Containern. Traefik teilt den Netzwerk-Namespace mit Gerbil über network_mode: service:gerbil – dadurch läuft der gesamte externe HTTPS-Traffic durch den WireGuard-Container. Gerbil wiederum startet erst, wenn Pangolin gesund ist (condition: service_healthy). Diese Abhängigkeitskette ist kritisch; ohne sie kommt es zu Race Conditions beim Start.

# /opt/pangolin/compose.yaml
services:
  pangolin:
    image: fosrl/pangolin:latest
    container_name: pangolin
    restart: unless-stopped
    volumes:
      - ./config:/app/config
    healthcheck:
      test: ["CMD", "curl", "-f", "http://localhost:3001/api/v1/"]
      interval: 3s
      retries: 5
      start_period: 20s
      timeout: 5s
    deploy:
      resources:
        limits:
          memory: 1g
        reservations:
          memory: 256m
    networks:
      - pangolin

  gerbil:
    image: fosrl/gerbil:latest
    container_name: gerbil
    restart: unless-stopped
    depends_on:
      pangolin:
        condition: service_healthy
    command:
      - --reachableAt=http://pangolin:3001
      - --generateAndSaveKeyTo=/var/config/key
      - --remoteConfig=http://pangolin:3001/api/v1/gerbil/get-config
    volumes:
      - ./config/:/var/config
    ports:
      - "51820:51820/udp"
      - "21820:21820/udp"
      - "443:443"
      - "80:80"
    cap_add:
      - NET_ADMIN
      - SYS_MODULE
    networks:
      - pangolin

  traefik:
    image: traefik:v3.6
    container_name: traefik
    restart: unless-stopped
    network_mode: service:gerbil
    depends_on:
      gerbil:
        condition: service_started
    volumes:
      - ./config/traefik:/etc/traefik:ro
      - ./config/letsencrypt:/letsencrypt
      - ./config/traefik/logs:/var/log/traefik

networks:
  pangolin:
    driver: bridge
    name: pangolin
    enable_ipv6: true

Beachte: Das Volume ./config/traefik wird mit :ro (read-only) eingebunden, ./config/letsencrypt hingegen ohne :ro – Traefik muss dort die acme.json-Datei schreiben können.

Verifizieren: Prüfe die Compose-Syntax vor dem Start: docker compose config im Projektordner. Bei einem fehlerfreien Ergebnis erscheint die ausgegebene, normalisierte Konfiguration ohne Fehlermeldung.

Schritt 5: Stack starten und Ersteinrichtung abschließen

Starte alle drei Container im Hintergrund:

docker compose up -d

Der Startvorgang dauert etwa 20–40 Sekunden, da Pangolin erst seinen Healthcheck bestehen muss, bevor Gerbil hochfährt. Verfolge den Fortschritt mit:

docker compose ps

Erwartete Ausgabe nach erfolgreichem Start:

NAME        IMAGE                    STATUS
pangolin    fosrl/pangolin:latest    Up (healthy)
gerbil      fosrl/gerbil:latest      Up
traefik     traefik:v3.6             Up

Hole dir jetzt das One-Time-Setup-Token aus den Pangolin-Logs – es erscheint nur einmal beim ersten Start:

docker compose logs pangolin | grep -i token

Rufe anschließend im Browser die Ersteinrichtungs-Seite auf:

https://pangolin.example.com/auth/initial-setup

Trage dort das Token sowie deine gewünschten Admin-Zugangsdaten ein. Nach dem Absenden landest du direkt im Pangolin-Dashboard.

Verifizieren: docker compose ps zeigt alle drei Container mit Status Up, Pangolin zusätzlich mit (healthy). Die URL https://pangolin.example.com öffnet im Browser das Login-Formular mit gültigem HTTPS-Zertifikat von Let's Encrypt.

Schritt 6: Newt-Client auf dem internen Host deployen

Der eigentliche Mehrwert von Pangolin liegt im Newt-Client: ein leichtgewichtiger Container, der auf dem internen Host (Heimserver, NAS, Raspberry Pi) läuft und aktiv eine ausgehende WireGuard-Verbindung zum Pangolin-Server aufbaut. Du musst dafür keinen einzigen Port am Heimrouter freigeben.

Lege im Pangolin-Dashboard zunächst einen neuen Site Connector an: Connectors → New Connector. Notiere die angezeigte Connector ID und das Connector Secret.

Erstelle auf dem internen Host eine compose.yaml für den Newt-Client:

# ~/newt/compose.yaml  (auf dem internen Host)
services:
  newt:
    image: fosrl/newt:latest
    container_name: newt
    restart: unless-stopped
    environment:
      - PANGOLIN_ENDPOINT=https://pangolin.example.com
      - NEWT_ID=deine-connector-id-aus-dem-dashboard
      - NEWT_SECRET=dein-connector-secret-aus-dem-dashboard
    network_mode: host

Starte den Newt-Client auf dem internen Host:

docker compose up -d
docker compose logs -f newt

Im Pangolin-Dashboard sollte der Connector nach wenigen Sekunden als Online erscheinen. Du kannst jetzt im Dashboard Ressourcen anlegen – zum Beispiel einen internen Dienst auf Port 8123 (Home Assistant) – und dem Connector zuweisen.

Verifizieren: Im Pangolin-Dashboard unter Connectors zeigt der neu angelegte Connector den Status Online. Die Logs des Newt-Containers (docker compose logs newt) enthalten keine Fehlermeldungen wie connection refused oder timeout.

Schritt 7: Updates und Backups

Für Updates aller drei Container genügt der übliche Compose-Workflow. Eine regelmäßige Backup-Routine einzurichten ist Pflicht – alle persistenten Daten liegen im ./config-Verzeichnis.

# Update (im Projektordner /opt/pangolin)
docker compose pull
docker compose up -d

# Logs im Fehlerfall prüfen
docker compose logs -f

# Backup: gesamtes config-Verzeichnis sichern
tar -czf pangolin-backup-$(date +%Y%m%d).tar.gz /opt/pangolin/config

Ändere server.secret in der config.yml niemals nach dem ersten Start – alle aktiven Sessions werden sonst invalidiert. Eine Backup-Strategie für das config-Verzeichnis findest du in der Anleitung 3-2-1-Backup-Strategie umsetzen.

Verifizieren: Nach docker compose pull && docker compose up -d zeigt docker compose ps alle Container mit aktualisierten Image-IDs und Status Up (healthy) für Pangolin.

Eckdaten auf einen Blick

EigenschaftWert
Image (empfohlen)fosrl/pangolin:latest (SQLite, Community Edition)
Variantenlatest, postgresql-latest, ee-latest, ee-postgresql-latest
Aktuelle Version1.19.1 (Juni 2026)
LizenzAGPL-3.0 (CE kostenlos bis 100 k USD Jahresumsatz)
Architekturamd64, arm64
RAM (min/empfohlen)512 MB / 1 GB+
PortProtokollFunktionExtern?
80tcpHTTP-Eingang (HTTPS-Redirect)ja
443tcpHTTPS/TLS (Traefik)ja
51820udpWireGuard Site-Connectorja
21820udpNewt-Client Relay/Hole-Punchja
3000–3003tcpPangolin intern (nie am Host exponieren)nein
Volume (Host)Container-PfadInhalt
./config/app/configSQLite-DB, config.yml, Logs (Pangolin)
./config//var/configWireGuard-Schlüssel (Gerbil)
./config/traefik/etc/traefik:roTraefik-Konfiguration (read-only)
./config/letsencrypt/letsencryptACME-Zertifikate (schreibbar!)
./config/traefik/logs/var/log/traefikAccess- und Error-Logs

Troubleshooting / Typische Fehler

  1. „failed to create wireguard interface" – Gerbil fehlen die Linux-Capabilities. Prüfe, ob cap_add: [NET_ADMIN, SYS_MODULE] in der compose.yaml vorhanden ist. Auf manchen Cloud-VMs (z. B. OpenVZ-Basis) muss das WireGuard-Kernelmodul zusätzlich auf dem Host geladen sein: modprobe wireguard.
  2. „failed to parse config" in den Pangolin-Logsconfig.yml enthält einen YAML-Syntaxfehler, häufig durch Tabs statt Leerzeichen. Validiere mit python3 -c "import yaml; yaml.safe_load(open('config/config.yml'))".
  3. HTTPS-Verbindungen schlagen fehl / kein Zertifikat – Traefik ist nicht über network_mode: service:gerbil mit Gerbil verbunden. Prüfe die compose.yaml. Außerdem muss Port 80/tcp für die HTTP-Challenge offen sein.
  4. CORS-Fehler im Browserapp.dashboard_url in config.yml stimmt nicht exakt mit dem aufgerufenen Hostnamen überein. Kein abschließender Schrägstrich, korrekte Domain eintragen, Container neu starten.
  5. One-Time-Setup-Token nicht mehr in den Logs – Das Token erscheint nur einmal beim ersten Start. Lösung: docker compose down && docker compose up -d, danach sofort docker compose logs pangolin | grep -i token ausführen.
  6. Newt-Client meldet „connection timeout" – Port 51820/udp oder 21820/udp ist in der VPS-Firewall (UFW, AWS Security Group, Hetzner Firewall) nicht freigegeben. UDP-Ports werden von Firewalls oft vergessen. Prüfe: ufw status bzw. die Cloud-Konsole.
  7. Traefik kann acme.json nicht schreiben – Das Volume ./config/letsencrypt wurde versehentlich mit :ro gemountet. Entferne das Flag und starte Traefik neu.
  8. Gerbil startet, meldet aber „connection refused" – Pangolin war beim Gerbil-Start noch nicht gesund. Stelle sicher, dass der Healthcheck korrekt konfiguriert ist und depends_on.pangolin.condition: service_healthy gesetzt ist.

Häufige Fragen

Brauche ich wirklich eine eigene Domain?

Ja, zwingend. Let's Encrypt stellt keine TLS-Zertifikate für IP-Adressen aus, und Browser-Cookies sowie CORS-Prüfungen setzen einen Hostnamen voraus. Du benötigst mindestens einen A-Record, der auf die öffentliche IP deines VPS zeigt. Setze den DNS-Eintrag, warte bis die TTL abgelaufen ist, und starte Pangolin erst dann.

Funktioniert Pangolin ohne Portweiterleitung am Heimrouter?

Ja – das ist der eigentliche Hauptanwendungsfall. Der Newt-Client auf dem internen Host baut eine ausgehende WireGuard-Verbindung zum öffentlichen Pangolin-Server auf. Am Heimrouter oder in der Firewall des internen Netzes muss kein Port geöffnet werden.

Welche Image-Variante soll ich nehmen?

fosrl/pangolin:latest (SQLite, Community Edition) ist für den Einstieg richtig. SQLite reicht für die überwiegende Mehrheit der Self-Hosting-Szenarien. Die PostgreSQL-Variante lohnt sich nur, wenn bereits PostgreSQL-Infrastruktur vorhanden ist oder sehr hohes Traffic-Aufkommen erwartet wird. Die Enterprise Edition (ee-*) ist für Unternehmen mit kommerziellem Support gedacht.

Wie verbinde ich einen internen Dienst, z. B. Home Assistant auf Port 8123?

Deploye den Newt-Client auf dem internen Host (Schritt 6). Lege dann im Pangolin-Dashboard unter Resources → New Resource einen Eintrag mit Zielhost localhost:8123 an und weise ihn dem Connector zu. Pangolin erstellt automatisch eine Subdomain und beschafft ein TLS-Zertifikat – kein Port am Router nötig.

Kann ich Pangolin neben einer bestehenden Traefik-Instanz betreiben?

Ja, aber mit Vorsicht: Pangolin bringt eine eigene Traefik-Instanz mit. Entweder du nutzt Pangolin als einzigen Entry Point und konfigurierst alle Dienste als Pangolin-Ressourcen, oder du lässt Pangolin auf alternativen Ports (z. B. 8443/tcp statt 443) laufen und schaltest deinen vorhandenen Reverse Proxy davor. Wie du Traefik generell als Docker-Reverse-Proxy einsetzt, zeigt die Anleitung Traefik als Docker-Reverse-Proxy mit automatischem HTTPS.

Ist Pangolin produktionsreif?

Mit Version 1.19.1, 78 Releases und aktiver Entwicklung durch Fossorial: ja. Die Community Edition unter AGPL-3.0 ist kostenlos für Privatnutzer und Unternehmen unter 100.000 USD Jahresumsatz. Für kritische Umgebungen empfiehlt sich die PostgreSQL-Variante und ein regelmäßiges Backup des gesamten ./config-Verzeichnisses.

Was passiert, wenn ich server.secret ändere?

Alle aktiven Sessions werden sofort invalidiert – alle eingeloggten Benutzer werden ausgeloggt, und Ressourcen-Zugriffstoken verlieren ihre Gültigkeit. Das Secret darf nach dem ersten Start unter keinen Umständen geändert werden. Sichere es zusammen mit dem Backup des config-Verzeichnisses an einem sicheren Ort.

Fazit

Pangolin schließt eine echte Lücke im Self-Hosting-Ökosystem: Es liefert das, was Cloudflare Tunnel in der kostenlosen Stufe bietet – sicherer externer Zugriff ohne Portfreigabe – als vollständig selbstgehostete, AGPL-lizenzierte Lösung. Der Dreier-Stack aus Pangolin, Gerbil und Traefik ist nach einmaligem Einrichten wartungsarm, und der Newt-Client macht den Anschluss interner Dienste zur Sache von wenigen Minuten. Der einzige nicht verhandelbare Einstiegspreis: ein öffentlicher VPS und eine eigene Domain. Wer beides hat, bekommt mit Pangolin ein professionelles Zero-Trust-Zugangssystem für den eigenen Stack – inklusive RBAC, Einladungssystem und automatischem TLS. Wie du deinen VPS dabei grundsätzlich absicherst, erklärt die Anleitung VPS absichern und härten: UFW, SSH-Keys und Fail2Ban.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian): die Self-Hosting-Grundlage
  2. Traefik als Docker-Reverse-Proxy mit automatischem HTTPS einrichten
  3. VPS absichern und härten: UFW, SSH-Keys und Fail2Ban
  4. 3-2-1-Backup-Strategie umsetzen
  5. WireGuard-VPN für Homeoffice und Standortvernetzung einrichten
  6. Headscale selbst hosten: Tailscale-Mesh-VPN ohne Cloud-Abhängigkeit für KMU

Offizielle Dokumentation und Quellen: Pangolin Docs – Docker Compose Setup · GitHub: fosrl/pangolin · Docker Hub: fosrl/pangolin