Bitdoze-Logo

Arcane Docker installieren: Self-Hosted-Container-Manager

Arcane-Docker-Installationsanleitung, aktualisiert für v2.17: Compose-Setup, Docker-Socket-Proxy-Sicherheit, OIDC/SSO, Reverse Proxy und Remote-Hosts. Jetzt mit Podman-Support.

Dragos

Aktualisiert Veröffentlicht 31 Min. Lesezeit

Arcane-Self-Hosted-Container-Manager-Dashboard, installiert mit Docker Compose auf einem Linux-Server

Ich betreibe Arcane inzwischen seit Monaten auf meinen Servern. Es hat Portainer ersetzt, und ich habe nicht zurückgeschaut. Das Ganze läuft auf Go – das heißt: schnell, sparsam mit Speicher und ohne komplizierte Runtime. Wenn du es einfach nur laufen lassen willst, deckt diese Arcane-Docker-Installationsanleitung alles ab, von der Basisinstallation bis zur Socket-Proxy-Absicherung.

Wenn du einen Vergleich mit einem anderen neueren Docker-Manager suchst, schau dir meinen Artikel Arcane vs. Dockhand an.

Diese Anleitung wurde am 2026-10-26 für Arcane 2.17 aktualisiert. Neu seit der letzten Revision: natives Podman, OpenTelemetry, Auto-Update-Verzögerungen, Registry-Browsing und Mobile-Apps. Eine v3-Beta existiert auf Docker Hub. Bleib für Produktion auf v2-Tags. Wenn du einer älteren Version dieser Anleitung gefolgt bist: Das Image ist von ghcr.io/getarcaneapp/arcane nach ghcr.io/getarcaneapp/manager umgezogen, JWT_SECRET ist weg, und der Headless-Agent heißt jetzt arcane-agent. Details unten.

Affiliate-Hinweis

Einige Links in dieser Anleitung sind Affiliate-Links. Wenn du darüber kaufst, erhalten wir möglicherweise eine kleine Provision – ohne zusätzliche Kosten für dich. Das hilft uns, diese Empfehlungen weiter zu testen und zu aktualisieren.

Was Arcane macht

Arcane ist eine webbasierte Docker-Verwaltungs-UI und eine Alternative zu Portainer. Du bekommst Container-Verwaltung, Compose-Stack-Bearbeitung, Echtzeit-Logs, ein Web-Terminal und GitOps – alles in einer einzigen Self-Hosted-Container-Manager-Oberfläche. Es läuft als einzelner Container.

Arcane-Docker-Manager-UI mit Container-Liste und Compose-Editor

Die Dauer-Features, die mich zum Wechsel gebracht haben:

  • REST-API, gegen die du direkt skripten kannst
  • CLI-Tool für Terminal-basierte Verwaltung neben der Web-UI
  • GitOps eingebaut, nicht als nachträglicher Gedanke. Auf ein Repo zeigen, und deine Stacks syncen automatisch
  • OIDC/SSO plus Passkeys und MFA, alles kostenlos
  • Trivy-Vulnerability-Scanning in der UI, Copacetic-Image-Patching und geplante S3-/Volume-Backups (alles in den Releases 2.9 bis 2.12 hinzugekommen). Für Offsite-Backups: Zerobyte für automatisierte restic-Backups
  • Tag-basierte Container-Auto-Updates, jetzt mit optionaler Update-Verzögerung als Supply-Chain-Abkühlphase
  • Remote-Host-Verwaltung über die arcane-agent-Binaries, mit einem mTLS-Edge-Tunnel für Hosts hinter NAT
  • BSD-3-Clause-Lizenz. Kostenlos, keine Bezahltarife, keine Feature-Locks

Neu seit 2.12 (der Release-Zug ist schnell, 110 Releases bisher):

  • Nativer Podman-Support (2.17), inklusive Rootless- und Quadlet-Beispielen
  • Update-Verzögerung in Stunden als Auto-Update-Abkühlphase (2.17)
  • OpenTelemetry-Export für Metriken, Traces und Logs (2.16)
  • Multiplexter Edge-Tunnel und eine neu designte Verbindungsansicht (2.16)
  • Registry-Browsing für Repos und Tags (2.15)
  • Risikobasierte Security-Ansicht, Bulk-Vulnerability-Ignore/Restore, Container-Prozesse-Tab (2.14)
  • Offizielle Images auf Docker Hub und Quay.io zusätzlich zu GHCR (seit 2.9)
  • Mobile Apps: iOS-Beta, plus Android-Beta auf Google Play (Oktober 2026)

Das Projekt steht bei 8.071 GitHub-Stars mit 344 Forks und ~95 Contributors und hat 110 Releases seit Erstellung des aktuellen Repos im April 2025 geshipt. Das Tempo ist echt.

Registry-Wahl: Die Docs nutzen ghcr.io/getarcaneapp/manager, und sowohl getarcaneapp/manager auf Docker Hub als auch quay.io/getarcaneapp/manager sind offiziell. Such dir eins aus und pinne einen Versions-Tag (ich pinne v2; mehr dazu im Install-Abschnitt).

Voraussetzungen

Bevor du anfängst, brauchst du:

  • Einen Linux-Server (VPS oder lokale Maschine). Ubuntu 22.04+ oder Debian 12 sind okay
  • Docker und Docker Compose installiert
  • ~1 vCPU und 1–2 GB RAM reichen für den Manager selbst. Es ist eine einzelne Go-Binary; der Rest der Kiste ist für deine Stacks
  • Einen Domainnamen, wenn du SSO oder einen Reverse Proxy mit TLS willst
  • Port 3552 für die UI und optional 3553, wenn du Direct-Agents (nicht Edge) fährst
  • Grundlegende Terminal-Kenntnisse

