Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 01.10.2026 · 11 min Lesezeit

ConvertX mit Docker Compose: Dateikonverter im eigenen Netz betreiben

ConvertX bündelt LibreOffice, Pandoc, ImageMagick, FFmpeg und Calibre in einem Container. Die Anleitung zeigt compose.yaml und .env, das sichere erste Konto, typische Login-Fehler hinter HTTP sowie einen geprüften Backup- und Restore-Ablauf.

Mit KI erstellt – redaktionelle Prüfung ausstehend

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

Hero-Grafik: Headline Dateien konvertieren im eigenen Netz, drei Karten Dokumente, Bilder, Audio und Video, rechts schematischer Dateikonverter mit Server

Wer ein Word-Dokument in PDF oder eine WAV-Aufnahme in MP3 umwandeln muss, landet oft bei einem kostenlosen Online-Konverter. Für Unternehmen ist das heikel: Angebote oder Personalunterlagen wandern dabei auf fremde Server, deren Speicherdauer und Standort niemand prüft. ConvertX ist ein selbst gehosteter Dateikonverter mit Weboberfläche, der Werkzeuge wie LibreOffice, Pandoc, ImageMagick, FFmpeg und Calibre in einem einzigen Container bündelt. Diese Anleitung zeigt, wie Sie ConvertX mit Docker Compose sicher betreiben, Konten absichern, Daten sichern und zurückspielen und welche Grenzen Sie kennen sollten.

Voraussetzungen

ConvertX ist ein einzelner Dienst ohne separate Datenbank. Engpässe sind Plattenplatz und Rechenzeit bei Videos.

  • CPU: 2 Kerne reichen für Dokumente, Bilder und Audio. Für häufige Video-Konvertierungen sind mehr Kerne sinnvoll.
  • RAM: 2 GB sind das Minimum, 4 GB empfehlenswert. Im Test belegte der Container direkt nach dem ersten Start rund 640 MiB und später im Leerlauf unter 50 MiB. Die Empfehlung ist eine eigene Einschätzung, denn das Projekt nennt keine Mindestwerte; LibreOffice und FFmpeg brauchen während einer Konvertierung zusätzlich Speicher.
  • Speicher: mindestens 10 GB frei. Das Image ist entpackt etwa 5,6 GB groß (Download rund 1,5 GB komprimiert), dazu kommen hochgeladene und erzeugte Dateien.
  • Architektur: Das Image wird für linux/amd64 und linux/arm64 veröffentlicht, läuft also auch auf ARM-Servern mit 64-Bit-System.
  • Software: Docker Engine mit dem Compose-Plugin (Befehl docker compose) sowie ein Reverse Proxy mit TLS-Zertifikat.

Ein kleiner Linux-Server oder eine VM im Firmennetz genügt.

Schritt 1: Version, Image und Projektordner festlegen

ConvertX wird von C4illin auf GitHub unter der Lizenz AGPL-3.0 entwickelt. Am 01.10.2026 zählte das Repository laut GitHub-API 19.078 Sterne, war nicht archiviert und hatte den letzten Push am 30.09.2026. Das aktuelle Release v0.19.0 erschien am 26.09.2026 und bringt laut Release-Notes unter anderem die Unterstützung für PUID und PGID, damit Konvertierungen nicht mehr als root laufen. Im Test lief der Prozess entsprechend als Benutzer convertx mit der UID aus PUID.

Achtung bei der compose.yaml im Repository: Sie baut das Image aus dem Quellcode und ist laut Kopfzeile nur für Entwicklung und Tests gedacht. Für den Betrieb gilt das Beispiel aus der README, das ein fertiges Image zieht. Neben latest (letztes Release) und main (letzter Commit) gibt es versionierte Tags wie v0.19.0. Schreiben Sie die Version fest, damit ein Pull nicht unbemerkt ein Update einspielt.

EckdatenWert
Imageghcr.io/c4illin/convertx:v0.19.0 (alternativ Docker Hub c4illin/convertx)
Port im Container3000 (änderbar über PORT)
Volume./data:/app/data mit mydb.sqlite, uploads/, output/
Wichtige VariablenJWT_SECRET, PUID, PGID, ACCOUNT_REGISTRATION, HTTP_ALLOWED, ALLOW_UNAUTHENTICATED, AUTO_DELETE_EVERY_N_HOURS
HealthcheckGET /healthcheck liefert {"status":"ok"} ohne Anmeldung
sudo mkdir -p /opt/convertx/data
sudo chown -R 1000:1000 /opt/convertx
cd /opt/convertx

Verifizieren: ls -ld /opt/convertx/data zeigt den Besitzer mit UID 1000, und docker compose version gibt eine Versionsnummer aus.

Schritt 2: compose.yaml und .env anlegen

Die Datei folgt der README und ergänzt die Bindung an 127.0.0.1, eine feste Version und einen Healthcheck.

services:
  convertx:
    image: ghcr.io/c4illin/convertx:${CONVERTX_TAG}
    container_name: convertx
    restart: unless-stopped
    ports:
      # nur lokal erreichbar, der Reverse Proxy leitet weiter
      - "127.0.0.1:3000:3000"
    env_file: .env
    volumes:
      - ./data:/app/data
    healthcheck:
      test: ["CMD", "curl", "-fsS", "-o", "/dev/null", "http://localhost:3000/healthcheck"]
      interval: 30s
      timeout: 5s
      retries: 3
      start_period: 30s

In die .env gehören Version, Benutzerkennung und Sicherheitsschalter. Alle Variablennamen stammen aus der README des Projekts.

# Version festschreiben
CONVERTX_TAG=v0.19.0
# Besitzer der Dateien in ./data (id -u und id -g auf dem Host)
PUID=1000
PGID=1000
LANGUAGE=de
# langer Zufallswert, z. B. aus: openssl rand -hex 32
JWT_SECRET=HIER_EIGENEN_ZUFALLSWERT_EINTRAGEN
# keine Selbstregistrierung nach dem ersten Konto
ACCOUNT_REGISTRATION=false
# nur true setzen, wenn kein HTTPS möglich ist
HTTP_ALLOWED=false
# nie true auf einem erreichbaren Server
ALLOW_UNAUTHENTICATED=false
# Aufträge und Dateien nach 24 Stunden löschen
AUTO_DELETE_EVERY_N_HOURS=24

Ohne JWT_SECRET erzeugt ConvertX bei jedem Start einen zufälligen Schlüssel. Im Test führte das dazu, dass nach jedem Neustart alle Anmeldungen ungültig waren. Schützen Sie die Datei mit chmod 600 .env.

Verifizieren: docker compose config gibt die Konfiguration ohne Fehler aus und zeigt beim Image den Tag v0.19.0.

Schritt 3: Starten und das erste Konto anlegen

docker compose up -d
docker compose logs --no-log-prefix | head -n 25

Der erste Start lädt das Image und dauerte im Test gut eine Minute. Im Log listet ConvertX seine Version und die aller Konverter auf, etwa LibreOffice 26.8.0.3 und FFmpeg 8.1.2. Rufen Sie danach die Oberfläche auf. Solange noch kein Konto existiert, leitet ConvertX auf /setup um. Wer diese Seite zuerst erreicht, legt das erste Konto an; die README warnt ausdrücklich davor, den Dienst unkonfiguriert offen stehen zu lassen. Legen Sie das Konto deshalb sofort an, bevor der Dienst im Netzwerk sichtbar ist.

Mit ACCOUNT_REGISTRATION=false sind weitere Registrierungen danach gesperrt: Im Test leitete ein zweiter Registrierungsversuch nur auf die Login-Seite um und legte kein Konto an. Für weitere Zugänge schalten Sie die Variable kurz auf true und danach zurück. Ein falsches Passwort beantwortet ConvertX mit HTTP 403 und der Meldung Invalid credentials..

Verifizieren: docker compose ps meldet Up (healthy), curl -s http://127.0.0.1:3000/healthcheck liefert {"status":"ok"}, und ls data zeigt die Datei mydb.sqlite mit dem Besitzer aus PUID.

Schritt 4: Dateien konvertieren und Grenzen kennen

Sie laden eine oder mehrere Dateien hoch, wählen Zielformat und Konverter und laden das Ergebnis einzeln oder als Archiv herunter. Im Praxistest funktionierten PNG nach JPG mit ImageMagick, Markdown nach HTML und DOCX mit Pandoc, DOCX nach PDF mit LibreOffice (Ergebnis nach etwa zwei Sekunden) sowie WAV nach MP3 mit FFmpeg. Für viele Zielformate stehen mehrere Konverter bereit; ein DOCX lässt sich etwa per LibreOffice, Pandoc oder Calibre nach PDF bringen, mit unterschiedlichem Layout.

