entrytwo

docs / getting-started / installation.md

Installation

Diese Anleitung bringt eine selbst gehostete entrytwo-Instanz zum Laufen.

entrytwo ist KI-native doppelte Buchführung mit Git-ähnlichem Datenmodell. Die KI bucht echte Journalbuchungen bei hoher Sicherheit. Vollständige Historie, Branches, Blame. Self-hosted.


Betrieb: Die meisten Produktions-Setups nutzen einen VPS mit Docker und HTTPS. Du kannst genauso lokal installieren und produktiv nutzen (z. B. auf dem Mac): dieselbe volle App, wie klassische Buchhaltungssoftware ohne Cloud. Läuft auf deinem VPS oder lokal.

Lass die KI die Installation machen

Kein Terminal-Mensch? Du kannst entrytwo trotzdem installieren. Gib einem KI-Coding-Agenten diese Seite (und das Repo) und bitte ihn, die Installation für dich zu erledigen — z. B. Claude Code, OpenClaw, Hermes, Cursor oder ein vergleichbares Tool, das Befehle auf deinem Rechner oder VPS ausführen kann. Sag ihm dein Ziel (lokal Mac vs. VPS + Domain), schick Fehlermeldungen zurück, wenn etwas scheitert, und teile Secrets (Passwörter, API-Keys) nicht in Chats, denen du nicht vertraust. Die Schritte unten bleiben die Quelle der Wahrheit; der Agent führt dich nur durch. Kanonische Agent-Dateien: llms.txt und SKILL.md.

Voraussetzungen

Wähle einen der zwei unterstützten Installationswege:

Weg A — Git / npm (klonen und lokal bauen)

  • Node.js 22.12 oder neuer, auf dem aktuellen 22.x (Prisma-Engines lehnen früheres 22.x ab; ein pauschales >= 22 reicht nicht)
  • npm, Git und openssl
  • PostgreSQL 16 (lokal oder per Docker)
  • Optional, aber empfohlen: Docker & Docker Compose (für Postgres)

Node von der offiziellen nodejs.org Download-/Versionsmanager-Seite installieren, dann prüfen:

node --version   # erwartet v22.12.0 oder ein späteres 22.x (Pin: v22.23.4)

Ohne nvm: Diese Befehle installieren das offizielle 22.23.4-Binary in deinem Home-Verzeichnis, prüfen die Prüfsumme und ergänzen PATH im aktuellen Terminal. Das entspricht dem exakten .nvmrc-Pin des Repositorys. 22.12.0 ist das Minimum, nicht der empfohlene Patchstand. Unterstützt werden Debian/Ubuntu (glibc) x64/ARM64 und macOS Intel/Apple Silicon; Alpine/musl braucht einen anderen Build. Benötigt curl, tar und sha256sum (Linux) oder shasum (macOS). Vor npm ci ausführen:

NODE_VERSION=22.23.4
case "$(uname -s)/$(uname -m)" in
  Linux/x86_64) NODE_PLATFORM=linux-x64 ;;
  Linux/aarch64|Linux/arm64) NODE_PLATFORM=linux-arm64 ;;
  Darwin/x86_64) NODE_PLATFORM=darwin-x64 ;;
  Darwin/arm64) NODE_PLATFORM=darwin-arm64 ;;
  *) echo "Unsupported platform; use nodejs.org/en/download" >&2; exit 1 ;;
esac
NODE_HOME="$HOME/.local/share/node-v$NODE_VERSION-$NODE_PLATFORM"
(
  set -eu
  NODE_TMP="$(mktemp -d)"
  trap 'rm -rf "$NODE_TMP"' EXIT
  cd "$NODE_TMP"
  ARCHIVE="node-v$NODE_VERSION-$NODE_PLATFORM.tar.gz"
  curl -fLO "https://nodejs.org/dist/v$NODE_VERSION/$ARCHIVE"
  curl -fLO "https://nodejs.org/dist/v$NODE_VERSION/SHASUMS256.txt"
  grep "  $ARCHIVE$" SHASUMS256.txt > CHECKSUM
  if command -v sha256sum >/dev/null 2>&1; then
    sha256sum -c CHECKSUM
  else
    shasum -a 256 -c CHECKSUM
  fi
  mkdir -p "$NODE_HOME"
  tar -xzf "$ARCHIVE" --strip-components=1 -C "$NODE_HOME"
) && export PATH="$NODE_HOME/bin:$PATH" && node --version

