JDownloader über Tor mit Portainer: Stack mit gesperrtem Direktzugang
JDownloader 2 und Tor als Portainer-Stack: JDownloader läuft in einem internen Netz ohne Internetzugang, nutzt nur den Tor-SOCKS5-Proxy und wird per Leak-Test aus JDownloader heraus geprüft.
Geprüft am 30.09.2026 · für jdownloader-2 26.09.1, tor 0.4.9.13
WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Mit Portainer verwalten Sie Docker-Stacks im Browser. Für JDownloader 2 über Tor reicht es aber nicht, einen Tor-Container in denselben Stack zu legen: Hat JDownloader selbst Internetzugang, laufen Verbindungen am Proxy vorbei, sobald ein Eintrag fehlt oder zurückgesetzt wird. Diese Anleitung zeigt einen Portainer-Stack, in dem JDownloader in einem internen Docker-Netz ohne Internetzugang läuft und nur über den Tor-SOCKS5-Proxy kommunizieren kann. Die Prüfungen erledigen Sie weitgehend in Portainer selbst, über Logs und die Container-Konsole.
Voraussetzungen
- Linux-Server oder VPS mit Docker Engine, x86_64 oder ARM64, 2 CPU-Kerne und 4 GB RAM; JDownloader erhält im Beispiel höchstens 1 GB Java-Heap
- etwa 1 GB Speicher für Images und Konfiguration plus Platz für Downloads
- Portainer CE oder BE mit Zugriff auf eine Docker-Standalone-Umgebung (Stand der Doku: Portainer 2.45 LTS); Einrichtung auf der Synology siehe Portainer auf Synology NAS installieren
- SSH-Zugang zum Server, um einmalig Ordner und eine Konfigurationsdatei anzulegen und später einen Tunnel für die Weboberfläche zu öffnen
- Grundlagen zu Docker, siehe Docker-Installation
Eckdaten
| Dienst | Image und Tag | Ports | Volumes | Netze |
|---|---|---|---|---|
| tor | dockurr/tor:0.4.9.13 | keine veröffentlicht (intern 9050 SOCKS5) | /opt/jdownloader-tor/tor-data | intern, extern |
| jdownloader | jlesage/jdownloader-2:v26.09.1 | keine veröffentlicht (intern 5800) | /opt/jdownloader-tor/config, /opt/jdownloader-tor/downloads | nur intern |
| gui | nginx:1.30-alpine | 127.0.0.1:5800 | /opt/jdownloader-tor/gui.conf | intern, frontend |
Portainer legt keine Hilfsdateien neben einem Stack aus dem Web-Editor ab. Deshalb nutzt der Stack absolute Pfade unter /opt/jdownloader-tor. Das früher übliche Image dperson/torproxy erhielt seit April 2021 keine Builds mehr; dockurr/tor wurde zuletzt am 24.09.2026 gebaut.
Schritt 1: Ordner und Nginx-Datei auf dem Host
Diesen Schritt erledigen Sie einmalig per SSH, weil Portainer weder Ordner noch Dateien auf dem Host anlegt.
sudo mkdir -p /opt/jdownloader-tor/{config,downloads,tor-data}
sudo chown -R $(id -u):$(id -g) /opt/jdownloader-tor/config /opt/jdownloader-tor/downloads
id -u; id -g
Legen Sie dann /opt/jdownloader-tor/gui.conf an. Die Konfiguration folgt dem Reverse-Proxy-Beispiel aus der Image-Dokumentation und reicht WebSockets durch:
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}
server {
listen 8080;
location / {
proxy_pass http://jdownloader:5800;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $connection_upgrade;
proxy_buffering off;
proxy_read_timeout 86400s;
proxy_send_timeout 86400s;
}
}
Verifizieren: ls /opt/jdownloader-tor zeigt config downloads gui.conf tor-data. Notieren Sie die Ausgabe von id -u und id -g, typischerweise 1000.
Schritt 2: Stack im Web-Editor anlegen
Wählen Sie in Portainer die Umgebung, dann Stacks, Add stack, Name jdownloader-tor und Web editor. Fügen Sie ein:
services:
tor:
image: dockurr/tor:0.4.9.13
restart: unless-stopped
networks: [intern, extern]
volumes:
- /opt/jdownloader-tor/tor-data:/var/lib/tor
jdownloader:
image: jlesage/jdownloader-2:v26.09.1
restart: unless-stopped
depends_on: [tor]
networks: [intern] # kein Internet, nur Tor erreichbar
environment:
USER_ID: ${JD_UID}
GROUP_ID: ${JD_GID}
TZ: Europe/Berlin
JDOWNLOADER_MAX_MEM: 1G
volumes:
- /opt/jdownloader-tor/config:/config
- /opt/jdownloader-tor/downloads:/output
gui:
image: nginx:1.30-alpine
restart: unless-stopped
depends_on: [jdownloader]
networks: [intern, frontend]
ports:
- "127.0.0.1:5800:8080" # nur lokal, Zugriff per SSH-Tunnel
volumes:
- /opt/jdownloader-tor/gui.conf:/etc/nginx/conf.d/default.conf:ro
networks:
intern:
internal: true
extern:
frontend:
Unter Environment variables legen Sie JD_UID und JD_GID mit den Werten aus Schritt 1 an. Portainer ersetzt die Platzhalter beim Deployment, die Compose-Definition bleibt unverändert. So passen Sie die IDs später ohne Eingriff in den YAML-Text an.
Der Nginx-Dienst ist nötig, weil Docker keine Ports eines Containers veröffentlicht, der nur in einem internen Netz hängt. Im Test blieb ein ports:-Eintrag direkt bei JDownloader wirkungslos.
Verifizieren: Nach Deploy the stack erscheint jdownloader-tor in der Stack-Liste ohne Fehlermeldung, und die Stack-Ansicht listet drei Container mit Status running.
Schritt 3: Tor in Portainer prüfen
Öffnen Sie in der Stack-Ansicht beim Tor-Container die Logs. Tor braucht beim ersten Start etwa eine Minute. Der eingebaute Healthcheck meldet danach healthy, im Test nach gut zwei Minuten.
Öffnen Sie anschließend beim JDownloader-Container die Console, verbinden Sie sich mit /bin/sh und führen Sie aus:
curl -s -x socks5h://tor:9050 https://check.torproject.org/api/ip
Verifizieren: Das Tor-Log enthält Bootstrapped 100% (done): Done, der Container zeigt healthy, und der Befehl liefert {"IsTor":true,"IP":"…"}. Dieser Test prüft nur Tor, noch nicht JDownloader.
Schritt 4: Negativtest ohne Proxy
In derselben Konsole prüfen Sie, dass JDownloader ohne Proxy nichts erreicht:
curl -sS -m 10 https://check.torproject.org/api/ip
In Portainer sehen Sie unter Networks das Netz jdownloader-tor_intern. Auf dem Host prüfen Sie zusätzlich die offenen Ports:
docker network inspect jdownloader-tor_intern --format '{{.Internal}}'
ss -ltn | grep -E ':5800|:9050|:8118'
Verifizieren: Der curl-Aufruf scheitert mit curl: (6) Could not resolve host: check.torproject.org (DNS server returned general failure), docker network inspect gibt true aus, und ss zeigt nur 127.0.0.1:5800. SOCKS-Port 9050 und HTTP-Tunnel 8118 sind nicht veröffentlicht.
Schritt 5: Proxy im Verbindungsmanager
Öffnen Sie einen SSH-Tunnel und danach http://127.0.0.1:5800 im Browser:
ssh -N -L 5800:127.0.0.1:5800 benutzer@ihr-server
JDownloader startet und scheitert zunächst an Updates, weil kein direkter Weg ins Internet existiert. Tragen Sie den Proxy ein, wie es der JDownloader-Support beschreibt:
- Settings, links Connection Manager.
- Add, im Dialog „Add new Proxy“ bei Type
Socks5wählen. - Host/Port:
torund9050, Benutzer und Passwort leer, Ok. - Den Haken bei No Proxy entfernen.
tor ist der Dienstname aus dem Stack. Zielnamen löst JDownloader in diesem Aufbau nicht selbst auf, sondern übergibt sie an Tor; im Test stand im Log SEND tcp connect request to:check.torproject.org:443 by domain.
Verifizieren: Die Tabelle zeigt eine aktive Zeile Socks 5 Proxy | tor | 9050, „No Proxy“ ist aus. Nach einem Neustart des Containers in Portainer liefert grep -rh "via \[" /opt/jdownloader-tor/config/logs | tail -3 Zeilen mit via [tor:9050 (Socks5 Proxy)].
Schritt 6: Leak-Test mit JDownloader
Erst ein Test mit JDownloaders eigenem HTTP-Client zeigt, welchen Weg die Anwendung wählt. Damit Anfrage und Antwort im Log stehen, aktivieren Sie vorübergehend das Debug-Logging. Stoppen Sie dazu den JDownloader-Container in Portainer, weil JDownloader seine Einstellungen beim Beenden überschreibt, und führen Sie auf dem Host aus:
sed -i -E 's/"debugmodeenabled" ?: ?false/"debugmodeenabled":true/' /opt/jdownloader-tor/config/cfg/org.appwork.utils.logging2.LogConfig.json
Starten Sie den Container, öffnen Sie im Tab LinkGrabber den Dialog Add New Links und fügen Sie directhttp://https://check.torproject.org/api/ip ein. Nach Continue erscheint der Eintrag als offline, weil die Antwort keine Datei ist. Entscheidend ist das Log:
grep -rh '"IsTor"' /opt/jdownloader-tor/config/logs/ | tail -1
Verifizieren: Die Ausgabe lautet {"IsTor":true,"IP":"…"} mit der IP eines Tor-Exit-Knotens. Setzen Sie danach debugmodeenabled wieder auf false, sonst wachsen die Logs schnell.
Schritt 7: Stack aktualisieren
JDownloader aktualisiert sich im Container selbst, im Test ebenfalls über Tor. Für neue Image-Versionen ändern Sie in Portainer unter Stacks, jdownloader-tor, Editor die Tags und bestätigen mit Update the stack. Weil die Tags festgeschrieben sind, zieht Docker bei einem geänderten Tag das neue Image. Über Version im Editor kehren Sie bei Bedarf zu einer früheren Fassung der Stack-Datei zurück. Die Proxy-Liste liegt in /opt/jdownloader-tor/config und übersteht das Neuerstellen.
Verifizieren: Die Stack-Ansicht zeigt die neuen Tags, alle drei Container laufen, und der Leak-Test aus Schritt 6 liefert weiterhin "IsTor":true.
Typische Fehler
- Deploy scheitert beim Einbinden von
gui.conf: Die Datei fehlt auf dem Host. Laut Docker-Dokumentation legt Docker für einen fehlenden Bind-Mount-Pfad immer ein Verzeichnis an, eine Datei lässt sich darüber nicht einbinden. Entfernen Sie das entstandene Verzeichnis, legen Sie die Datei aus Schritt 1 an und deployen Sie neu. - Weboberfläche liefert keine Antwort: Der Port wurde bei JDownloader statt bei
guieingetragen. Portainer zeigt dann bei JDownloader5800/tcpohne Host-Zuordnung. - Log zeigt
UnknownHostException: Could not resolve: -update.jdownloader.org<->update.jdownloader.org-: JDownloader versucht den Direktweg. Das zeigt, dass die Sperre wirkt; Proxy aus Schritt 5 eintragen. ${JD_UID}bleibt leer: Die Variable fehlt unter Environment variables des Stacks. Compose meldet dannThe "JD_UID" variable is not set. Defaulting to a blank string., und der Container erhält einen leeren Wert. Legen Sie die Variablen an und aktualisieren Sie den Stack.- Proxy-Eintrag verschwindet: Die JSON-Datei wurde bei laufendem Container bearbeitet. Immer erst stoppen.
Häufige Fragen
Bin ich damit anonym?
Nicht automatisch. Laut Tor Project verhindert Tor, dass Zielserver Ihren Standort und Ihr Provider Ihre Ziele erfahren. Ein Login bei einem Hoster identifiziert Sie trotzdem, und der Exit-Knoten sieht unverschlüsselte HTTP-Inhalte. Zwischen JDownloader und dem Tor-Container läuft der Verkehr unverschlüsselt; die Anonymität beginnt laut Tor Project erst am Tor-Knoten.
Kann ich den Stack aus Git deployen?
Ja. Portainer kann eine Compose-Datei aus einem Git-Repository laden. Die Ordner und gui.conf auf dem Host brauchen Sie trotzdem, solange Sie absolute Pfade verwenden.
Warum nicht einfach JAVA_TOOL_OPTIONS setzen?
Dass JDownloader Java-Proxy-Eigenschaften für alle eigenen Verbindungen nutzt, ist nicht dokumentiert. Der Verbindungsmanager ist der vom Hersteller beschriebene Weg, und das interne Netz verhindert ohnehin jeden Direktweg.
Reicht Portainers Zugriffskontrolle für die Oberfläche?
Nein. Portainer schützt nur die Verwaltung. Die JDownloader-Oberfläche hat ohne weitere Einstellungen keine Anmeldung und ist hier nur über 127.0.0.1 und SSH-Tunnel erreichbar. Das Image bietet zusätzlich WEB_AUTHENTICATION, das SECURE_CONNECTION=1 voraussetzt.
Fazit
Portainer macht den Stack bequem verwaltbar, die Sicherheit kommt aus dem internen Netz: JDownloader erreicht nur Tor oder gar nichts. Prüfen Sie nach jedem Update mit dem Leak-Test aus JDownloader, nicht nur mit curl im Tor-Container.
Weiterführende Anleitungen und Quellen
- JDownloader über Tor auf Linux mit Docker Compose
- JDownloader über Tor auf der Synology mit Container Manager
- Portainer Docs: Add a new stack
- Portainer Docs: Inspect or edit a stack
- jlesage/docker-jdownloader-2
- dockur/tor
- JDownloader Support: VPN/Proxy mit JDownloader
- Tor Project: Welche Schutzwirkung Tor bietet


