Zum Hauptinhalt springen

Einen 24/7 aria2-Download-Server mit Docker betreiben

Ein vollständiges, korrektes Deployment, das Sie vollständig kontrollieren: eine aria2-Engine in einem kleinen Alpine-Container, eine saubere aria2.conf, optionales AriaNg-WebUI, sicherer Fernzugriff, Auto-Hooks nach dem Download und Health-Checks. Läuft auf jedem Linux-Host, Synology, QNAP, Unraid oder VPS.

Zuletzt geprüft im September 2026 · aria2 v1.37.0 · Docker Engine 24+ / Compose v2

Voraussetzungen

Warum Docker und was wir bauen

aria2 in einem Container zu betreiben gibt Ihnen einen isolierten, reproduzierbaren, dauerhaft laufenden Downloader, den Sie aktualisieren oder verschieben können, ohne den Host anzufassen. Der Stack besteht aus drei unabhängigen Teilen:

1. Engine (aria2c)

Der Multi-Protokoll-Downloader, der eine eingebundene aria2.conf liest und JSON-RPC auf Port 6800 bereitstellt.

2. WebUI (optional)

AriaNg oder das Online-WebUI spricht per RPC mit der Engine. Vollständig austauschbar.

3. Speicher

Zwei Mounts: /downloads (Nutzlast) und /config (Session, Logs, Hooks) – beide bleiben außerhalb des Containers erhalten.

Wir bauen unser eigenes kleines Image aus alpine. Das hält die Anleitung korrekt und portabel – ohne versteckte Umgebungsvariablen eines fremden Images, das Sie nicht einsehen können. (Community-Images sind eine Alternative als Abkürzung; prüfen Sie deren Variablen anhand ihrer eigenen Dokumentation.)

Die drei Dateien

Erstellen Sie einen Ordner (z. B. /opt/aria2) und legen Sie diese drei Dateien nebeneinander ab.

1. aria2.conf

aria2.conf
dir=/downloads
continue=true
file-allocation=falloc
max-concurrent-downloads=5
max-connection-per-server=16
min-split-size=10M
split=16

# --- RPC (für jedes WebUI erforderlich) ---
enable-rpc=true
rpc-listen-all=true
rpc-listen-port=6800
rpc-secret=CHANGE_ME_STRONG_SECRET
# für Browser-WebUIs nötig; siehe Sicherheitshinweise
rpc-allow-origin-all=true

# --- BitTorrent ---
bt-max-peers=128
# listen ports must match the ports published in docker-compose.yml
listen-port=6888
dht-listen-port=6888
enable-dht=true
enable-peer-exchange=true
bt-enable-lpd=true
seed-ratio=1.0
disk-cache=64M

# --- Session-Persistenz (übersteht Neustarts) ---
save-session=/config/aria2.session
input-file=/config/aria2.session
save-session-interval=60
log=/config/aria2.log

2. Dockerfile

Dockerfile
FROM alpine:3.20
RUN apk add --no-cache aria2 ca-certificates tzdata bash
COPY aria2.conf /etc/aria2/aria2.conf
VOLUME ["/downloads", "/config"]
EXPOSE 6800 6888 6888/udp
# aria2 refuses to start if input-file is missing, so create the session file first
ENTRYPOINT ["sh", "-c", "touch /config/aria2.session && exec aria2c --conf-path=/etc/aria2/aria2.conf"]

3. docker-compose.yml

docker-compose.yml
services:
  aria2:
    build: .
    container_name: aria2
    restart: unless-stopped
    environment:
      - TZ=UTC
    volumes:
      - ./aria2-config:/config
      - ./downloads:/downloads
    ports:
      - "6800:6800"      # JSON-RPC (privat halten!)
      - "6888:6888"      # BitTorrent TCP
      - "6888:6888/udp"  # BitTorrent DHT UDP

Die Engine schreibt aria2.session und aria2.log nach ./aria2-config, sodass beide auf dem Host liegen und Neustarts sowie Image-Rebuilds überstehen.

In 5 Minuten bereitstellen

mkdir -p /opt/aria2/aria2-config /opt/aria2/downloads
cd /opt/aria2
# aria2.conf, Dockerfile und docker-compose.yml hier ablegen