Für neue Terminals export PATH="<installierter NODE_HOME-Pfad>/bin:$PATH" in die eigene ~/.bashrc (Linux bash) oder ~/.zshrc (macOS zsh) eintragen oder manuell wiederholen. Die Befehle ändern keine Shell-Profile und brauchen kein sudo. Mit bereits installiertem nvm stattdessen im Clone nvm install && nvm use ausführen.

Weg B — Docker Compose pull (veröffentlichtes Image, ohne Clone)

  • Docker Engine oder Docker Desktop mit Docker Compose v2
  • curl und openssl zum Herunterladen und Erzeugen von Secrets

Für Docker werden Node.js, PostgreSQL und Git auf dem Host nicht benötigt.

Optional, aber nützlich:

  • Domain + Reverse-Proxy (Caddy, Nginx, Traefik) für HTTPS
  • SMTP für Magic-Link-Login (und Einladungs-E-Mails)
  • Google- und/oder Microsoft-Entra-ID-OAuth-Apps für Mitarbeiter-Login
  • LLM-API-Key (OpenAI, Anthropic, xAI usw.)

Weg A: Git / npm (Entwicklung und Anpassungen)

Das Quellcode-Repository ist öffentlich. Es gibt keine zusätzliche Unterverzeichnisebene entrytwo_v1 im Clone.

git clone https://github.com/felixkrusch/entrytwo.git
cd entrytwo
node --version   # erwartet v22.12.0 oder ein späteres 22.x
cp .env.example .env
npm ci

Wenn npm oder Prisma danach ein Update- oder Security-Banner zeigt: Lockfile-Versionen behalten. npm audit fix oder npm audit fix --force nicht als Installationsschritt ausführen.

Setze in .env DATABASE_URL, AUTH_SECRET, ENCRYPTION_KEY, JOB_RUNNER_SECRET und deinen LLM-Anbieter/Key. Erzeuge jedes Secret unabhängig mit openssl rand -hex 32 (Werte nicht wiederverwenden, nicht in Agent-Chats einfügen). ENCRYPTION_KEY muss genau 64 Hex-Zeichen haben. openssl rand -base64 48 ist für AUTH_SECRET und JOB_RUNNER_SECRET ebenfalls gültig (≥ 32 Zeichen), aber eine Konvention verwenden: hex 32 für alle. xAI-Beispiel (Modell-ID aus deinem xAI-Konto, nicht raten):

NEXT_LLM_PROVIDER=xai
NEXT_LLM_MODEL=<Modell-ID aus der xAI-Konsole>
XAI_API_KEY=<dein Key>

Bewahre den ursprünglichen ENCRYPTION_KEY für Wiederherstellungen auf. Falls noch keine lokale Datenbank läuft, passt dieses Beispiel zu DATABASE_URL aus der Vorlage:

docker run --name entrytwo-dev-db \
  -e POSTGRES_USER=entrytwo \
  -e POSTGRES_PASSWORD=entrytwo_dev_password \
  -e POSTGRES_DB=entrytwo \
  -p 127.0.0.1:5432:5432 \
  -v entrytwo_dev_postgres:/var/lib/postgresql/data \
  -d postgres:16-alpine

i=0
until docker exec entrytwo-dev-db pg_isready -U entrytwo -d entrytwo; do
  i=$((i + 1))
  if [ "$i" -ge 30 ]; then
    echo "PostgreSQL wurde nicht bereit" >&2
    exit 1
  fi
  sleep 1
done

Diese Zugangsdaten sind ausschließlich für lokale Entwicklung. Bei einer vorhandenen Datenbank den Beispielcontainer (und die pg_isready-Schleife) überspringen und DATABASE_URL anpassen. Der mitgelieferte Compose-db-Service veröffentlicht keinen Host-Port; docker compose up -d db allein reicht daher für eine native Node.js-App nicht. Warte auf die Bereitschaft von PostgreSQL und führe dann aus:

npx prisma generate
npx prisma migrate deploy
mkdir -p .data/files .data/backups
npm run dev

Öffne http://localhost:3000, lege den ersten Admin an und schließe das Firmen-Onboarding ab; dabei wird der Kontenplan angelegt. Der Sofort-E-Mail-Login funktioniert nur in der Entwicklung. Für Hintergrundjobs starte in einem zweiten Terminal node --env-file=.env scripts/job-worker.mjs. Echte Rechnungs-E-Mails benötigen SMTP.