Kostencheck: Ein 4–6-€/Monat-VPS fährt Arcane plus einen kleinen Stack locker. Ich empfehle Hetzner und Hostinger für VPS-Hosting.

VPS-Preise sind 2026 überall gestiegen. Wenn du eine gemietete Kiste überdenkst: Was sich geändert hat und wann ein Mini-PC gewinnt.

Hetzner VPS Hostinger VPS DigitalOcean $100 Free Vultr $100 Free

Oder betreib es zu Hause. Siehe den Guide Mini-PC als Home Server. Ich mag die ASUS-Mini-PC-Hardwareklasse dafür: leise, wenig Strom, genug RAM für Docker plus ein Dutzend Services.

Docker installieren

Wenn du Docker noch nicht hast, nutze Dockers Convenience-Skript. Es erkennt die Distro und richtet das richtige Repo ein:

bash
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USER
# log out and back in for the group to apply

Verifiziere sowohl die Engine als auch das Compose-Plugin:

bash
docker version
docker compose version

„Kaputt” sieht aus wie permission denied while trying to connect to the Docker daemon socket. Das heißt, die Gruppenmitgliedschaft ist noch nicht aktiv geworden. Neu einloggen – nicht ewig mit sudo dagegen ankämpfen. Kompletter Walkthrough: Docker & Docker-Compose für Ubuntu installieren.

Arcane mit Docker Compose installieren

Es gibt zwei Wege, Arcane zu installieren. Das Convenience-Skript ist am schnellsten, aber ich bevorzuge die Compose-Methode, weil du genau siehst und kontrollierst, was passiert.

Schnellinstallation (Convenience-Skript)

Wenn du in 30 Sekunden laufen willst:

bash
curl -fsSL https://getarcane.app/install.sh | sudo bash

Das ist eine native Installation, kein Container

Das Install-Skript richtet Docker ein (falls es fehlt), lädt die native Arcane-Binary von GitHub Releases herunter und registriert einen systemd-Service. Es symlinks die Binary nach /usr/local/bin/arcane. Es pullt kein Container-Image und schreibt keine Compose-Datei für dich. Gut zum Testen; nutze Compose für ein dauerhaftes Setup, damit dir die Config gehört.

Prüfen:

bash
systemctl status arcane

Dann http://deine-server-ip:3552 öffnen. Zum späteren Entfernen gibt es einen Uninstaller. Er ist interaktiv, und --force --remove-all nimmt Docker gleich mit – also die Prompts lesen:

bash
curl -fsSL https://getarcane.app/uninstall.sh | sudo bash

Docker-Compose-Installation (empfohlen)

Erstelle zuerst ein Verzeichnis für Arcane:

bash
mkdir -p /opt/arcane
cd /opt/arcane

Generiere den ENCRYPTION_KEY:

bash
openssl rand -hex 32

Offizielle Alternativen, falls du Arcanes eigenen Generator bevorzugst:

bash
docker run --rm ghcr.io/getarcaneapp/manager:latest /app/arcane generate secret
# or: arcane-cli generate secret

Jetzt deine compose.yaml erstellen:

yaml
services:
  arcane:
    image: ghcr.io/getarcaneapp/manager:v2
    container_name: arcane
    ports:
      - "3552:3552"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - arcane-data:/app/data
      - /opt/stacks:/opt/stacks
    environment:
      - APP_URL=http://localhost:3552
      - PUID=1000
      - PGID=1000
      - ENCRYPTION_KEY=your-generated-encryption-key
      - PROJECTS_DIRECTORY=/opt/stacks
      - TZ=Europe/Bucharest
    cgroup: host
    healthcheck:
      test: ["CMD", "./arcane", "health", "--timeout", "2s"]
      interval: 10s
      timeout: 3s
      retries: 5
      start_period: 15s
    restart: unless-stopped
    stop_grace_period: 15s
volumes:
  arcane-data:

Ersetze ENCRYPTION_KEY durch den Wert, den du generiert hast. Setze APP_URL auf deine tatsächliche Server-Adresse, wenn du remote zugreifst. Die Zeile cgroup: host lässt Arcane seine eigene Container-ID erkennen – wichtig für Self-Upgrades.

Ein paar Notizen zu dieser Datei:

  • Pinne den Image-Tag. :v2 beschert dir Patch-Releases auf der 2.x-Linie. :latest kann dich an einem Montagmorgen überraschen. Rollback ist der umgekehrte Weg: den vorherigen Tag neu pinnen (v2.16.1 oder was immer du hattest), dann docker compose pull && docker compose up -d. Siehe wie man einen Container mit Docker Compose aktualisiert für den kompletten Tanz.
  • Die Zeilen healthcheck und stop_grace_period: 15s stammen aus den offiziellen Beispielen. Der Healthcheck gibt depends_on etwas Echtes, worauf es warten kann, sobald du einen Socket-Proxy hinzufügst.
  • Optionale Mounts: /builds für Arcanes Build Workspace (Image-Builds) und /backups für exportierte Backups. Füg sie hinzu, wenn du die Features nutzt.
  • Secrets: Jede sensible Variable unterstützt das _FILE-Suffix, falls du lieber aus einer gemounteten Datei lesen willst statt Werte inline zu übergeben. Siehe Docker-Compose-Secrets für Muster, die mit Compose funktionieren.

Was ist mit JWT_SECRET passiert?

Arcane 2.x signiert Session-Tokens mit einem ML-DSA-87-Key, den es selbst generiert und speichert (ML-DSA-87 ist das NIST-FIPS-204-Post-Quantum-Signaturverfahren, geshipt in Arcane 2.10.0) – JWT_SECRET wird also nicht mehr verwendet. Wenn deine Compose-Datei es noch setzt, loggt Arcane beim Start eine Warnung. Entferne es. Dieselbe Geschichte beim Image-Namen: ghcr.io/getarcaneapp/arcane ist der alte Name, ghcr.io/getarcaneapp/manager der aktuelle.

Finger weg von v3-Tags

Docker Hub hat v3-beta-Tags, Stand Oktober 2026. Sie sind Beta. Für alles, was dir wichtig ist, pinne v2 (oder v2.17) und lass die v3-Leute die scharfen Kanten finden.

Volume-Pfade

Identische Host- und Container-Pfade sind weiterhin die Empfehlung, wenn Arcane bestehende Compose-Projekte verwalten soll (z. B. /opt/stacks:/opt/stacks). Es ist keine harte Anforderung mehr: Arcane liest seine eigenen Container-Mounts und übersetzt Projektpfade zu Host-Pfaden. Wenn du das Mapping selbst angeben willst, setze PROJECTS_DIRECTORY=<containerPath>:<hostPath>. Compose-Dateien mit relativen Pfaden lösen in beiden Fällen korrekt auf, sobald das Mapping stimmt.

Starten:

bash
docker compose up -d

Die Installation verifizieren

Nicht überspringen. Zwei Minuten hier ersparen später eine Debug-Session.

  • docker compose ps zeigt den Container als healthy (der Healthcheck tut seinen Job innerhalb von ~15 s nach dem Start)
  • curl -s http://localhost:3552/health liefert ein Health-Payload aus der Kiste
  • Öffne http://deine-server-ip:3552 und logge dich mit arcane / arcane-admin ein
  • docker compose logs -f arcane ist ruhig. Keine Warnungen über JWT_SECRET oder fehlende Keys

Der erste Login erzwingt eine Passwortänderung

Arcane verlangt beim ersten Einloggen eine Änderung des Standard-Passworts. Das ist erzwungen, kein Vorschlag. Wenn du nach dem ersten Login irgendwie noch arcane-admin als Passwort hast, ist etwas schiefgegangen.

Wenn der Container in einer Schleife neu startet, ist das Erste, was du prüfst, ENCRYPTION_KEY. Ein leerer oder malformed Wert ist der übliche Übeltäter. Wenn auf 3552 gar nichts lauscht, prüfe die Firewall oder die Security Group deines Providers, bevor du Arcane die Schuld gibst. Beide Fälle sind im Troubleshooting am Ende abgedeckt.

Härtung: Docker-Socket-Proxy

Den Docker-Socket direkt zu mounten, gibt Arcane volle Kontrolle über deinen Docker-Daemon. Das ist ein Sicherheitsrisiko. Wird Arcane irgendwie kompromittiert, hat ein Angreifer Root-äquivalenten Zugriff auf deinen Host. Der Socket ist eine Root-Level-API, verkleidet als Unix-Datei.

Der Fix ist ein Socket-Proxy, der filtert, welche Docker-API-Calls Arcane machen darf. Die Form:

unsafe: direct socket mountBrowserArcaneDocker socketroot-equivalent✕safe: socket proxy with allowlistBrowserArcanesocket-proxyallowlist onlyDocker
Warum einen Socket-Proxy nutzen?

Der Docker-Socket (/var/run/docker.sock) ist faktisch eine Root-Level-API. Jeder Container mit Zugriff darauf kann privilegierte Container erstellen, das Host-Dateisystem mounten oder beliebige Befehle als root auf dem Host ausführen.

Ein Socket-Proxy sitzt zwischen Arcane und dem Docker-Daemon. Er fängt API-Calls ab und lässt nur die durch, die du explizit erlaubt hast. Du bekommst die Verwaltungsfunktionalität, ohne die Schlüssel zum Königreich abzugeben.

Dieses Setup wird für jeden internet-facing Server empfohlen, und es ist das Layout, das Arcanes eigene Docs für SELinux- und gehärtete Hosts vorschlagen. Für ein Homelab hinter einer Firewall ist direktes Socket-Mounting wahrscheinlich okay. Wenn deine Kiste internet-facing ist, paare das mit den anderen langweiligen Schichten: Wie ich meinen Docker-Server nach dem BSI-Bericht abgesichert habe und Wie man einen internet-facing VPS mit CrowdSec schützt.

Arcanes Docs empfehlen jetzt wollomatic/socket-proxy als Default. Das ist es, was der offizielle Instance Generator produziert. Wenn du Tecnativas docker-socket-proxy schon fährst, behalte ihn; die korrigierte Allowlist steht in Option 2. Für neue Setups nimm Option 1.

Arcane Instance Generator

Option 1: wollomatic Socket-Proxy (empfohlen)

Der Generator schreibt diese Datei für dich. Hier die Form, damit du weißt, was du deployst:

