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.
Werbung Mit * 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

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. In der Regel belegt 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/amd64undlinux/arm64verö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. Das Repository ist nicht archiviert. 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. Der Prozess läuft entsprechend als Benutzer convertx mit der UID aus PUID. Version v0.20.0 vom 28.10.2026 ergänzt laut Release-Notes die Umwandlung von DjVu-Dateien, eine überarbeitete Seite bei fehlgeschlagener Anmeldung und Korrekturen bei Titelbildern in Audiodateien; neue Variablen gibt es nicht.
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.20.0. Schreiben Sie die Version fest, damit ein Pull nicht unbemerkt ein Update einspielt.
| Eckdaten | Wert |
|---|---|
| Image | ghcr.io/c4illin/convertx:v0.20.0 (alternativ Docker Hub c4illin/convertx) |
| Port im Container | 3000 (änderbar über PORT) |
| Volume | ./data:/app/data mit mydb.sqlite, uploads/, output/ |
| Wichtige Variablen | JWT_SECRET, PUID, PGID, ACCOUNT_REGISTRATION, HTTP_ALLOWED, ALLOW_UNAUTHENTICATED, AUTO_DELETE_EVERY_N_HOURS |
| Healthcheck | GET /healthcheck liefert {"status":"ok"} ohne Anmeldung |
$ sudo mkdir -p /opt/convertx/data
$ sudo chown -R 1000:1000 /opt/convertx
$ cd /opt/convertxls -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: 30sIn die .env gehören Version, Benutzerkennung und Sicherheitsschalter. Alle Variablennamen stammen aus der README des Projekts.
# Version festschreiben
CONVERTX_TAG=v0.20.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=24Ohne JWT_SECRET erzeugt ConvertX bei jedem Start einen zufälligen Schlüssel. Dadurch werden nach jedem Neustart alle Anmeldungen ungültig. Schützen Sie die Datei mit chmod 600 .env.
docker compose config gibt die Konfiguration ohne Fehler aus und zeigt beim Image den Tag v0.20.0.
Schritt 3: Starten und das erste Konto anlegen
$ docker compose up -d
$ docker compose logs --no-log-prefix | head -n 25Der erste Start lädt das Image und kann gut eine Minute dauern. 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: Ein zweiter Registrierungsversuch leitet nur auf die Login-Seite um und legt 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..
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.
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 tritt dabei auf. 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.
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 startDie 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 startLöschen Sie nach der Sicherung einen Konvertierungsauftrag in der Oberfläche, läuft der Download ins Leere, und der Auftrag fehlt in der Datenbank. Nach dem Restore ist er wieder vorhanden, die JPG-Datei lässt sich erneut herunterladen, und das vorherige Anmelde-Cookie bleibt gültig, weil das JWT_SECRET unverändert ist. Wegen AUTO_DELETE_EVERY_N_HOURS enthält ein Backup ohnehin nur Dateien der letzten Stunden; wertvoll sind vor allem die Konten.
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.0Ein 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.
So läuft das Update, etwa von v0.19.0 auf v0.20.0: Nach dem Tagwechsel und docker compose up -d meldet das Log ConvertX v0.20.0, der Container wird nach wenigen Sekunden healthy, das vorhandene Konto meldet sich an, eine bestehende Sitzung bleibt gültig, ein falsches Passwort bekommt 403, ein Aufruf ohne Anmeldung liefert 401, und eine weitere Registrierung bleibt gesperrt.
Die erste Logzeile nennt die neue Version, etwa ConvertX v0.20.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.20.0
$ sudo rm -rf /opt/convertxdocker ps -a --filter name=convertx und docker images | grep convertx liefern keine Ausgabe mehr.
Grundlagen zum Betrieb finden Sie in Docker Compose unter Linux: Grundlage für Selfhosting, Docker Compose absichern: Secrets, Healthchecks, Non-Root und Linux-Server absichern mit UFW und Fail2ban.
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 mitcurl -sD - -o /dev/null -d 'email=...&password=...' http://host:3000/login | grep -i set-cookie. Lösung: HTTPS per Reverse Proxy, im Notfall nur zum AusprobierenHTTP_ALLOWED=true.- Nach jedem Neustart abgemeldet
JWT_SECRETfehlt oder ändert sich. Prüfen mitdocker compose exec convertx printenv JWT_SECRET.unable to open database fileLaut README stimmen dann die Rechte am Datenordner nicht.
PUIDundPGIDanid -uundid -ganpassen oder den Ordner mitchownübergeben.Bind for 127.0.0.1:3000 failed: port is already allocatedDer Port ist belegt. Mit
ss -ltnp | grep 3000den Verursacher finden oder in dercompose.yamleinen anderen Host-Port wählen.- Pull findet das Image nicht
Tag ohne „v“ angegeben. Die Registry kennt
0.19.0nicht (Manifest-Abfrage mit HTTP 404), richtig istv0.19.0bzw.v0.20.0.- Ergebnisse verschwunden
Die automatische Löschung nach
AUTO_DELETE_EVERY_N_HOURShat gegriffen; mit0abschaltbar.
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.
Weiterführende Anleitungen und Quellen
- Stirling PDF mit Docker einrichten: ergänzt ConvertX um PDF-Bearbeitung wie Zusammenführen, Schwärzen und Texterkennung.
- Gotenberg als PDF-API mit Docker: die Alternative, wenn Dokumente automatisiert per API umgewandelt werden sollen.
- Caddy als Reverse Proxy mit automatischem HTTPS: für Schritt 5.
- 3-2-1-Backup-Strategie praktisch umsetzen: damit das Archiv aus Schritt 6 nicht auf demselben Server liegt.
- ConvertX auf GitHub mit README und Variablenübersicht
- Release-Notes zu ConvertX v0.20.0
- Changelog des Projekts
- Container-Image in der GitHub Container Registry