Keine echten Installationen seeden. npx prisma db seed leert vorhandene Anwendungstabellen, bevor Beispieldaten angelegt werden. Nur für wegwerfbare Entwicklungsdatenbanken verwenden, niemals als Installations- oder Update-Schritt. prisma migrate dev ist für die Entwicklung von Schemaänderungen; veröffentlichte Migrationen werden mit migrate deploy angewendet.

Weg B: Docker Compose (veröffentlichte Images)

  1. Verzeichnis erstellen und öffentliche Installationsdateien herunterladen:
mkdir entrytwo && cd entrytwo
RELEASE_URL=https://github.com/felixkrusch/entrytwo-releases/releases/latest/download
curl -fL "$RELEASE_URL/compose.yaml" -o compose.yaml
curl -fL "$RELEASE_URL/entrytwo.env.example" -o .env.example
  1. Beispiel-Umgebung kopieren:
umask 077
cp .env.example .env
  1. .env bearbeiten und mindestens setzen:
  • DATABASE_URL (oder Compose-Defaults nutzen)
  • POSTGRES_PASSWORD (von Compose benötigt; unabhängig openssl rand -hex 32)
  • AUTH_SECRET – unabhängig openssl rand -hex 32 (≥ 32 Zeichen)
  • ENCRYPTION_KEY – unabhängig openssl rand -hex 32 (genau 64 Hex-Zeichen)
  • JOB_RUNNER_SECRET – unabhängig openssl rand -hex 32
  • UPDATER_TOKEN – unabhängig openssl rand -hex 32 (für den Updater-Sidecar) - LICENSE_VERIFY_URL=https://entrytwo.com/api/license/verify (später nötig, um einen bezahlten et1.-Key zu aktivieren; die 30-Tage-Testphase braucht keinen Key. Menschen kaufen unter Kaufen; Agenten dürfen Stripe-Checkout nicht abschließen.)
  • Mindestens einen LLM-Key, wenn du KI/Chat willst. xAI: NEXT_LLM_PROVIDER=xai, XAI_API_KEY, NEXT_LLM_MODEL = Modell-ID aus deinem xAI-Konto
  • NEXT_LLM_PROVIDER und NEXT_LLM_MODEL

Jedes Secret separat erzeugen, Werte nicht wiederverwenden, nicht in Agent-Chats einfügen. openssl rand -base64 48 ist für Auth-/Job-/Updater-Secrets ebenfalls gültig, aber eine Konvention verwenden: hex 32 für alle.

  1. Stack starten:
docker compose config --quiet
docker compose pull
docker compose up -d

Das startet:

  • app (Next.js auf Port 3000)
  • db (PostgreSQL)
  • worker (Hintergrundjobs)
  • updater (isolierter Sidecar für signierte Updates – siehe Self-Hosted Updates)
  • redis
  1. Migrationen laufen automatisch. Die mitgelieferten Werte für COSIGN_IDENTITY und UPDATE_MANIFEST_URL beibehalten. Immer aus dem Installationsverzeichnis heraus starten. Für einen lokalen HTTP-Test AUTH_ALLOW_HTTP=true setzen; öffentliche Server benötigen HTTPS.

  2. http://localhost:3000 öffnen

Beim ersten Besuch ohne Admin-Benutzer kannst du das initiale ADMIN-Konto anlegen.

Das Quellcode-Repository ist öffentlich, wird für diese Image-Installation aber nicht benötigt. App und Updater sind getrennte öffentliche Container-Images; ein GitHub-Login ist nicht erforderlich. Port 3000 ist standardmäßig nur an 127.0.0.1 gebunden. Der Updater hat privilegierten Docker-Socket-Zugriff und darf nicht öffentlich erreichbar sein.

Auch auf einem Laptop laufen diese Container im Produktionsmodus: vollständiges SMTP/OAuth und TOTP für Administratoren sind erforderlich. Für Rechnungs-E-Mails werden SMTP und der Worker auch dann benötigt, wenn OAuth die Anmeldung übernimmt.


Handler-Modus (ein Compose pro Mandant)

entrytwo ist nicht mandantenfähig. Ein laufender Stack = eine juristische Person.