Ehrlich bleiben sollten Sie bei den Grenzen. ConvertX ist ein Werkzeug für Einzelaufträge, keine Dokumentenstraße: Die README beschreibt keine API für automatisierte Abläufe und nennt weder Texterkennung für gescannte PDFs noch Bearbeitungsfunktionen wie das Zusammenführen von Seiten. Die README nennt Passwortschutz und mehrere Konten; Single Sign-on oder Zwei-Faktor-Anmeldung führt sie nicht auf. Hochgeladene Dateien liegen unverschlüsselt unter data/uploads, bis die automatische Löschung greift, und sind damit für jeden lesbar, der Zugriff auf den Server hat. Große Videos belasten die CPU stark; Hardwarebeschleunigung erfordert eigene FFMPEG_ARGS.

Verifizieren: Konvertieren Sie eine Testdatei, laden Sie das Ergebnis herunter und prüfen Sie es mit file ergebnis.jpg. Im Log steht pro Auftrag eine Zeile wie Converted ... from png to jpeg successfully using imagemagick.

Schritt 5: Reverse Proxy mit HTTPS davorsetzen

ConvertX setzt das Anmelde-Cookie mit dem Attribut Secure, solange HTTP_ALLOWED auf false steht. Browser speichern so ein Cookie nur über HTTPS oder für localhost. Rufen Sie den Dienst per http:// über einen Hostnamen oder eine IP auf, nimmt der Server die Anmeldung zwar an, der Browser verwirft das Cookie aber, und Sie landen wieder auf der Login-Seite. Genau dieses Verhalten zeigte der Test. Die saubere Lösung ist HTTPS, nicht HTTP_ALLOWED=true. Ein Beispiel mit Caddy, das intern ein Zertifikat ausstellt:

convert.firma.intern {
    tls internal
    reverse_proxy 127.0.0.1:3000
}

Bei Nginx begrenzt client_max_body_size die Uploadgröße. Soll ConvertX unter einem Unterpfad wie /convert laufen, setzen Sie laut README zusätzlich WEBROOT=/convert.

Verifizieren: curl -sI https://convert.firma.intern/login liefert HTTP 200, und nach der Anmeldung im Browser bleibt die Sitzung bestehen.

Schritt 6: Backup und Restore

Alles Wichtige liegt in ./data: die SQLite-Datenbank mit Konten und Auftragsliste sowie die Ordner uploads und output. Stoppen Sie den Container für eine konsistente Sicherung kurz, denn SQLite nutzt WAL-Dateien. Sichern Sie auch die .env, denn ohne dasselbe JWT_SECRET sind nach einer Wiederherstellung alle Sitzungen ungültig.

cd /opt/convertx
docker compose stop
tar czf /backup/convertx-$(date +%F).tar.gz data .env
docker compose start

Die Wiederherstellung ersetzt den Datenordner vollständig:

cd /opt/convertx
docker compose stop
mv data data.alt
tar xzf /backup/convertx-2026-10-01.tar.gz
docker compose start

Im Test wurde nach der Sicherung ein Konvertierungsauftrag in der Oberfläche gelöscht. Der Download lief danach ins Leere, und der Auftrag fehlte in der Datenbank. Nach dem Restore war er wieder vorhanden, die JPG-Datei ließ sich erneut herunterladen, und das vorherige Anmelde-Cookie blieb gültig, weil das JWT_SECRET unverändert war. Wegen AUTO_DELETE_EVERY_N_HOURS enthält ein Backup ohnehin nur Dateien der letzten Stunden; wertvoll sind vor allem die Konten.

Verifizieren: tar tzf auf das Archiv listet data/mydb.sqlite, und nach dem Restore erscheinen die Konten wieder; Aufträge im Verlauf sind sichtbar, sofern sie noch nicht automatisch gelöscht waren.

Schritt 7: Updates und Rollback

Release-Notes lesen, Backup wie in Schritt 6, dann nur CONVERTX_TAG in der .env ändern:

docker compose pull
docker compose up -d
docker compose logs --no-log-prefix | head -n 3
# alte Version erst nach erfolgreichem Test entfernen
docker rmi ghcr.io/c4illin/convertx:v0.19.0

Ein Rollback bedeutet: alten Tag eintragen, Datenordner aus dem Backup vor dem Update zurückspielen, neu starten. Nur den Tag zurückzudrehen ist riskant, denn ob eine ältere Version mit einer von der neueren Version veränderten Datenbank zurechtkommt, ist nicht dokumentiert. Wegen der Imagegröße von mehreren Gigabyte sollten Sie das alte Image nach einem erfolgreichen Update gezielt mit docker rmi entfernen, aber erst, wenn kein Rollback mehr nötig ist.

