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

ToolJet mit Docker installieren: Open-Source Low-Code-Plattform für interne Tools und Dashboards

ToolJet ist eine Open-Source Low-Code-Plattform, mit der Entwicklerteams per Drag-and-Drop interne Tools, Dashboards und Business-Apps aus 80+ Datenquellen bauen – ohne tiefen Frontend-Code. Diese Anleitung zeigt, wie du ToolJet mit Docker Compose auf jedem Linux-Host selbst hostest.

ToolJet mit Docker installieren: Open Source Low Code Plattform für interne Tools und Dashboards mit Datenquellen wie SQL, MongoDB und REST APIs, visuellen Dashboards, Berechtigungen, Plugins und selbstgehosteter Server Infrastruktur. KI-generiert

Wer im KMU-Alltag Admin-Panels, CRUD-Interfaces oder Approval-Workflows produktiv bringen will, ohne wochenlang an einem React-Frontend zu sitzen, liegt mit ToolJet richtig. Die Plattform verbindet per Drag-and-Drop über 80 native Datenquellen – von PostgreSQL und MySQL über REST- und GraphQL-APIs bis zu AWS S3, Stripe und Twilio – und liefert daraus funktionierende Web-Applikationen. Mit 38.000 GitHub-Stars, AGPL-3.0-Lizenz und aktivem Release-Zyklus (aktuell v3.20.178-lts, Stand Juni 2026) ist ToolJet eine ernstzunehmende Alternative zu kommerziellen No-Code-Plattformen. Dieser Artikel zeigt dir, wie du ToolJet auf einem beliebigen Linux-Host per Docker Compose sauber und sicher aufsetzt.

Voraussetzungen

  1. Linux-Host oder VM mit x86_64-Architektur (kein ARM64, kein Apple Silicon ohne Rosetta-Emulation); Ubuntu 22.04 LTS oder Debian 12 empfohlen
  2. Docker Engine ≥ 20.10 und Docker Compose Plugin v2 (docker compose, nicht das veraltete docker-compose); falls noch nicht installiert: Docker und Docker Compose auf Linux installieren
  3. Mindestens 4 GB RAM für ToolJet; für produktiven PostgreSQL-Betrieb werden 8 GB RAM und 2 vCPUs empfohlen
  4. Mindestens 8 GB freier Festplattenspeicher (das ToolJet-Image allein ist ca. 1,4 GB groß)
  5. Öffentlich erreichbare IP-Adresse oder Domain für die TOOLJET_HOST-Variable (inklusive Protokoll, z. B. http://192.168.1.10:3000)
  6. openssl auf dem Host installiert (auf Ubuntu/Debian standardmäßig vorhanden)
  7. Optional: SMTP-Zugangsdaten für E-Mail-Einladungen, Domain und SSL-Zertifikat für HTTPS hinter einem Reverse Proxy

Schritt 1: Projektordner anlegen

Lege einen dedizierten Ordner für den ToolJet-Stack an. Alle Konfigurationsdateien und der Datenbank-Bind-Mount landen hier:

mkdir -p /opt/tooljet
cd /opt/tooljet
mkdir postgres_data

Das Verzeichnis postgres_data muss vor dem ersten Start manuell existieren – anderenfalls legt Docker es als Root-eigenem Verzeichnis an und PostgreSQL verweigert den Start.

Verifizieren: Mit ls -la /opt/tooljet/ solltest du den Unterordner postgres_data/ sehen. Die Berechtigungen müssen von deinem Docker-Prozess schreibbar sein.

ls -la /opt/tooljet/
# Erwartete Ausgabe:
# drwxr-xr-x  3 root root 4096 Jun 11 10:00 .
# drwxr-xr-x 12 root root 4096 Jun 11 10:00 ..
# drwxr-xr-x  2 root root 4096 Jun 11 10:00 postgres_data

Schritt 2: Secrets erzeugen und .env anlegen

ToolJet benötigt drei kryptografische Secrets, die du einmalig vor dem ersten Start erzeugst. Einmal gesetzte Secrets dürfen nicht nachträglich geändert werden – das würde alle gespeicherten Datasource-Credentials und Sessions ungültig machen.

# SECRET_KEY_BASE (64 Byte Hex, für Session-Cookies)
openssl rand -hex 64

# LOCKBOX_MASTER_KEY (32 Byte Hex, für Datasource-Credential-Verschlüsselung)
openssl rand -hex 32

# PGRST_JWT_SECRET (32 Byte Hex, für PostgREST JWT)
openssl rand -hex 32

Trage die drei Ausgaben in eine neue Datei /opt/tooljet/.env ein. Ersetze die Platzhalter durch deine tatsächlichen Werte:

# === ToolJet Secrets – NIEMALS in Git committen! ===
SECRET_KEY_BASE=hier_dein_64byte_hex_string
LOCKBOX_MASTER_KEY=hier_dein_32byte_hex_string
PGRST_JWT_SECRET=hier_dein_32byte_hex_string

# === ToolJet Host – muss öffentlich erreichbar sein ===
TOOLJET_HOST=http://192.168.1.10:3000

# === PostgreSQL-Zugangsdaten ===
PG_HOST=postgres
PG_DB=tooljet_db
PG_USER=tooljet
PG_PASS=sicheres_passwort_hier
PG_PORT=5432

# === ToolJet interne Datenbank (gleiche Instanz) ===
TOOLJET_DB=tooljet_db
TOOLJET_DB_HOST=postgres
TOOLJET_DB_USER=tooljet
TOOLJET_DB_PASS=sicheres_passwort_hier
TOOLJET_DB_PORT=5432

# === PostgREST Verbindungs-URI ===
PGRST_DB_URI=postgres://tooljet:sicheres_passwort_hier@postgres:5432/tooljet_db

# === Optionale Härtung ===
DISABLE_TOOLJET_TELEMETRY=true
DISABLE_SIGNUPS=true

Schütze die Datei sofort vor unbefugtem Zugriff und sorge dafür, dass sie nie in ein Git-Repository gelangt:

chmod 600 /opt/tooljet/.env
echo ".env" >> /opt/tooljet/.gitignore

Verifizieren: Prüfe, dass die Datei existiert, die Berechtigungen stimmen und kein Secret-Wert leer geblieben ist:

ls -la /opt/tooljet/.env
# Erwartete Ausgabe: -rw------- 1 root root ... .env

# Alle Pflicht-Variablen auf Inhalt prüfen:
grep -E "^(SECRET_KEY_BASE|LOCKBOX_MASTER_KEY|PGRST_JWT_SECRET)=" /opt/tooljet/.env

Schritt 3: compose.yaml erstellen

Der Stack besteht aus drei Diensten: tooljet (App und Frontend), postgres (Datenbank) und postgrest (interner REST-Layer für die ToolJet DB). Alle drei müssen laufen, damit ToolJet korrekt funktioniert.

Wichtige Entscheidung beim Image: tooljet/tooljet-ce:ce-lts-latest ist die reine Community Edition unter AGPL-3.0. Wer Enterprise-Features wie SAML SSO oder Audit-Logs benötigt, verwendet tooljet/tooljet:ee-lts-latest. Den Tag :latest solltest du im Produktivbetrieb vermeiden, da er unkontrolliert auf neue Major-Versionen springen kann.

Erstelle die Datei /opt/tooljet/compose.yaml:

services:
  tooljet:
    image: tooljet/tooljet-ce:ce-lts-latest
    platform: linux/amd64
    restart: always
    tty: true
    stdin_open: true
    ports:
      - "3000:80"
    env_file:
      - .env
    environment:
      SERVE_CLIENT: "true"
      PORT: "80"
    command: npm run start:prod
    depends_on:
      postgres:
        condition: service_healthy
    volumes:
      - logs:/app/logs
      - certs:/app/certs
      - fallbackcerts:/app/fallbackcerts

  postgres:
    image: postgres:16
    restart: always
    environment:
      POSTGRES_USER: ${PG_USER}
      POSTGRES_PASSWORD: ${PG_PASS}
      POSTGRES_DB: ${PG_DB}
    volumes:
      - ./postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${PG_USER} -d ${PG_DB}"]
      interval: 10s
      timeout: 5s
      retries: 5
      start_period: 30s

  postgrest:
    image: postgrest/postgrest:v12.0.2
    platform: linux/amd64
    restart: always
    environment:
      PGRST_DB_URI: ${PGRST_DB_URI}
      PGRST_JWT_SECRET: ${PGRST_JWT_SECRET}
      PGRST_SERVER_PORT: "80"
      PGRST_DB_PRE_CONFIG: postgrest.pre_config
    depends_on:
      postgres:
        condition: service_healthy

volumes:
  logs:
  certs:
  fallbackcerts:

Beachte: Der postgres_data-Ordner wird als Bind-Mount (./postgres_data:/var/lib/postgresql/data) und nicht als Named Volume eingebunden. Das ist bewusste Absicht – so kannst du die Daten einfach per rsync oder pg_dump sichern und verlierst sie nicht, wenn du versehentlich docker compose down -v ausführst.

Auf welchen Ports läuft was? Eine Übersicht der Eckdaten:

ParameterWertHinweis
Image (CE)tooljet/tooljet-ce:ce-lts-latestCommunity Edition, AGPL-3.0
Image (EE)tooljet/tooljet:ee-lts-latestEnterprise Edition
Stabile Versionv3.20.178-ltsStand Juni 2026
Architekturlinux/amd64 onlyARM64 nicht unterstützt
Port (extern)3000 → intern 80Web-UI und API
PostgreSQLpostgres:16Bind-Mount ./postgres_data
PostgRESTpostgrest/postgrest:v12.0.2nur container-intern
Mindest-RAM4 GB (ToolJet) / 8 GB (prod.)Gesamt empfohlen: 8 GB
Image-Größeca. 1,4 GBErsten Pull einplanen

Verifizieren: Prüfe die Syntax der compose.yaml, bevor du den Stack startest:

cd /opt/tooljet
docker compose config --quiet && echo "Syntax OK"
# Erwartete Ausgabe: Syntax OK

Schritt 4: Stack starten

Starte den Stack im Hintergrund. Docker zieht beim ersten Ausführen alle Images – das kann bei 1,4 GB für das ToolJet-Image mehrere Minuten dauern:

cd /opt/tooljet
docker compose up -d

Beim allerersten Start führt ToolJet automatisch alle Datenbankmigrationen durch. Dieser Prozess dauert 5–10 Minuten. Starte den Container in dieser Zeit nicht neu – das würde die Migrationen unterbrechen.

Beobachte den Fortschritt in den Logs:

docker compose logs -f tooljet
# ToolJet ist bereit, wenn die folgende Zeile erscheint (sinngemäß):
# Server is listening on port 80

Verifizieren: Prüfe den Status aller drei Container – alle müssen running oder (healthy) zeigen:

docker compose ps
# Erwartete Ausgabe:
# NAME                IMAGE                              STATUS
# tooljet-tooljet-1   tooljet/tooljet-ce:ce-lts-latest   Up X minutes
# tooljet-postgres-1  postgres:16                        Up X minutes (healthy)
# tooljet-postgrest-1 postgrest/postgrest:v12.0.2        Up X minutes

Prüfe zusätzlich per HTTP-Request, ob ToolJet antwortet:

curl -I http://localhost:3000
# Erwartete Ausgabe: HTTP/1.1 200 OK (oder 302 Found zur Login-Seite)

Schritt 5: Erst-Einrichtung im Browser

Öffne http://<DEINE-IP>:3000 im Browser. Beim ersten Aufruf zeigt ToolJet einen Setup-Wizard, in dem du den ersten Admin-Account anlegst. Dieser initiale Account kann sich nicht per Einladung anmelden – er wird direkt im Wizard erstellt.

Nach dem Login landest du im ToolJet-Dashboard. Von hier aus kannst du:

  1. Apps erstellen: per Drag-and-Drop im visuellen App-Builder
  2. Datenquellen verbinden: über „Data Sources" im linken Menü (PostgreSQL, REST-API, MySQL, MongoDB, S3, Stripe und 75+ weitere)
  3. Nutzer einladen: über „Settings → Users" (setzt SMTP-Konfiguration voraus)
  4. Workspaces verwalten: ToolJet unterstützt mehrere isolierte Workspaces

Wenn du DISABLE_SIGNUPS=true in der .env gesetzt hast, können sich neue Benutzer nur noch über eine E-Mail-Einladung registrieren – das ist für produktive Installationen der richtige Ansatz.

Verifizieren: Nach dem Anlegen des Admin-Accounts siehst du das leere ToolJet-Dashboard im Browser. Prüfe im Terminal, dass keine Fehler in den Logs auftauchen:

docker compose logs --tail=20 tooljet
# Keine Zeilen mit ERROR oder FATAL sollten erscheinen

Schritt 6: Reverse Proxy und HTTPS (optional, empfohlen)

Für den Produktivbetrieb solltest du ToolJet hinter einem Reverse Proxy mit HTTPS betreiben. Passe dazu die .env an:

TOOLJET_HOST=https://tooljet.deine-domain.de

Binde den ToolJet-Port nur auf Localhost:

ports:
  - "127.0.0.1:3000:80"

Der Reverse Proxy muss WebSocket-Verbindungen weiterleiten (Upgrade- und Connection-Header), sonst funktionieren Echtzeit-Features in der UI nicht. Eine ausführliche Anleitung für den Reverse-Proxy-Einstieg bietet Caddy als Reverse Proxy mit automatischem HTTPS – Caddy übernimmt Let's-Encrypt-Zertifikate vollautomatisch und eignet sich besonders gut für ToolJet, da keine manuelle Zertifikatsverwaltung nötig ist.

Starte nach jeder Änderung an der .env den Stack neu:

docker compose up -d --force-recreate tooljet

Verifizieren: Rufe die HTTPS-URL im Browser auf. Das Schloss-Symbol muss grün erscheinen, und ToolJet darf nicht auf http:// weiterleiten. Prüfe außerdem, dass WebSockets funktionieren (App-Builder muss sich ohne Verbindungsfehler öffnen lassen).

Schritt 7: Updates und Backup

Da du den LTS-Tag ce-lts-latest verwendest, zieht ein einfaches pull immer die neueste LTS-Version. Datenbankmigrationen laufen automatisch beim Neustart des Containers:

cd /opt/tooljet
docker compose pull
docker compose up -d

Lege vor jedem Update ein Backup der PostgreSQL-Daten an. Am einfachsten per pg_dump:

docker compose exec postgres pg_dump -U tooljet tooljet_db > /opt/tooljet/backup_$(date +%Y%m%d).sql

Alternativ kannst du das gesamte postgres_data-Verzeichnis sichern, wenn der Container gestoppt ist. Für automatisierte Offsite-Backups empfiehlt sich die Kombination aus pg_dump und rclone, wie sie in der Anleitung MySQL & PostgreSQL Backup automatisieren mit cron beschrieben ist.

Verifizieren: Nach dem Update zeigt docker compose ps wieder alle drei Container als running. Prüfe zusätzlich die ToolJet-Version in der UI unter „Settings → About".

Troubleshooting / Typische Fehler

  1. Container startet nicht, postgres_data-Fehler: Das Verzeichnis /opt/tooljet/postgres_data fehlt. Manuell anlegen (mkdir /opt/tooljet/postgres_data) und neu starten mit docker compose up -d.
  2. OAuth/SAML-Redirect schlägt fehl, falsche Weiterleitungs-URL: TOOLJET_HOST ist ohne Protokoll gesetzt oder zeigt auf die falsche IP. Immer http:// oder https:// voranstellen und die korrekte öffentlich erreichbare Adresse verwenden. Nach Änderung docker compose up -d --force-recreate tooljet.
  3. Kryptofehler beim Start / App zeigt leere Seite: SECRET_KEY_BASE oder LOCKBOX_MASTER_KEY sind leer oder wurden nachträglich geändert. Einmalig gesetzt und bei bestehenden Daten nicht mehr ändern. Prüfe mit docker compose exec tooljet env | grep SECRET_KEY_BASE.
  4. PostgREST crasht in Schleife: PGRST_DB_URI zeigt auf falsche Datenbank oder Zugangsdaten stimmen nicht. URI-Format prüfen: postgres://tooljet:passwort@postgres:5432/tooljet_db. PostgreSQL-Healthcheck abwarten.
  5. Container startet nicht auf ARM64 / Apple Silicon (Exec format error): ToolJet unterstützt offiziell nur linux/amd64. Auf einem Mac mit M-Chip hilft platform: linux/amd64 in der compose.yaml (Rosetta-Emulation) – für produktive Lasten aber auf x86-Hardware wechseln.
  6. Sehr langsamer erster Start (5–10 Minuten): Das ist normal – Datenbankmigrationen laufen beim ersten Start. Logs mit docker compose logs -f tooljet beobachten und nicht ungeduldig neustarten.
  7. E-Mail-Einladungen kommen nicht an: SMTP-Variablen fehlen in der .env. DEFAULT_FROM_EMAIL, SMTP_DOMAIN, SMTP_PORT, SMTP_USERNAME und SMTP_PASSWORD eintragen und Stack neu starten.
  8. Workflows funktionieren nicht bei mehreren Instanzen: Workflows benötigen bei mehreren Worker-Instanzen einen externen Redis. Einen Redis-Container hinzufügen und REDIS_HOST/REDIS_PORT in der .env setzen.
  9. .env versehentlich committed: Sofort aus dem Repository-Verlauf entfernen und alle drei Secrets neu generieren und ersetzen. Die .env unbedingt in .gitignore aufnehmen.

Häufige Fragen

Welchen Image-Tag soll ich verwenden – ce-lts-latest, ee-lts-latest oder latest?

Für rein Open-Source-Betrieb unter AGPL-3.0 verwendest du tooljet/tooljet-ce:ce-lts-latest. Wenn du Enterprise-Features wie SAML SSO, Audit-Log oder benutzerdefinierte Themes benötigst, wechselst du zu tooljet/tooljet:ee-lts-latest (proprietäre Lizenzteile). Den Tag :latest solltest du im Produktivbetrieb grundsätzlich vermeiden – er kann unkontrolliert auf neue Major-Versionen springen und Migrationen ohne Vorwarnung auslösen.

Wie groß sind die Systemanforderungen wirklich?

ToolJet selbst benötigt mindestens 4 GB RAM und 1 vCPU. Für einen produktiven PostgreSQL-Server empfiehlt die offizielle Dokumentation 8 GB RAM und 2 vCPUs. Dazu kommen ca. 8 GB freier Festplattenspeicher für Images und wachsende Datenbankdateien. Für einen Testbetrieb oder ein kleines Team reicht ein VPS mit 4 GB RAM; für produktive Nutzung mit vielen Apps solltest du 8 GB einplanen.

Kann ich ToolJet hinter einem Reverse Proxy mit HTTPS betreiben?

Ja – das ist sogar der empfohlene Weg für produktive Installationen. Setze TOOLJET_HOST auf die HTTPS-URL, binde den ToolJet-Port nur auf Localhost (127.0.0.1:3000:80) und schalte den Reverse Proxy mit SSL-Terminierung davor. Wichtig: WebSocket-Weiterleitung muss aktiviert sein (Upgrade- und Connection-Header), sonst funktioniert der App-Builder nicht korrekt.

Was ist der Unterschied zwischen ToolJet DB und der PostgreSQL-Datenbank?

ToolJet verwendet PostgreSQL auf zwei Arten: Zum einen als App-Datenbank (speichert ToolJet-Konfiguration, Apps, Benutzer) und zum anderen als ToolJet DB – eine integrierte Datenbank-Abstraktionsschicht, über die du direkt in ToolJet-Apps tabellarische Daten speichern und per Drag-and-Drop abfragen kannst, ohne eine externe Datenquelle konfigurieren zu müssen. PostgREST ist der interne REST-Layer, der diese zweite Funktion ermöglicht.

Wie deaktiviere ich die öffentliche Registrierung?

Setze DISABLE_SIGNUPS=true in der .env und starte den tooljet-Container neu. Danach können sich neue Nutzer nur noch über eine E-Mail-Einladung registrieren, die ein bestehender Admin versendet. Das ist für jede produktive, nicht öffentlich zugängliche Installation empfehlenswert.

Wie sichere ich die Daten bei einem Update ab?

Lege vor jedem Update ein pg_dump-Backup an (docker compose exec postgres pg_dump -U tooljet tooljet_db > backup.sql) oder stoppe den Stack und sichere das Verzeichnis ./postgres_data per rsync. Verwende niemals docker compose down -v – das -v-Flag löscht Named Volumes und kann Daten vernichten.

Fazit

ToolJet ist eine ausgereifte Low-Code-Plattform, die KMU-Entwicklerteams echten Mehrwert bringt: Interne Admin-Panels, CRUD-Interfaces und Dashboards entstehen in Stunden statt Wochen, weil 80+ Konnektoren die lästige Anbindungsarbeit abnehmen. Der Docker-Compose-Setup ist nach dieser Anleitung in unter 30 Minuten lauffähig – die Hauptarbeit besteht darin, die drei Secrets sauber zu erzeugen und TOOLJET_HOST korrekt zu setzen.

Gegenüber kommerziellen Alternativen wie Retool punktet ToolJet mit vollständiger Datensouveränität und AGPL-3.0-Lizenz. Der Trade-off: ARM-Hardware ist nicht kompatibel, und der erste Start mit Datenbankmigrationen erfordert Geduld. Für eine produktive Installation lohnt sich außerdem die Investition in einen Reverse Proxy mit HTTPS und automatische pg_dump-Backups – beides ist in wenigen Minuten ergänzt.

Wer nach ToolJet weitere Low-Code- und Datenbank-Tools evaluieren möchte, findet in der Anleitung zu Appsmith mit Docker eine interessante Alternative mit ähnlichem Ansatz. Wer seinen gesamten Docker-Stack sicher und wartbar halten will, findet in Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only für den Produktivbetrieb die passenden nächsten Schritte.

Weiterführende Anleitungen und Quellen

  1. Docker und Docker Compose auf Linux installieren (Ubuntu/Debian): die Self-Hosting-Grundlage
  2. Caddy als Reverse Proxy einrichten: Anfänger-Anleitung mit automatischem HTTPS
  3. MySQL & PostgreSQL Backup automatisieren mit cron: mysqldump, pg_dump, Rotation und rclone-Cloud-Sync
  4. Appsmith mit Docker installieren: Open-Source Low-Code für interne Tools
  5. Docker Compose absichern: Secrets, Healthchecks, Non-Root und Read-Only für den Produktivbetrieb

Offizielle Quellen: ToolJet Docs – Deploying with Docker Compose | ToolJet GitHub Repository | ToolJet Environment Variables Reference | Docker Hub – tooljet/tooljet-ce