yaml
services:
  arcane:
    image: ghcr.io/getarcaneapp/manager:v2
    container_name: arcane
    ports:
      - "3552:3552"
    volumes:
      - arcane-data:/app/data
      - /opt/stacks:/opt/stacks
    environment:
      - APP_URL=https://arcane.yourdomain.com
      - PUID=1000
      - PGID=1000
      - ENCRYPTION_KEY=your-generated-encryption-key
      - PROJECTS_DIRECTORY=/opt/stacks
      - TZ=Europe/Bucharest
      - DOCKER_HOST=tcp://docker-socket-proxy:2375
    cgroup: host
    depends_on:
      docker-socket-proxy:
        condition: service_healthy
    networks:
      - arcane-net
    restart: unless-stopped
    stop_grace_period: 15s

  docker-socket-proxy:
    image: wollomatic/socket-proxy:1.13.1
    container_name: arcane-docker-proxy
    user: "0:0"
    command:
      - "-listenip=0.0.0.0"
      - "-allowfrom=arcane,arcane-upgrader"
      - "-allowhealthcheck"
      # method+path allow rules (allowGET/allowPOST/allowPUT/allowDELETE)
      # go here. See the note below before starting this
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    read_only: true
    cap_drop: [ALL]
    security_opt: ["no-new-privileges:true"]
    healthcheck:
      test: ["CMD", "./healthcheck"]
      interval: 2s
      timeout: 5s
      retries: 15
    networks:
      - arcane-net
    restart: unless-stopped

networks:
  arcane-net:
    driver: bridge

volumes:
  arcane-data:

Zu den Allow-Regeln: wollomatic ist deny-by-default, ohne sie kann Arcane also nichts. Die Regeln sind method+path-Paare, die als Flags übergeben werden (Syntax-Form: -allowGET=/v1.*/containers/*). Die komplette aktuelle Liste ist versionsspezifisch und lebt in Arcanes Socket-Proxy-Docs. Der Instance Generator schreibt den kompletten Command-Block für dich. Nutze eine dieser beiden Quellen statt einer aus einem Blogpost kopierten Liste (diesem hier eingeschlossen).

Drei Dinge, die in dieser Config zählen:

  • -allowfrom=arcane,arcane-upgrader braucht beide Namen. arcane-upgrader ist der Alias, den Arcanes Self-Upgrade-Helfer nutzen.
  • Der Socket ist :ro gemountet, und der Proxy-Container läuft read_only mit allen Capabilities gedroppt und no-new-privileges. Der Proxy ist der einzige Container, der den Socket anfasst; Arcane spricht über das interne Bridge-Netzwerk mit ihm.
  • DOCKER_HOST=tcp://docker-socket-proxy:2375 auf der Arcane-Seite ist der ganze Schalter: Arcane mountet den Socket selbst nie.

Bestehende Installationen: arcane-upgrader hinzufügen und neu erstellen

Wenn du wollomatic früher nur mit -allowfrom=arcane eingerichtet hast, werden Self-Upgrade-Helfer geblockt. Füge arcane-upgrader zur Allowlist hinzu und erstelle den Proxy-Container neu: docker compose up -d --force-recreate docker-socket-proxy. Das erste Upgrade nach der Migration sollte über einen normalen Compose-Pull + Recreate laufen, damit du nicht mitten im Upgrade einen halb geblockten Helfer hast.

Verifiziere, dass der Schalter funktioniert hat:

bash
docker compose ps          # proxy shows healthy
docker compose logs arcane # no Docker API errors in the UI's log stream

Dann durch die UI klicken: Container-Liste lädt, Logs streamen, Terminal öffnet sich. Jedes davon ist ein API-Pfad, den die Allowlist erlauben muss. Wenn etwas vor dem Schalter funktionierte und danach nicht mehr, fehlt dir eine Allow-Regel.

Option 2: Tecnativa docker-socket-proxy

Nutze das nur, wenn du Tecnativa schon anderswo auf dem Host fährst. Die Allowlist unten ist die aktuelle aus Arcanes Docs (DISTRIBUTION und SYSTEM wurden im Doc-Update 2.13.1 auf 1 gedreht):

yaml
services:
  arcane:
    image: ghcr.io/getarcaneapp/manager:v2
    container_name: arcane
    ports:
      - "3552:3552"
    volumes:
      - arcane-data:/app/data
      - /opt/stacks:/opt/stacks
    environment:
      - APP_URL=https://arcane.yourdomain.com
      - PUID=1000
      - PGID=1000
      - ENCRYPTION_KEY=your-generated-encryption-key
      - PROJECTS_DIRECTORY=/opt/stacks
      - DOCKER_HOST=tcp://docker-socket-proxy:2375
    cgroup: host
    depends_on:
      - docker-socket-proxy
    networks:
      - arcane-net
    restart: unless-stopped

  docker-socket-proxy:
    image: tecnativa/docker-socket-proxy:latest
    container_name: arcane-socket-proxy
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
    environment:
      - EVENTS=1
      - PING=1
      - VERSION=1
      - POST=1
      - AUTH=0
      - SECRETS=0
      - BUILD=0
      - COMMIT=0
      - CONFIGS=0
      - CONTAINERS=1
      - DISTRIBUTION=1
      - EXEC=1
      - IMAGES=1
      - INFO=1
      - NETWORKS=1
      - NODES=0
      - PLUGINS=0
      - SERVICES=0
      - SESSION=0
      - SWARM=0
      - SYSTEM=1
      - TASKS=0
      - VOLUMES=1
    networks:
      - arcane-net
    security_opt:
      - no-new-privileges:true
    restart: unless-stopped

networks:
  arcane-net:
    driver: bridge

volumes:
  arcane-data:

Arcane mountet den Docker-Socket nicht mehr direkt. Es verbindet sich über DOCKER_HOST=tcp://docker-socket-proxy:2375 mit dem Proxy. Der Socket ist auf dem Proxy read-only gemountet, und beide Container sitzen in einem internen Bridge-Netzwerk.

Die Flags steuern, welche Docker-API-Endpunktgruppen erreichbar sind. Dieses Set ist das, was Arcanes Docs aktuell empfehlen, mit Swarm, Auth und Secrets aus. Wenn du Arcanes Swarm-Lesezugriff nutzt, drehe SWARM, SERVICES, TASKS und NODES auf 1. Behalte AUTH=0 und SECRETS=0, außer du hast einen konkreten Grund dagegen.

OIDC/SSO einrichten

Wenn du schon einen Identity Provider wie Authentik, Keycloak oder Authelia fährst, kannst du Arcane für Single Sign-On anbinden.

Über die Web-UI

Gehe in Arcane zu Settings → Authentication. Trage Client-ID, Client-Secret und Issuer-URL ein (kein Trailing Slash). Arcane discovered die Endpunkte von der .well-known/openid-configuration-Seite des Providers. Die Redirect-URI ist:

text
https://your-arcane-url/auth/oidc/callback

Speichern und die Verbindung testen. User, die sich via OIDC authentifizieren, werden beim ersten Login auto-provisioniert, und du kannst den lokalen Passwort-Login komplett deaktivieren, sobald es funktioniert.

Über Umgebungsvariablen

Füge diese zu deiner Compose-Datei hinzu:

yaml
environment:
  - OIDC_ENABLED=true
  - OIDC_CLIENT_ID=your-client-id
  - OIDC_CLIENT_SECRET=your-client-secret
  - OIDC_ISSUER_URL=https://your-idp.example.com
  - OIDC_SCOPES=openid email profile groups
  - OIDC_GROUPS_CLAIM=groups
  - OIDC_ROLE_MAPPINGS=[{"claimValue":"arcane-admins","roleId":"role_admin"}]

OIDC_GROUPS_CLAIM sagt Arcane, wo die Gruppenmitgliedschaft im Token lebt (realm_access.roles für Keycloak, memberOf für Azure AD). OIDC_ROLE_MAPPINGS bindet einen Claim-Wert an eine Arcane-Rolle, mit optionalem environmentId zum Scopen. So gesetzte Mappings werden bei jedem Boot reconciled und sind in der UI read-only; es unterstützt auch das _FILE-Suffix für Docker-Secrets.

Ältere Guides erwähnen OIDC_ADMIN_CLAIM und OIDC_ADMIN_VALUE. Die sind in 2.x weg, ersetzt durch das Role-Mappings-Setup oben.

Sobald die Grundlagen laufen, sind das die Variablen, die man kennen sollte:

  • OIDC_AUTO_REDIRECT_TO_PROVIDER=true überspringt das lokale Login-Formular komplett. Bevor du es umdrehst, bestätige, dass die Notfall-Login-Seite https://your-arcane-url/login/backup funktioniert. Das ist dein Notausgang, wenn der IdP ausfällt.
  • OIDC_MERGE_ACCOUNTS verknüpft eine OIDC-Identität per E-Mail mit einem bestehenden lokalen Account. Seit 2.16.0 erfordert der Merge eine verifizierte E-Mail vom Provider – genau das Verhalten, das du willst.
  • OIDC_SKIP_TLS_VERIFY existiert für Lab-IdPs mit self-signed Certs. Nicht in Produktion setzen.
  • Provider-Name-/Logo-Variablen und manuelle Endpoint-Overrides sind für Nicht-Discovery-Provider verfügbar.

Keine Anführungszeichen um Werte in Listenform-Environment-Blöcken

In Composes Listensyntax (- KEY=value) werden Anführungszeichen um den Wert Teil des Werts. OIDC_ISSUER_URL="https://idp.example.com" bricht die Discovery. Das beißt jeden einmal. Das JSON in OIDC_ROLE_MAPPINGS ist die Ausnahme: Die JSON-Braces sind in Listenform ungequotet okay.

Verifizieren: Einmal über den IdP einloggen, bestätigen, dass der User mit der richtigen Rolle in Arcane landet – und erst dann (und wirklich erst dann) überlegen, den lokalen Login zu deaktivieren.

Reverse-Proxy-Setup

Du willst einen Reverse Proxy vor Arcane für SSL und einen sauberen Domainnamen. Arcane nutzt WebSockets für Echtzeit-Updates, deine Proxy-Config muss das also unterstützen.

Nginx

nginx
server {
    listen 443 ssl http2;
    server_name arcane.yourdomain.com;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;

    location / {
        proxy_pass http://127.0.0.1:3552;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Die Schlüsselzeilen sind proxy_http_version 1.1 und die Upgrade-/Connection-Header. Ohne sie scheitern WebSocket-Verbindungen, und die UI bekommt keine Live-Updates.

Traefik

Wenn du schon Traefik fährst (was du für Docker-Setups wahrscheinlich solltest), füge deinem Arcane-Service Labels hinzu:

yaml
labels:
  - "traefik.enable=true"
  - "traefik.http.routers.arcane.rule=Host(`arcane.yourdomain.com`)"
  - "traefik.http.routers.arcane.entrypoints=websecure"
  - "traefik.http.routers.arcane.tls.certresolver=letsencrypt"
  - "traefik.http.services.arcane.loadbalancer.server.port=3552"

Traefik handhabt das WebSocket-Upgrade automatisch. Wenn du Edge-Agents auf auto/grpc-Transport fahren willst, sind zwei weitere Dinge nötig (siehe den Remote-Hosts-Abschnitt): eine h2c-Route für /api/tunnel/connect und das Read-Timeout des websecure-Entrypoints deaktiviert:

yaml
# Traefik static/command config: entrypoint level, not router level
- "--entrypoints.websecure.transport.respondingtimeouts.readtimeout=0s"

Das 60-s-Standard-Read-Timeout tötet den gRPC-Tunnel. Komplette Traefik-Setup-Anleitung: Wie man Traefik als Reverse Proxy in Docker nutzt.

Cloudflare Tunnels

Wenn du gar keine Ports exponieren willst, funktionieren Cloudflare Tunnels gut. Zeige einen Tunnel auf http://localhost:3552, und Cloudflare übernimmt SSL und Routing. WebSocket-Support ist automatisch.

Das ist es, was ich in meinem Homelab nutze, weil ich keine Ports auf meinem Router öffnen will. Wenn du Edge-Agents hinter einem Cloudflare-Tunnel hinzufügst, setze EDGE_TRANSPORT=poll auf dem Agent. Polling funktioniert gut durch den Tunnel; langlebiges gRPC durch CF würde ich nicht ohne Test verbauen.

TRUSTED_PROXIES setzen

Seit 2.16.0 extrahiert Arcane Client-IPs nur von Proxies, denen du explizit vertraust. Hinter jedem Reverse Proxy setze TRUSTED_PROXIES auf den CIDR deines Proxy-Netzwerks (z. B. TRUSTED_PROXIES=172.18.0.0/16 für die Docker-Bridge, der dein Proxy beitritt). Ohne das benehmen sich Login-Rate-Limiting und IP-Logging daneben: Du siehst überall die Proxy-IP, und Rate-Limits feuern auf die falsche Identität. Und wo wir gerade dabei sind: Docker kann deine Firewall-Regeln umgehen – verlass dich also nicht allein auf UFW, um 3552 geschlossen zu halten.

Aktualisiere die APP_URL-Umgebungsvariable in deiner Compose-Datei auf deine tatsächliche Domain (z. B. https://arcane.yourdomain.com, ohne :3552; der Proxy terminiert den Port).

Wenn du den Reverse Proxy lieber komplett überspringen willst, kann Arcane TLS selbst ausliefern: setze TLS_ENABLED=true, TLS_CERT_FILE und TLS_KEY_FILE. Es spricht HTTP/2 über TLS direkt. Okay fürs Lab; ich bevorzuge trotzdem einen Proxy davor.

Remote-Hosts verwalten

Arcane kann Docker auf anderen Maschinen über den Arcane-Agent verwalten. Praktisch, wenn du mehrere Server hast, aber ein Dashboard willst. Wenn du eine ältere Version dieses Stacks installiert hast: Der Agent hieß früher arcane-headless; das aktuelle Image ist ghcr.io/getarcaneapp/agent, und die Binary heißt arcane-agent. Aktualisiere alte Compose-Dateien auf die neuen Namen.

Es gibt zwei Verbindungsmodi:

direct: manager dials agent, inbound 3553 openManagerTCP :3553Agent :3553remote hostedge: agent dials out, no inbound portManagerEdge agentmTLS poll / tunnel (outbound)behind NAT ok

Direct heißt, der Manager erreicht den Agent auf TCP-Port 3553. Edge heißt, der Agent wählt sich über einen mTLS-Tunnel beim Manager ein – der Remote-Host braucht also keinen offenen Inbound-Port. Edge ist der Modus, den du für alles hinter NAT oder einer Firewall willst. Das mTLS-Setup ist in Arcanes Edge-mTLS-Docs dokumentiert.

In beiden Fällen erstelle zuerst das Environment: Öffne Environments → Add Environment in der Arcane-UI, wähle Direct oder Edge, und es generiert den Token plus ein startfertiges Snippet für dich. Die Edge-Compose sieht so aus:

yaml
services:
  arcane-edge-agent:
    image: ghcr.io/getarcaneapp/agent:v2
    container_name: arcane-edge-agent
    environment:
      - EDGE_AGENT=true
      - EDGE_TRANSPORT=poll
      - AGENT_TOKEN=arc_your-generated-token
      - MANAGER_API_URL=https://arcane.yourdomain.com
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock
      - agent-data:/app/data
    cgroup: host
    restart: unless-stopped
    stop_grace_period: 15s
volumes:
  agent-data:

EDGE_TRANSPORT-Optionen:

Wert Verhalten Wann nutzen
poll Agent meldet sich periodisch; kein persistenter Tunnel NAT, Cloudflare-Tunnels, wackelige Verbindungen. Generierte Snippets nutzen das
auto Kontinuierlicher gRPC-Tunnel mit WebSocket-Fallback (Default, wenn nicht gesetzt) Stabile Netzwerke, wo du Instant-Push willst
websocket Kontinuierlicher WebSocket-Tunnel Proxies, die an gRPC würgen
grpc Kontinuierlicher gRPC-Tunnel Direkte Verbindungen oder Traefik mit h2c + deaktiviertem Read-Timeout

Auf Poll-Environments siehst du die Status Online / Standby / Pending / Offline in der Verbindungsansicht. Standby heißt gesund: Der Agent idled und wartet auf den nächsten Poll, er ist nicht down. Die erste Aktion gegen ein Idle-Poll-Environment kann einen Moment dauern, während die Verbindung aufwacht. Stelle die Erwartungen richtig ein, bevor du annimmst, es sei kaputt.

Der Agent kann auch als Standalone-Binary laufen, wenn du auf dem Remote-Host keinen Container willst.

Ein Ops-Detail gegen Verwirrung: Es gibt zwei verschiedene „Update All”-Buttons. Updates → Update All aktualisiert Container und Projekte. Environments → Update All aktualisiert erst die Agents, dann den Manager. Flotten-Upgrades sind ein einzelner Klick statt einer Per-Host-Pflicht.

Arcane auf Podman betreiben

Neu in 2.17.0 (21. Oktober 2026): Arcane verwaltet Podman nativ. Wenn deine Hosts Podman statt Docker fahren, ist dies das erste Release, in dem der Support echt statt experimentell ist.

Das Repo liefert die Beispiele: compose.podman-rootful.yaml, compose.podman-rootless.yaml und Quadlet-Dateien unter docker/examples/quadlet/. Die praktischen Unterschiede zur Docker-Installation sind der Socket-Pfad (Podmans Socket, rootless vs. rootful) und das Rootless-Permission-Modell. Es gibt außerdem eine eigene Docs-Sektion (docs/podman/) für Quadlets, Kube, Secrets und Auto-Update.

Quadlet-verwaltete Container überspringen Arcane-Auto-Updates

Absichtlich. Container, die systemd-Quadlets gehören, würden ihre systemd-Unit verlieren, wenn Arcane sie neu erstellen würde – Arcane lässt sie also in Ruhe. Für diese nutze Podmans eigenen Auto-Update-Mechanismus (podman auto-update + das io.containers.autoupdate-Label).

Dieser Support ist zum Schreiben Wochen alt. Ich würde ihn jetzt auf einem Lab-Host einsetzen und ein paar Release-Zyklen warten, bevor ich eine Produktiv-Podman-Flotte drauf ziehe. Wenn du bei der Container-Engine selbst noch am Entscheiden bist: Wie Podman im Vergleich zu Docker abschneidet.

Umgebungsvariablen-Referenz

Das sind die Variablen, nach denen ich am häufigsten greife. Für das Gesamtbild, wie Docker Config in Container reicht: Wie Docker-Umgebungsvariablen funktionieren.

Variable Default Was sie tut
APP_URL http://localhost:3552 Öffentliche URL der Instanz (auf deine echte Domain hinter einem Proxy setzen)
PUID / PGID 65532:65532 User-/Gruppen-ID für Dateiberechtigungen. Images starten als root zum Vorbereiten, droppen dann auf diesen User
ENCRYPTION_KEY keiner Pflicht. 32-Byte-Key zum Verschlüsseln sensibler Daten
PROJECTS_DIRECTORY /app/data/projects Wo Arcane nach Compose-Projekten sucht. Akzeptiert die Mapping-Form <containerPath>:<hostPath>
DOCKER_HOST unix:///var/run/docker.sock Docker-Verbindung. tcp:// für Socket-Proxy nutzen
TZ Container-Default Zeitzone. Relevant für Cron-Zeitpläne (Backups, Auto-Update-Fenster)
TRUSTED_PROXIES unset CIDR der Proxies, die Client-IPs setzen dürfen. Pflicht hinter jedem Reverse Proxy (2.16+)
TLS_ENABLED / TLS_CERT_FILE / TLS_KEY_FILE unset HTTPS direkt ausliefern, kein Reverse Proxy
DATABASE_URL SQLite Externer Datenbank-Connection-String
JWT_REFRESH_EXPIRY 168h Refresh-Token-Lebensdauer
ADMIN_STATIC_API_KEY unset Statischer API-Key für Automatisierung
TRIVY_SECURITY_OPTS / TRIVY_PRIVILEGED unset Trivy-Scanning-Verhalten feintunen
GIT_WORK_DIR / SSH_KNOWN_HOSTS eingebaut GitOps-Workspace und SSH-Host-Verifizierung
http_proxy / https_proxy / no_proxy unset Ausgehender Proxy für Image-Pulls und API-Calls (kleingeschrieben)
LOG_LEVEL info Log-Verbosität
UI_CONFIGURATION_DISABLED false Config nur via Env-Vars erzwingen. Settings-Override-Env-Vars werden nur beachtet, wenn das true ist (oder AGENT_MODE=true)

JWT_SECRET taucht weiterhin in alten Docs und Compose-Dateien auf, ist aber in 2.x ungenutzt. Nicht setzen. GPU-Monitoring-Variablen (GPU_MONITORING_ENABLED, GPU_TYPE) tauchen in manchen älteren Guides auf, fehlen aber in der aktuellen .env.example. Prüfe die Environment-Variables-Doku deiner Version, bevor du dich darauf verlässt.

Troubleshooting

Arcane sieht meine bestehenden Compose-Stacks nicht

Identische Host-/Container-Pfade bleiben die Empfehlung. Wenn deine Compose-Dateien unter /opt/stacks/myapp/compose.yaml liegen, ist das simple Setup:

yaml
volumes:
  - /opt/stacks:/opt/stacks

mit PROJECTS_DIRECTORY=/opt/stacks.

Trotzdem: Pfad-Mismatch ist nicht mehr fatal. Arcane liest seine eigenen Container-Mounts und übersetzt Projektpfade zu Host-Pfaden. Wenn dein Mapping ungewöhnlich ist, gib es explizit an:

yaml
environment:
  - PROJECTS_DIRECTORY=/app/data/projects:/opt/stacks

Format ist <containerPath>:<hostPath>. Wenn Stacks danach immer noch nicht auftauchen, prüfe, ob der Mount im Container existiert (docker exec arcane ls /opt/stacks), bevor du das Mapping beschuldigst.

WebSocket-Fehler oder UI aktualisiert nicht live

Dein Reverse Proxy reicht WebSocket-Verbindungen nicht weiter. Stelle sicher, dass die Upgrade-Header gesetzt sind. Für Nginx brauchst du:

nginx
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
Permission denied auf dem Docker-Socket

Entweder deinen User zur docker-Gruppe hinzufügen (sudo usermod -aG docker $USER) oder sicherstellen, dass die PUID/PGID-Werte in der Compose-Datei zu einem User mit Docker-Zugriff passen. Innerhalb des Containers bekommen auf Bind-Mounts erstellte Dateien die PUID/PGID-Ownership. Wähle IDs, die zum User passen, dem deine Stacks gehören. Für Container, die du selbst baust: Wie man einen Non-Root-User zu einem Docker-Container hinzufügt.

Noch das alte Image oder JWT_SECRET im Einsatz

Wenn deine Compose ghcr.io/getarcaneapp/arcane referenziert oder JWT_SECRET setzt: auf ghcr.io/getarcaneapp/manager aktualisieren und die JWT-Zeile streichen. Arcane startet trotzdem, loggt aber Warnungen – und der alte Image-Name ist aus aktuellen Beispielen und Registries verschwunden.

Self-Upgrade schlägt nach Umstieg auf einen Socket-Proxy fehl

Der Upgrade-Helper-Container trägt das Label arcane-upgrader. Wenn deine wollomatic-Allowlist nur -allowfrom=arcane hat, wird der Helfer mitten im Upgrade geblockt. Füge arcane-upgrader zu -allowfrom hinzu und erstelle den Proxy neu:

bash
docker compose up -d --force-recreate docker-socket-proxy

Mach das erste Upgrade nach dieser Migration über einen normalen Compose-Pull + Recreate, damit du dich nicht auf den Helfer verlässt, während sich die Allowlist einspielt.

Login-Rate-Limits feuern auf die falsche IP

Du bist hinter einem Reverse Proxy, und TRUSTED_PROXIES ist nicht gesetzt. Arcane (seit 2.16.0) vertraut Client-IPs nur von konfigurierten Proxies. Ohne das sieht jeder Request aus, als käme er von der Proxy-Adresse – Rate-Limiting und IP-Logs sind also falsch. Setze TRUSTED_PROXIES auf den Proxy-Netzwerk-CIDR (z. B. 172.18.0.0/16) und starte neu.

Edge-Agent bleibt in Pending hängen oder verbindet nicht durch Traefik

Drei Checks, in dieser Reihenfolge:

  1. AGENT_TOKEN und MANAGER_API_URL stimmen mit dem Environment überein, das du in der UI erstellt hast (Snippet neu generieren, wenn unsicher).
  2. Auf Traefik mit EDGE_TRANSPORT=auto oder grpc: /api/tunnel/connect als h2c routen und --entrypoints.websecure.transport.respondingtimeouts.readtimeout=0s setzen. Das 60-s-Standard-Read-Timeout droppt den Tunnel.
  3. Hinter Cloudflare oder jedem Pfad, der langlebige Verbindungen nicht mag, nutze EDGE_TRANSPORT=poll.

Und: Standby ist nicht down. Ein Poll-Modus-Agent in Standby ist gesund und idled.

Was ich mag und was fehlt

Ich betreibe Arcane inzwischen lange genug, um Meinungen zu haben.

Die GitOps-Integration ist das Feature, das ich am meisten nutze. Ich halte meine Compose-Dateien in einem privaten Git-Repo, und wenn ich Änderungen pushe, pickt Arcane sie auf und deployt neu. Keine Webhook-Config, keine CI-Pipeline nötig.

Die REST-API ist das andere, auf das ich mich stütze. Ich habe ein kleines Skript geschrieben, das Container-Health prüft und alles Unhealthy neu startet. Hat etwa 20 Minuten gedauert, weil die API geradlinig ist.

Die Lücken, über die ich mich in der ersten Version dieser Anleitung beschwert habe, sind größtenteils geschlossen: Trivy-Scanning, geplante Auto-Updates und Backups kamen alle in den Releases 2.9 bis 2.12, und 2.14 bis 2.17 brachten den Prozesse-Tab, eine risikobasierte Security-Ansicht und Registry-Browsing. Die neue Update Delay ist der Teil, den ich für alles Internet-facing aktivieren würde. Sie ist eine Supply-Chain-Abkühlphase, damit ein frisch veröffentlichter bösartiger Tag nicht in der Sekunde gepullt wird, in der er erscheint:

yaml
x-arcane:
  updater:
    delay: 72          # project default, hours
services:
  cache:
    image: redis:7
    x-arcane:
      updater:
        delay: 0       # opt a service out of the cool-down
# or label: com.getarcaneapp.arcane.updater.delay=72

Was mit Stand v2.17.1 noch fehlt: Dockhand-artiges Scan-before-Swap-Gating, bei dem ein Update nur durchläuft, wenn das neue Image sauber scannt (zum Schreibzeitpunkt nicht in den Docs), und ein richtiger Datei-Browser innerhalb von Containern. Keins davon ist ein Dealbreaker, aber beide würden Arcane angenehmer machen. Wenn Auto-Updates generell dein Ding sind, ist Tugtainers Auto-Update-Ansatz ebenfalls lesenswert.

Wenn du diese konkreten Features heute willst, schau dir wie man Dockhand installiert an. Und für das breitere Feld: Mein Portainer-Alternativen-Vergleich deckt Sencho, Dockge, Komodo und den Rest ab.

Verwandte Artikel

Hat diese Anleitung bei dir funktioniert?

Brauchst du Hilfe bei Astro, VPS oder einer Self-hosted-App? Services ansehen →