docker compose up -d --build      # einmal bauen, dann starten
docker compose ps                 # prüfen, ob es läuft
docker compose logs -f aria2      # Start beobachten

Bestätigen Sie, dass der RPC-Endpunkt antwortet (Secret ersetzen):

curl -s http://127.0.0.1:6800/jsonrpc \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":"1","method":"aria2.getVersion","params":["token:CHANGE_ME_STRONG_SECRET"]}'

Eine JSON-Antwort mit einem version-Feld bedeutet: Engine und Secret sind korrekt.

Konfigurieren & absichern

Wichtige aria2.conf-Einstellungen in diesem Stack
EinstellungWarum
rpc-secretPflicht. Ohne sie steuert jeder, der Port 6800 erreicht, Ihre Downloads.
rpc-allow-origin-all=trueErlaubt einem Browser-WebUI (AriaNg, das WebUI dieser Seite), den RPC aufzurufen. Nur sicher, weil der Port privat bleibt.
file-allocation=fallocReserviert Speicher schnell und reduziert Fragmentierung (auf Dateisystemen ohne Unterstützung none nutzen).
disk-cache=64MBündelt Schreibvorgänge im RAM – weniger Mikro-Schreibvorgänge, längere Lebensdauer der Platte.
continue=trueTeil-Downloads über Neustarts hinweg fortsetzen.
save-session / input-fileWarteschlange persistieren; Downloads werden nach einem Neustart automatisch fortgesetzt.

Veröffentlichen Sie Port 6800 niemals im Internet. Binden Sie ihn an Host/LAN und erreichen Sie ihn über ein VPN oder einen authentifizierten Reverse-Proxy (siehe unten).

WebUI hinzufügen

Wählen Sie, was zu Ihrem Workflow passt:

  ariang:
    image: nginx:alpine
    container_name: ariang
    restart: unless-stopped
    volumes:
      - ./ariang:/usr/share/nginx/html:ro
    ports:
      - "6880:80"

Stellen Sie in den AriaNg-Einstellungen den RPC-Host auf Ihren Server, Port 6800, und fügen Sie das rpc-secret ein.

NAS & Plattformhinweise

Linux / VPS / Raspberry Pi

Folgen Sie dem 5-Minuten-Deploy. Auf einem Pi halten Sie disk-cache moderat und rechnen mit geringerem Durchsatz.

Synology DSM 7+

Container Manager → Projekt → Erstellen; Compose einfügen. Reale DSM-Pfade für die Mounts verwenden (z. B. /volume1/docker/aria2/config und /volume1/downloads).

QNAP / Unraid

Container Station → Anwendung erstellen oder das Compose-Plugin von Unraid. /config auf einen Appdata-Pfad und /downloads auf eine Freigabe mappen.

Dateieigentümerschaft

Wenn andere Apps (Plex/Jellyfin/Arr) die Dateien lesen müssen, setzen Sie entweder den Container-Benutzer oder chown den Download-Ordner. Unser Alpine-Image läuft standardmäßig als root; fügen Sie user: "1000:1000" zum Dienst hinzu, um Ihre Host-UID/GID zu treffen.

Sicherer Fernzugriff (HTTPS-Reverse-Proxy)

Um das WebUI über das Internet zu erreichen, setzen Sie einen authentifizierten HTTPS-Proxy davor und legen Sie 6800 niemals offen. Moderne Browser blockieren zudem unverschlüsselten RPC von einer HTTPS-Seite (Mixed Content), daher brauchen Sie TLS + WebSocket-Weiterleitung.

Nginx: TLS + WebSocket-RPC + Basic Auth
server {
    listen 443 ssl;
    server_name aria2.example.com;

    ssl_certificate     /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    auth_basic "aria2";
    auth_basic_user_file /etc/nginx/.htpasswd;

    location / {
        proxy_pass http://127.0.0.1:6880;      # AriaNg
        proxy_set_header Host $host;
    }

    location /jsonrpc {
        proxy_pass http://127.0.0.1:6800/jsonrpc;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_read_timeout 86400;              # WebSocket am Leben halten
    }
}