Verifizieren: Die erste Logzeile nennt die neue Version, etwa ConvertX v0.19.0, und docker compose ps zeigt wieder healthy.

Schritt 8: ConvertX entfernen

Warnung: Die folgenden Befehle löschen alle Konten, Aufträge und Dateien unwiderruflich. Erstellen Sie vorher ein Backup, falls Sie die Daten noch brauchen.

cd /opt/convertx
docker compose down -v --remove-orphans
docker rmi ghcr.io/c4illin/convertx:v0.19.0
sudo rm -rf /opt/convertx

Verifizieren: docker ps -a --filter name=convertx und docker images | grep convertx liefern keine Ausgabe mehr.

Troubleshooting

  • Login springt zurück auf die Login-Seite: Zugriff per HTTP über Hostname oder IP. Das Cookie trägt das Attribut Secure. Prüfen mit curl -sD - -o /dev/null -d 'email=...&password=...' http://host:3000/login | grep -i set-cookie. Lösung: HTTPS per Reverse Proxy, im Notfall nur im Labor HTTP_ALLOWED=true.
  • Nach jedem Neustart abgemeldet: JWT_SECRET fehlt oder ändert sich. Prüfen mit docker compose exec convertx printenv JWT_SECRET.
  • unable to open database file: Laut README stimmen dann die Rechte am Datenordner nicht. PUID und PGID an id -u und id -g anpassen oder den Ordner mit chown übergeben.
  • Bind for 127.0.0.1:3000 failed: port is already allocated: Der Port ist belegt. Mit ss -ltnp | grep 3000 den Verursacher finden oder in der compose.yaml einen anderen Host-Port wählen.
  • Pull findet das Image nicht: Tag ohne „v“ angegeben. Die Registry kennt 0.19.0 nicht (Manifest-Abfrage mit HTTP 404), richtig ist v0.19.0.
  • Ergebnisse verschwunden: Die automatische Löschung nach AUTO_DELETE_EVERY_N_HOURS hat gegriffen; mit 0 abschaltbar.

Häufige Fragen

Ist ConvertX für personenbezogene Daten geeignet?

Besser als ein öffentlicher Online-Konverter, weil die Dateien Ihr Netz nicht verlassen. Trotzdem liegen sie unverschlüsselt auf dem Server. Begrenzen Sie die Speicherdauer über AUTO_DELETE_EVERY_N_HOURS, beschränken Sie den Serverzugang und nehmen Sie den Dienst in Ihr Verarbeitungsverzeichnis auf.

Darf ConvertX ohne Anmeldung laufen?

Technisch ja, mit ALLOW_UNAUTHENTICATED=true. Die README warnt ausdrücklich davor, den Dienst so ins Internet zu stellen.

Wie groß dürfen Dateien sein?

Die README nennt keine feste Obergrenze. Praktisch begrenzen Reverse Proxy, Plattenplatz und Rechenzeit. Mit MAX_CONVERT_PROCESS lässt sich die Zahl paralleler Konvertierungen begrenzen.

Fazit

ConvertX ersetzt für typische Büroaufgaben die Online-Konverter, ohne dass Dateien das Unternehmen verlassen. Entscheidend sind ein festes JWT_SECRET, eine geschlossene Registrierung, HTTPS davor und ein Backup, das neben dem Datenordner auch die .env umfasst. Für automatisierte Dokumentenstrecken passt eine spezialisierte Lösung besser.

Testumfang

Praktisch getestet wurden mit v0.19.0 auf amd64 der Start mit Healthcheck, das Anlegen des ersten Kontos samt gesperrter Zweitregistrierung, Login, die Konvertierungen PNG nach JPG, Markdown nach HTML und DOCX, DOCX nach PDF und WAV nach MP3, die Persistenz nach Neustart, Backup und Restore eines gelöschten Auftrags sowie die Fehlerbilder fehlendes JWT_SECRET, HTTP-Login über einen Hostnamen und belegter Port. Nur aus der Dokumentation stammen Reverse-Proxy-Konfiguration, WEBROOT, Video-Konvertierung und Hardwarebeschleunigung, der Betrieb auf ARM, das Update auf eine spätere Version sowie die zeitgesteuerte automatische Löschung.

Weiterführende Anleitungen und Quellen

ConvertXDocker ComposeDateikonverterSelfhostingDatenschutzLibreOfficeFFmpeg