12 KiB
LTX DeskWEB manuell mit Docker installieren
Diese Anleitung installiert das fertige Web-Frontend auf Debian/Linux amd64. Auf dem Zielserver wird nichts kompiliert. Athena Deck muss die GUI nicht selbst installieren: Die zwei unten genannten Labels machen sie in „Weitere Dienste“ sichtbar.
Voraussetzungen und Aufbau
- Docker Engine ist installiert und läuft. Für die optionale Compose-Variante zusätzlich ein aktuelles Docker-Compose-Plugin verwenden.
- Ein eingerichtetes LTX-Desktop-Backend ist separat vorhanden. Bei Verwendung von Athena Deck stellt dessen API-Port im Videomodus die native LTX-API bereit.
- GUI und LTX-Backend sehen dieselben Eingabe- und Ausgabedateien. Nur eine API-Adresse genügt nicht, da die native LTX-API Server-Dateipfade verwendet.
- Der gewünschte GUI-Port ist frei. Das Beispiel verwendet Port 8118.
Die GUI braucht keine GPU-Freigabe, NVIDIA-Runtime oder Docker-Socket. Das Image enthält den Webdienst und ffmpeg für Medienvorschauen, keine Modellgewichte. Die folgenden Serverbefehle als root ausführen. Sie entsprechen Athenas aktueller LTX-Pfadstruktur; auf einem anderen Server die Pfade und Benutzergruppen anpassen.
1. Fertiges Image herunterladen
Falls das Paket einen Login verlangt:
docker login git.casaderoll.de --username michael
Passwort bzw. Token interaktiv eingeben. Für den Download genügen Paket-Leserechte. Dann:
docker pull git.casaderoll.de/michael/ltx-deskweb:0.1.0-9ff96db
Das Image enthält die Korrekturen für Upload-Rechte und Browser-Höhe. Version und geprüfter Digest stehen in CONTAINER_REGISTRY.md.
2. Volumes und Zugriffsrechte vorbereiten
| Hostpfad im Athena-Beispiel | Pfad im GUI-Container | Zugriff / Zweck |
|---|---|---|
/data/video/ltx-desktop/LTXDesktop/remote-inputs/deskweb |
/data/inputs |
Lesen/Schreiben: Uploads, importierte Dateien, Vorschaubilder |
/data/video/ltx-desktop/LTXDesktop/outputs |
/data/outputs |
Nur Lesen: Ergebnisse des LTX-Backends |
/opt/ltx-deskweb/secrets/web-password |
/run/secrets/web_password |
Nur Lesen: Kennwort für die Web-GUI |
/opt/ltx-deskweb/secrets/ltx-token |
/run/secrets/ltx_token |
Nur Lesen: API-Token des angesprochenen Backends/Deck-Endpunkts |
Die unten beschriebenen Pfade unter /opt/ltx-deskweb/secrets sind ein Beispiel für
neue manuelle Installationen. Die bereits ausgerollte Athena-Instanz verwendet
/opt/ltx-deskweb/source/secrets; deren Betriebsanleitung steht in
ATHENA_DEPLOYMENT.md. Keine zweite Instanz mit demselben
Container-Namen oder Port starten.
Nur für die neue Einrichtung:
install -d -m 700 /opt/ltx-deskweb/secrets
install -d -o 1000 -g 0 -m 2750 \
/data/video/ltx-desktop/LTXDesktop/remote-inputs/deskweb
test -d /data/video/ltx-desktop/LTXDesktop/outputs
Der letzte Befehl muss erfolgreich sein. Andernfalls zuerst die tatsächliche Ausgabeablage des LTX-Backends klären, nicht einfach einen leeren Ersatzordner anlegen. Vorhandene Modell-/Medienverzeichnisse nicht rekursiv umberechtigen.
Warum UID 1000 / GID 0? Die GUI läuft ohne root-UID als Benutzer 1000. Athenas
LTX-Backend läuft als UID/GID 0, aber ohne Linux-Capabilities. Es kann deshalb
private Dateien eines anderen Benutzers nicht automatisch lesen. Der neue
Input-Ordner ist gruppenlesbar und hat das Setgid-Bit (2750); neue Dateien erben
GID 0 und erhalten 0640. So können beide Dienste dieselben Uploads lesen.
Bei anderer Backend-Identität eine passende gemeinsame Gruppe verwenden.
Auch LTX-Ausgaben müssen für die GUI lesbar sein; der Mount bleibt read-only.
Zuordnung zum LTX-Container, nicht zur GUI:
| GUI-Pfad | Derselbe Inhalt aus Sicht des LTX-Backends |
|---|---|
/data/inputs |
/data/LTXDesktop/remote-inputs/deskweb |
/data/outputs |
/data/LTXDesktop/outputs |
Diese zweite Spalte wird mit BACKEND_INPUT_DIR und BACKEND_OUTPUT_DIR gesetzt.
Bei Athena bindet LTX /data/video/ltx-desktop vom Host als /data ein. Bei anderen
Mounts müssen die Backend-Pfade entsprechend angepasst werden.
3. Kennwort und API-Token hinterlegen
Zwei getrennte Dateien verwenden:
web-password: eigenes GUI-Kennwort, mindestens 16 Zeichen.ltx-token: vorhandener API-Token von Athena Deck, wenn die URL auf Deck zeigt. Beim direkten LTX-Zugriff stattdessen dessen Token. Nur bei einem Backend ohne Authentifizierung darf diese Datei leer sein.
Das folgende interaktive Beispiel schreibt keine Secrets in die Shell-Historie und überschreibt keine vorhandenen Dateien:
python3 - <<'PY'
import getpass, os
from pathlib import Path
root = Path('/opt/ltx-deskweb/secrets')
if any((root / name).exists() for name in ('web-password', 'ltx-token')):
raise SystemExit('Secret-Dateien existieren bereits; nichts überschrieben.')
password = getpass.getpass('Neues GUI-Kennwort (mindestens 16 Zeichen): ')
if len(password) < 16 or password != getpass.getpass('GUI-Kennwort wiederholen: '):
raise SystemExit('Kennwort zu kurz oder Wiederholung stimmt nicht.')
token = getpass.getpass('Vorhandener Deck-/LTX-API-Token: ')
for name, value in [('web-password', password), ('ltx-token', token)]:
fd = os.open(root / name, os.O_WRONLY | os.O_CREAT | os.O_EXCL, 0o400)
with os.fdopen(fd, 'w') as stream:
stream.write(value + '\n')
os.chown(root / name, 1000, 0)
PY
Secrets nicht ins Repository einchecken. Sie werden nur in den Container gemountet und bleiben außerhalb des Images.
4. Labels und Ports
Für die Anzeige unter Athena Deck → Weitere Dienste sind beide Labels nötig:
io.athena-deck.managed=true
io.athena-deck.role=application
Zusätzliche beschreibende Labels dieses Images:
org.ltx-deskweb.role=frontend
org.ltx-deskweb.backend=ltx-desktop
Labels werden beim Erstellen des Containers gesetzt. Sie registrieren kein Modell und laden keine GPU-Laufzeit. Die GUI erscheint nur in der Docker-Instanz, die Deck abfragt; ein Container auf einem anderen Server wird dadurch nicht automatisch entdeckt.
| Verbindung | Port / Bedeutung |
|---|---|
| Browser → Web-GUI | 8118 im Beispiel; frei wählbar |
| Web-GUI → Athena Deck | 8120 im bestehenden Aufbau; die konfigurierte API-Adresse verwenden |
| Web-GUI → LTX direkt (optional) | Tatsächlicher nativer LTX-Port, auf Athena derzeit 41955; kein zusätzlicher GUI-Port |
| Mac → Athena (SSH-Tunnel) | SSH-Port 22 auf Athena |
Die folgende Variante verwendet Host-Networking nur für diesen GUI-Container.
Damit erreicht sie Decks 127.0.0.1:8120, ohne Decks Netzwerk zu verändern.
HOST=127.0.0.1 beschränkt den GUI-Zugriff auf Loopback. Es gibt bei Host-Networking
keine -p-Portabbildung: PORT ist der tatsächlich auf dem Host belegte Port.
5. Container starten — ohne Build und ohne Git-Checkout
Vorher z. B. mit ss -ltn prüfen, dass 8118 frei ist.
docker run -d \
--name ltx-deskweb \
--restart unless-stopped \
--init \
--network host \
--user 1000:0 \
--read-only \
--cap-drop ALL \
--security-opt no-new-privileges:true \
--cpus 2 --memory 1g \
--tmpfs /tmp:size=128m,mode=1777 \
--label io.athena-deck.managed=true \
--label io.athena-deck.role=application \
--label org.ltx-deskweb.role=frontend \
--label org.ltx-deskweb.backend=ltx-desktop \
--env HOST=127.0.0.1 \
--env PORT=8118 \
--env PUBLIC_ORIGIN=http://127.0.0.1:8118 \
--env LTX_BACKEND_URL=http://127.0.0.1:8120 \
--env WEB_PASSWORD_FILE=/run/secrets/web_password \
--env LTX_TOKEN_FILE=/run/secrets/ltx_token \
--env LOCAL_INPUT_DIR=/data/inputs \
--env BACKEND_INPUT_DIR=/data/LTXDesktop/remote-inputs/deskweb \
--env LOCAL_OUTPUT_DIR=/data/outputs \
--env BACKEND_OUTPUT_DIR=/data/LTXDesktop/outputs \
--mount type=bind,src=/data/video/ltx-desktop/LTXDesktop/remote-inputs/deskweb,dst=/data/inputs \
--mount type=bind,src=/data/video/ltx-desktop/LTXDesktop/outputs,dst=/data/outputs,readonly \
--mount type=bind,src=/opt/ltx-deskweb/secrets/web-password,dst=/run/secrets/web_password,readonly \
--mount type=bind,src=/opt/ltx-deskweb/secrets/ltx-token,dst=/run/secrets/ltx_token,readonly \
git.casaderoll.de/michael/ltx-deskweb:0.1.0-9ff96db
Für Portainer/andere Container-Verwaltungen dieselben Labels, Umgebungsvariablen, Bind-Mounts, Benutzer- und Netzwerkeinstellungen übernehmen.
Alternative: vorhandene Compose-Dateien verwenden
Im geklonten Repository .env und secrets/ gemäß README vorbereiten. Hier liegen
Secrets relativ zum Repository, nicht im Pfad des obigen docker run-Beispiels.
Die Werte für den dedizierten Input-Ordner inklusive /deskweb verwenden.
docker compose -p ltx-deskweb -f compose.yaml -f compose.registry.yaml \
-f deploy/compose.athena.yaml pull ltx-deskweb
docker compose -p ltx-deskweb -f compose.yaml -f compose.registry.yaml \
-f deploy/compose.athena.yaml up -d --no-build --no-deps ltx-deskweb
compose.registry.yaml entfernt den Build-Schritt; die Labels kommen aus
compose.yaml. Nicht zusätzlich zur docker run-Variante starten.
Alternative: Bridge-Netzwerk oder anderer Container-Stack
Ohne --network host gilt: HOST=0.0.0.0 im Container und beispielsweise
-p 127.0.0.1:8118:8118 für den Host. LTX_BACKEND_URL muss vom Container aus
wirklich erreichbar sein: 127.0.0.1 bezeichnet dann die GUI selbst.
host.docker.internal allein macht einen ausschließlich auf Host-Loopback
gebundenen Backend-Port nicht erreichbar. Netzwerkzugang bewusst planen, nicht
pauschal bestehende Backend-Bindings oder Firewallregeln ändern.
Ein anderer Rechner benötigt zusätzlich Zugriff auf dieselben Medien, etwa über
geeignet eingebundenen gemeinsamen Speicher.
6. Im Browser öffnen
Auf dem Mac den Tunnel starten und das Terminal offen lassen:
ssh -i /Users/mike_i386/.ssh/athena_key -o BatchMode=yes \
-o ExitOnForwardFailure=yes -N \
-L 8118:127.0.0.1:8118 root@192.168.1.212
Dann http://127.0.0.1:8118 öffnen und das GUI-Kennwort verwenden. Die Anwendung läuft auf Athena; der Mac ist Browser und Tunnel-Client. Ist der Tunnel bereits offen, nicht noch einmal denselben Port belegen.
PUBLIC_ORIGIN muss exakt zur verwendeten Browser-Adresse passen, einschließlich
Schema und Port. Bei einer Domain mit HTTPS dort die tatsächliche HTTPS-Origin
setzen und einen passenden Reverse Proxy verwenden. Die Anleitung richtet kein
öffentliches Routing oder WireGuard ein.
Unter Deck „Weitere Dienste“ aktualisieren: ltx-deskweb sollte erscheinen.
Für Generierung Video in Deck aktivieren. Der GUI-Start selbst schaltet keine
Modelle um und verändert den LTX-Dienst nicht.
7. Prüfen, stoppen, aktualisieren
docker ps --filter name=ltx-deskweb
curl --fail --output /dev/null http://127.0.0.1:8118/
docker ps -a --filter label=io.athena-deck.managed=true \
--filter label=io.athena-deck.role=application
# Nur die GUI stoppen / wieder starten:
docker stop ltx-deskweb
docker start ltx-deskweb
Für Updates erst die neue geprüfte Image-Version herunterladen und dann nur den
GUI-Container ersetzen. Vorher laufende Generierungen und die GUI-Verbindung
berücksichtigen; ein Neustart beendet die Web-Sitzungen. Compose-Nutzer starten
mit den gleichen drei Dateien erneut up -d --no-build --no-deps ltx-deskweb.
Bei docker run muss der alte GUI-Container nach dem Stoppen entfernt und mit dem
neuen Image neu angelegt werden. Die Bind-Mount-Daten bleiben erhalten.
Details: UPGRADE_INFO.md.
Projekte liegen in dieser Version im Browser. JSON-Backup in „Connection & information“ verwenden; ein Container-Backup allein sichert keine Browserprojekte. Medien und Secrets separat sichern. Ein Image enthält keine Nutzerdaten.
Häufige Fehler
| Meldung / Verhalten | Prüfen |
|---|---|
Image file not found |
Backend-Pfad, gleicher Hostordner in beiden Containern, Ordnerdurchquerung und Gruppen-Leserechte (2750 / 0640) |
| GUI läuft, LTX nicht bereit | Deck im Videomodus? API-Port und Token korrekt? Backend erreichbar? |
Cross-origin request rejected |
PUBLIC_ORIGIN stimmt exakt mit der Browser-URL überein |
| Container fehlt in Deck | Beide io.athena-deck.*-Labels gesetzt und derselbe Docker-Host? |
Registry unauthorized |
Login auf dem Rechner ausführen, der das Image pullt; Paket-Leserechte prüfen |
| Port belegt | Freien PORT wählen; Tunnel und PUBLIC_ORIGIN ebenfalls anpassen. Bei Host-Networking hilft eine Änderung nur an -p nicht. |
| Vorschau/Download nicht lesbar | Output-Mount und Dateirechte für UID 1000 / gemeinsame Gruppe prüfen |