Sicherheit schichten: HTTPS, eine Auth-Schicht (Basic Auth oder ein Identity-Proxy), ein starkes rpc-secret und eine Firewall. Ein VPN (WireGuard/Tailscale) ist der einfachste Weg, den Dienst gar nicht erst offenzulegen.

Automatisierung nach dem Download

aria2 führt nach Abschluss eines Downloads einen Befehl aus, gesteuert über on-download-complete. Fügen Sie ihn zu aria2.conf hinzu und binden Sie das Skript ein:

# in aria2.conf
on-download-complete=/config/on-complete.sh
on-download-error=/config/on-error.sh

# /config/on-complete.sh  (chmod +x)
#!/bin/bash
GID="$1"; NUM_FILES="$2"; TARGET_PATH="$3"   # $3 ist der Pfad der ersten Datei
logger "aria2 fertig: $TARGET_PATH"
# Beispiele:
#   rclone move "$(dirname "$TARGET_PATH")" remote:downloads/
#   unzip -o "$TARGET_PATH" -d "$(dirname "$TARGET_PATH")"
#   curl -s "https://ntfy.sh/mytopic" -d "Download fertig: $(basename "$TARGET_PATH")"

$1 = GID, $2 = Anzahl der Dateien, $3 = Pfad der ersten Datei. Halten Sie Hooks schnell und nicht blockierend; erledigen Sie die schwere Arbeit im Hintergrund.

Health & Monitoring

    healthcheck:
      test: ["CMD-SHELL", "aria2c --version >/dev/null && wget -qO- http://127.0.0.1:6800/jsonrpc --post-data='{\"jsonrpc\":\"2.0\",\"id\":\"h\",\"method\":\"aria2.getVersion\",\"params\":[\"token:CHANGE_ME_STRONG_SECRET\"]}' >/dev/null"]
      interval: 60s
      timeout: 10s
      retries: 3

Fehlerbehebung

WebUI meldet „Disconnected“ / RPC schlägt fehl

Prüfen Sie drei Dinge: Der Container läuft (docker compose ps), Port 6800 ist gemappt, und das Secret entspricht rpc-secret. Lädt das WebUI über HTTPS, müssen auch seine RPC-Aufrufe HTTPS/WSS sein (Mixed-Content-Regel) – nutzen Sie den Reverse-Proxy oben.

Torrent zeigt 0 Peers / DHT 0 Knoten

Mappen und leiten Sie einen Port für TCP und UDP weiter (wir nutzen 6888) und fügen Sie frische Tracker über die Tracker-Liste oder bt-tracker=… in der Konfiguration hinzu. DHT startet, sobald es das Netzwerk erreicht.

Zugriff verweigert beim Schreiben der Downloads

Der Container schreibt als sein Benutzer (standardmäßig root). Setzen Sie entweder user: "1000:1000" passend zum Host oder chown den Ordner ./downloads, damit der Container-Benutzer schreiben darf.

Downloads starten nach einem Neustart bei 0

Session-Persistenz ist nicht konfiguriert. Stellen Sie sicher, dass save-session, input-file und save-session-interval auf einen gemounteten Pfad zeigen (hier /config/aria2.session) und continue=true gilt.

Port 6800 bereits belegt / Container startet nicht

Eine andere aria2-Instanz oder App belegt 6800 auf dem Host. Ändern Sie das Host-Mapping (z. B. "6801:6800") oder stoppen Sie den anderen Prozess.

FAQ

Brauche ich einen WebUI-Container?

Nein. AriaNg, das Online-WebUI dieser Seite oder jeder RPC-Client kann direkt mit der Engine sprechen. Das WebUI ist optionale Dekoration über der RPC-API.

Wie aktualisiere ich aria2?

Bauen Sie das Image neu, wenn ein neues Alpine-Paket verfügbar ist: docker compose build --no-cache && docker compose up -d. Ihre Konfiguration, Session und Downloads bleiben in den Mounts erhalten.

Ist ein Community-Image wie p3terx/aria2-pro in Ordnung?

Ja, wenn Sie dessen dokumentierte Variablen prüfen. Diese Anleitung baut ihr eigenes minimales Image, damit die Konfiguration explizit und portabel ist; ein gepflegtes Community-Image ist aber eine gültige Abkürzung.