Files
Bruchtal/docs/docker/portainer/portainer.md

7.4 KiB

Portainer EE mit Remote-Agent (Hetzner) über SSH-Tunnel

Ziel

Lokaler Portainer EE verwaltet zusätzlich einen entfernten Docker-Host (Hetzner), ohne dass der Agent-Port (9001) öffentlich erreichbar ist. Der Key für die EE ist in Bitwarden hinterlegt.

Die Verbindung erfolgt ausschließlich über einen SSH-Tunnel.


Architektur

Übersicht

  • Heimserver: Portainer EE
  • Hetzner-Server: Portainer Agent
  • Verbindung: SSH-Tunnel (autossh + systemd)
  • Kein öffentlicher Port 9001

Netzwerkarchitektur mit Namespace- und Layer-Trennung

                                ┌────────────────────────────┐
                                │         Internet           │
                                └──────────────┬─────────────┘
                                               │
                                               │ SSH (TCP 22)
                                               │
                    ┌──────────────────────────┴──────────────────────────┐
                    │                Hetzner VPS (Host OS)                │
                    │------------------------------------------------------│
                    │                                                      │
                    │   Docker Engine                                      │
                    │   ┌──────────────────────────────────────────────┐   │
                    │   │ portainer_agent Container                    │   │
                    │   │----------------------------------------------│   │
                    │   │ Agent lauscht auf: 0.0.0.0:9001              │   │
                    │   └──────────────────────────────────────────────┘   │
                    │                                                      │
                    │   Host-Port-Mapping: 9001 -> Container 9001         │
                    └──────────────────────────┬───────────────────────────┘
                                               │
                                               │ localhost:9001
============================================== SSH Tunnel ==============================================
ssh -L 0.0.0.0:9002:localhost:9001 root@hetzner-ip
=========================================================================================================
                                               │
                                               │ 0.0.0.0:9002 (Heimserver Host)
                    ┌──────────────────────────┴──────────────────────────┐
                    │                Heimserver (Host OS)                 │
                    │------------------------------------------------------│
                    │                                                      │
                    │ autossh Service                                      │
                    │ lauscht auf: 0.0.0.0:9002                            │
                    │                                                      │
                    │ Docker Bridge Netzwerk                               │
                    │ IP: 172.17.0.1                                       │
                    │                                                      │
                    │   Docker Engine                                      │
                    │   ┌──────────────────────────────────────────────┐   │
                    │   │ portainer-ee Container                       │   │
                    │   │----------------------------------------------│   │
                    │   │ Verbindet zu: 172.17.0.1:9002                │   │
                    │   │ (Host-Bridge-IP)                             │   │
                    │   └──────────────────────────────────────────────┘   │
                    │                                                      │
                    └──────────────────────────────────────────────────────┘

Funktionsweise

  1. Der Portainer-Agent läuft auf Hetzner und lauscht auf Port 9001.
  2. Dieser Port ist nicht öffentlich relevant, da keine direkte Nutzung erfolgt.
  3. Der Heimserver baut per SSH einen Tunnel auf:
    • Lokaler Port 9002 → Hetzner localhost:9001
  4. Portainer EE verbindet sich intern über: 172.17.0.1:9002 (docker bridge)
  5. Der gesamte Traffic läuft verschlüsselt über SSH.

1. Portainer-Agent auf Hetzner

docker-compose.yml

version: "3.8"

services:
portainer_agent:
 image: portainer/agent:2.27.3
 container_name: portainer_agent
 restart: unless-stopped
 ports:
   - "9001:9001"
 volumes:
   - /var/run/docker.sock:/var/run/docker.sock
   - /var/lib/docker/volumes:/var/lib/docker/volumes

Starten: docker compose up -d Prüfen: ss -tlnp | grep 9001 Erwartet: 0.0.0.0:9001

2. SSH-Tunnel automatisieren (Heimserver)

autossh installieren

apt update apt install autossh -y

systemd Service anlegen

Datei: /etc/systemd/system/portainer-hetzner-tunnel.service

Inhalt:

[Unit]
Description=SSH Tunnel to Hetzner Portainer Agent
After=network.target

[Service]
User=root
Environment="AUTOSSH_GATETIME=0"
ExecStart=/usr/bin/autossh \
  -M 0 \
  -N \
  -o "ServerAliveInterval=30" \
  -o "ServerAliveCountMax=3" \
  -o "ExitOnForwardFailure=yes" \
  -o "StrictHostKeyChecking=no" \
  -i /root/.ssh/portainer_tunnel \
  -L 0.0.0.0:9002:localhost:9001 \
  root@65.

Restart=always
RestartSec=5

[Install]
WantedBy=multi-user.target

Service aktivieren

systemctl daemon-reload
systemctl enable portainer-hetzner-tunnel
systemctl start portainer-hetzner-tunnel

Status prüfen:

systemctl status portainer-hetzner-tunnel

Port prüfen:

ss -tlnp | grep 9002

Erwartet:

0.0.0.0:9002

3. Portainer EE konfigurieren

In der WebUI: Environments → Add Environment → Agent Adresse: 172.17.0.1:9002 Hinweis: 172.17.0.1 ist die Docker-Bridge-IP des Hosts Portainer läuft im Container Der Tunnel läuft auf dem Host

Sicherheitsmodell

  • Port 9001 nicht öffentlich erreichbar
  • Kommunikation ausschließlich über SSH
  • SSH-Key-basierte Authentifizierung
  • Automatischer Reconnect via autossh
  • Kein zusätzlicher VPN erforderlich

Troubleshooting

|Problem |Ursache | Prüfen |connection refused |Agent nicht auf 9001 gemappt | - ports9001:9001 in der docker-compose |SSH channel open failed |Agent lauscht nicht |keys vorhanden? |Endpoint unreachable |Tunnel nicht aktiv |curl localhost:9001 schlägt fehl |Agent läuft nicht korrekt