Wenn du Bücher für mehrere Firmen führst (Kanzlei, Agentur, „Handler“), bekommt jeder Mandant ein eigenes Compose-Projekt:

  • Eigenes Verzeichnis (mindestens eigene .env, Volumes und Backups)
  • Eigener COMPOSE_PROJECT_NAME (z. B. entrytwo-acme)
  • Eigener, an Loopback gebundener Host-Port (127.0.0.1:3000:3000, 127.0.0.1:3001:3000, …)
  • Eigene Secrets
  • Eigene .etbackup-Dateien — niemals Backup von Firma A in Firma B einspielen

RAM: ≥ 2 GB pro Stack. Chat-Lock für Bulk-Arbeit durch Agenten; vor Massenimport branchen; nie unter 0,85 Confidence buchen; ein Mensch schließt die Periode.

Eine bezahlte Lizenz deckt Installationen für Unternehmen ab, die dir gehören. Fremde Mandanten benötigen eigene Lizenzen. Der öffentliche Quellcode steht unter einer proprietären Source-Available-Lizenz, nicht unter einer Open-Source-Lizenz.


Umgebungsvariablen (die wichtigsten)

.env.example kopieren und ausfüllen:

Erforderlich (lokal oder Produktion)

  • DATABASE_URL
  • AUTH_SECRET (≥ 32 Zeichen)
  • POSTGRES_PASSWORD (bei Compose)
  • LICENSE_VERIFY_URL — https://entrytwo.com/api/license/verify (Aktivierung bezahlter Keys; Testphase braucht keinen Key)

In Produktion erforderlich (App startet nicht sauber / Health bleibt degraded ohne diese)

  • ENCRYPTION_KEY (64 Hex-Zeichen)
  • JOB_RUNNER_SECRET
  • AUTH_URL (öffentliche Origin, z. B. https://books.example.com)
  • AUTH_TRUST_HOST=true (hinter nginx/caddy/traefik)
  • Mindestens eine echte Anmeldemethode:
    • SMTP: SMTP_HOST, SMTP_USER, SMTP_PASS (idealerweise SMTP_FROM), und/oder
    • Google: GOOGLE_CLIENT_ID + GOOGLE_CLIENT_SECRET, und/oder
    • Microsoft: MICROSOFT_ENTRA_ID_ID + MICROSOFT_ENTRA_ID_SECRET (+ Issuer)

Für den veröffentlichten Docker-Stack erforderlich

  • UPDATER_TOKEN – Shared Secret für den Updater-Sidecar

Für KI-Funktionen

  • LLM-Key + NEXT_LLM_PROVIDER / NEXT_LLM_MODEL
  • xAI-Beispiel: NEXT_LLM_PROVIDER=xai, XAI_API_KEY, NEXT_LLM_MODEL auf eine Modell-ID aus deinem xAI-Konto (aus der Konsole kopieren, Version nicht raten)

Für Produktion / Updates

  • UPDATE_MANIFEST_URL – zeigt auf dein signiertes Release-Manifest
  • Cosign-Einstellungen (COSIGN_IDENTITY, COSIGN_PUBLIC_KEY usw.)
  • STRIPE_WEBHOOK_SECRET / PayPal-Secrets (bei Processor-Feeds)

Vollständige Liste in der App-.env.example. Auth-Go-Live: VPS-Auth-Install.md.


Manuelles Postgres (ohne Docker)

  1. Datenbank anlegen:
 CREATE USER entrytwo WITH PASSWORD 'entrytwo_dev_password';
 CREATE DATABASE entrytwo OWNER entrytwo;
  1. In .env setzen:
DATABASE_URL="postgresql://entrytwo:entrytwo_dev_password@localhost:5432/entrytwo"

Das SQL als PostgreSQL-Administrator ausführen. Das Passwort dient nur als lokales Entwicklungsbeispiel. Für echte Installationen ein frisches Passwort verwenden. Als Datenbankeigentümer hat die App-Rolle die nötigen Schema-Rechte.

  1. Im geklonten Repository Abhängigkeiten installieren und Migrationen anwenden:
npm ci
npx prisma generate
npx prisma migrate deploy
mkdir -p .data/files .data/backups
npm run dev

Erster Admin (Bootstrap)

entrytwo ist so gebaut, dass der allererste Benutzer einer frischen Installation ADMIN wird.

  • Existiert kein ADMIN, erlaubt der Anmelde-/Onboarding-Flow die Erstellung (Firma, Sprache, Standard-Kontenplan).
  • Danach kommen weitere Benutzer nur per Einladung (Admin → Benutzer). Anmeldung mit genau der eingeladenen E-Mail über Google, Microsoft oder Magic Link.
  • Rollen: ADMIN, ACCOUNTANT oder VIEWER.
  • In Produktion muss ADMIN TOTP (2FA) einrichten, bevor die App nutzbar ist.

Siehe Erste Schritte.


Authentifizierung (Kurzüberblick)

UmgebungAnmeldung
Lokale EntwicklungSofort-E-Mail („Weiter“) – kein SMTP nötig
ProduktionMagic Link (SMTP) und/oder Google-OAuth und/oder Microsoft Entra ID

Sofort-E-Mail ist bei NODE_ENV=production deaktiviert. OAuth-Redirect-URIs: {AUTH_URL}/api/auth/callback/google und .../microsoft-entra-id.


Health und grundlegende Prüfung

  • App-Health: GET /api/health
  • Produktion sollte "ready": true und auth.productionReady: true melden
  • Nach docker compose up -d hat der App-Container einen Healthcheck auf diesem Endpoint

Optional: lokaler Git/npm-Smoke (nur frische Installationen)

Nur auf einer brandneuen lokalen npm run dev-Installation verwenden. Legt den ersten Admin und die Firma an. Nicht gegen eine echte Geschäftsinstanz, einen Docker-Produktionsstack oder eine Datenbank mit bestehenden Benutzern ausführen.

POST /api/auth/dev liefert in Produktion (NODE_ENV=production) 403, einschließlich veröffentlichter Docker-Images.

curl --fail-with-body --silent --show-error http://localhost:3000/api/health
node scripts/check-install.mjs http://localhost:3000

# Nur statt Browser-Onboarding, mit den gewünschten Inhaberdaten:
node scripts/check-install.mjs http://localhost:3000 --bootstrap --email you@example.com --company "Meine Firma"

Der Bootstrap-Befehl prüft Entwicklungs-Provider und verweigert Änderungen, wenn bereits ein Administrator existiert. Er führt Onboarding vor dem Dev-Login aus, prüft die ADMIN-Session und hält Cookies nur im Speicher, ohne Cookie-Datei. Die App initialisiert .data/files und .data/backups auch beim Start; der explizite mkdir-Schritt zeigt das erforderliche Speicherlayout. Agenten finden llms.txt, AGENTS.md und skills/entrytwo/SKILL.md auch lokal im Clone.


Produktion / VPS (kurz)

Vor dem ersten produktiven Start:

  1. Secrets — AUTH_SECRET, ENCRYPTION_KEY, JOB_RUNNER_SECRET, POSTGRES_PASSWORD (pro Installation neu).
  2. Anmeldung — volles SMTP (SMTP_HOST + USER + PASS) und/oder Google/Microsoft-OAuth. Sofort-E-Mail ist in Produktion aus.
  3. Öffentliche URL — AUTH_URL=https://deine.domain, AUTH_TRUST_HOST=true.
  4. DNS — A-Record auf die VPS-IP bevor HTTPS erwartet wird. Nach spät gesetztem DNS Reverse-Proxy neu starten (z. B. Caddy).
  5. Deploy — Weg B: docker compose pull, dann docker compose up -d; der Entrypoint führt Migrationen aus. Weg A läuft nativ: prisma migrate deploy, npm run build, dann npm start und separat node --env-file=.env scripts/job-worker.mjs unter einem Prozessmanager mit derselben Umgebung. /api/health → ready: true prüfen.
  6. Erster Admin — Bootstrap, danach TOTP für ADMIN.

RAM: ≥ 2 GB für einen Stack; ~4 GB, wenn mehrere Installationen auf einem Host laufen.

Installationsdateien und Update-Manifeste: öffentliche Releases. Quellcode: felixkrusch/entrytwo.


Typische nächste Schritte

  • Erste Schritte lesen
  • Mindestens einen LLM-Key setzen und den Chat testen
  • SMTP und/oder OAuth konfigurieren, damit Teammitglieder sich anmelden können
  • (Produktion) HTTPS, starke Secrets und die VPS-Auth-Checkliste
  • (Später) Bank-Feeds, Updates und Lizenzierung

Siehe auch: