350 lines
11 KiB
Markdown
350 lines
11 KiB
Markdown
# Steuerkram
|
||
|
||
Self-hosted Buchhaltungs- und Steueranwendung für deutsche Freiberufler und Kleinunternehmer. Entwickelt als datensouveräne Alternative zu SaaS-Diensten – mit Unterstützung von [Claude Code](https://claude.ai/code).
|
||
|
||

|
||

|
||

|
||
[](LICENSE.md)
|
||
|
||
---
|
||
|
||
## Funktionsumfang
|
||
|
||
| Bereich | Beschreibung |
|
||
|---|---|
|
||
| **Kontenrahmen SKR03** | DATEV-konform, 157 Konten, mit UStVA-Kennzahlen und EÜR-Zeilennummern |
|
||
| **Belegverwaltung** | PDF, PNG, TIFF, ZUGFeRD-XML; SHA-256 Integritätsprüfung; optionale KI-Kontierung |
|
||
| **Buchungen** | EÜR-Modell (Einnahme/Ausgabe); GoBD-konforme Trigger; Stornobuchungen; Journal |
|
||
| **Anlagevermögen** | Anlagenspiegel; automatische Anlagen-Nummerierung; Buchungsworkflow mit Asset-Verknüpfung |
|
||
| **Ausgangsrechnungen** | DIN 5008, PDF-Export via mPDF |
|
||
| **UStVA** | Kennzahlen-Berechnung, ELSTER XML-Export, Drill-down |
|
||
| **EÜR** | Jahresauswertung, PDF-Export, Drill-down |
|
||
| **Kundenverwaltung** | CRUD |
|
||
| **Einstellungen** | Firmendaten, Logo, ELSTER-Steuernummer, Nummernkreise |
|
||
| **Benutzerverwaltung** | Mehrbenutzer, Session-Auth mit 24 h Timeout |
|
||
|
||
---
|
||
|
||
## Schnellstart
|
||
|
||
```bash
|
||
curl -fsSL https://codeberg.org/fds2610/Steuerkram/raw/branch/main/install.sh -o install.sh
|
||
sudo bash install.sh
|
||
cd /opt/Steuerkram
|
||
docker compose up -d
|
||
```
|
||
|
||
---
|
||
|
||
### Manuelle Installation
|
||
|
||
#### 1. Repository klonen
|
||
|
||
```bash
|
||
git clone <repository-url> steuerkram
|
||
cd steuerkram
|
||
```
|
||
|
||
#### 2. Konfiguration anpassen
|
||
|
||
Kopiere `.env.example` nach `.env` und passe die Werte an:
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
```
|
||
|
||
```dotenv
|
||
DB_PASS=sicheres-passwort # Datenbankpasswort – in docker-compose.yml spiegeln
|
||
APP_SECRET=zufaelliger-string # Zufälligen langen String eintragen (für Sessions)
|
||
```
|
||
|
||
Außerdem in `docker-compose.yml` das `MARIADB_PASSWORD` im `db`-Service auf denselben Wert wie `DB_PASS` setzen.
|
||
|
||
#### 3. Container starten
|
||
|
||
```bash
|
||
docker compose up -d
|
||
```
|
||
|
||
Beim ersten Start werden automatisch:
|
||
- die Datenbank initialisiert (`migrations/001_initial_schema.sql`)
|
||
- der SKR03-Kontenrahmen eingespielt (`migrations/002_seed_skr03.sql`)
|
||
- das Docker-Image mit PHP-Abhängigkeiten (mPDF) gebaut
|
||
|
||
#### 4. Anwendung aufrufen
|
||
|
||
```
|
||
http://localhost:8080
|
||
```
|
||
|
||
Beim ersten Aufruf erscheint die **Ersteinrichtung**: dort den ersten Benutzer-Account anlegen. Danach ist die Anwendung passwortgeschützt.
|
||
|
||
Weitere Benutzer können nach dem Login unter **Benutzer** in der Seitenleiste verwaltet werden.
|
||
|
||
#### 5. KI-Beleganalyse einrichten (optional)
|
||
|
||
Die KI-gestützte Belegerkennung ist standardmäßig deaktiviert. Sie kann unter **Einstellungen → KI-Kontierungsvorschlag** aktiviert werden, sobald ein LLM erreichbar ist.
|
||
|
||
**Option A – Lokales Ollama** (kein API-Schlüssel nötig, aber hoher Ressourcenbedarf):
|
||
|
||
```bash
|
||
ollama pull mistral # oder llama3.2 etc.
|
||
```
|
||
|
||
In `.env` ist keine weitere Konfiguration nötig – die App erkennt Ollama auf `localhost:11434` automatisch. Modell und URL können optional überschrieben werden:
|
||
|
||
```dotenv
|
||
OLLAMA_URL=http://localhost:11434
|
||
OLLAMA_MODEL=mistral
|
||
```
|
||
|
||
**Option B – Remote-API** (OpenAI-kompatibel, z. B. OpenAI, OpenRouter, LM Studio):
|
||
|
||
```dotenv
|
||
LLM_API_URL=https://api.openai.com/v1
|
||
LLM_API_KEY=sk-...
|
||
LLM_MODEL=gpt-4o-mini
|
||
```
|
||
|
||
> **Hinweis:** Die Ergebnisqualität hängt stark vom gewählten Modell ab. Tests mit `mistral` (lokal via Ollama) lieferten bisher mäßige Ergebnisse.
|
||
|
||
#### 6. Firmendaten hinterlegen
|
||
|
||
Nach dem ersten Login unter **Einstellungen** Firmendaten, Logo und ELSTER-Steuernummer eintragen. Diese Angaben erscheinen auf Ausgangsrechnungen und im EÜR-Export.
|
||
|
||
## Port ändern
|
||
|
||
Der Standard-Port ist `8080`. Um ihn zu ändern, passe in `docker-compose.yml` die `ports`-Zeile an:
|
||
|
||
```yaml
|
||
ports:
|
||
- "9090:80" # Beispiel: Port 9090 auf dem Host
|
||
```
|
||
|
||
## Upload-Limit anpassen
|
||
|
||
Die maximale Dateigröße für Beleganhänge ist auf **20 MB** voreingestellt (`php/uploads.ini`). Um das Limit zu ändern, die Werte in dieser Datei anpassen und den Container neu bauen:
|
||
|
||
```ini
|
||
upload_max_filesize = 20M
|
||
post_max_size = 20M
|
||
```
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
## Belege automatisch aus Nextcloud importieren
|
||
|
||
Belege können automatisch aus einem Nextcloud-Ordner via WebDAV importiert werden. Das CLI-Skript `scripts/nextcloud-import.php` liest alle unterstützten Dateien (PDF, JPEG, PNG, TIFF, XML) aus dem konfigurierten Ordner, legt sie als Belege an und verschiebt sie anschließend in einen Erledigte-Ordner (oder löscht sie, wenn kein Ziel-Ordner konfiguriert ist).
|
||
|
||
### Konfiguration
|
||
|
||
Die Zugangsdaten werden in der Steuerkram-UI gepflegt: **Einstellungen → Nextcloud-Belegimport**.
|
||
|
||
Empfehlung: Ein Nextcloud-App-Passwort verwenden (Nextcloud → Einstellungen → Sicherheit → App-Passwörter).
|
||
|
||
### Manueller Aufruf
|
||
|
||
```bash
|
||
docker compose exec web php scripts/nextcloud-import.php
|
||
```
|
||
|
||
### Automatisch per Cron (auf dem Host)
|
||
|
||
Für den automatischen Abruf muss ein Cron-Eintrag auf dem Host angelegt werden. Dabei gibt es zwei Varianten:
|
||
|
||
**Option 1: Root-Crontab** (`sudo crontab -e`)
|
||
|
||
```cron
|
||
*/15 * * * * docker compose -f /opt/steuerkram/docker-compose.yml exec -T web \
|
||
php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
||
```
|
||
|
||
Kein `sudo` im Befehl nötig. Nachteil: Root-Crons sind schwerer zu überblicken.
|
||
|
||
**Option 2: User-Crontab** (`crontab -e`) – empfohlen
|
||
|
||
Damit `docker compose exec` ohne `sudo` funktioniert, muss der User in der Docker-Gruppe sein:
|
||
|
||
```bash
|
||
sudo usermod -aG docker $USER
|
||
# Danach neu einloggen
|
||
```
|
||
|
||
Anschließend in der User-Crontab (ohne `sudo`):
|
||
|
||
```cron
|
||
*/15 * * * * docker compose -f /home/fds/projects/Steuerkram/docker-compose.yml exec -T web \
|
||
php scripts/nextcloud-import.php >> /var/log/steuerkram-import.log 2>&1
|
||
```
|
||
|
||
> **Hinweis:** Das `-T`-Flag ist bei Cron zwingend erforderlich – ohne TTY schlägt `docker compose exec` sonst still fehl.
|
||
>
|
||
> **Empfehlung:** User-Crontab + Docker-Gruppe. Das ist konsistent mit dem bestehenden Setup (alle anderen Jobs laufen ebenfalls in der User-Crontab).
|
||
|
||
Das Skript gibt beim Start eine Zusammenfassung aus (importiert / übersprungen / Fehler) und beendet sich mit Exit-Code 1 bei Fehlern.
|
||
|
||
## Datenpersistenz
|
||
|
||
| Pfad | Inhalt |
|
||
|---|---|
|
||
| `./data/mariadb/` | MariaDB-Datenbankdateien |
|
||
| Docker Volume `uploads` | Hochgeladene Belege |
|
||
|
||
Beide Pfade liegen außerhalb des Containers und bleiben bei `docker compose down` erhalten.
|
||
|
||
## Systemd-Service einrichten
|
||
|
||
Damit Steuerkram automatisch beim Systemstart startet und als Dienst verwaltet werden kann, liegt im Repository die Datei `steuerkram.service`.
|
||
|
||
#### 1. Service-Datei installieren
|
||
|
||
```bash
|
||
sudo cp steuerkram.service /etc/systemd/system/steuerkram.service
|
||
```
|
||
|
||
Die Datei setzt `WorkingDirectory=/opt/Steuerkram` voraus. Falls das Repository in ein anderes Verzeichnis geklont wurde, den Pfad in der Service-Datei anpassen:
|
||
|
||
```bash
|
||
sudo nano /etc/systemd/system/steuerkram.service
|
||
# WorkingDirectory= auf das tatsächliche Installationsverzeichnis setzen
|
||
```
|
||
|
||
#### 2. Service aktivieren und starten
|
||
|
||
```bash
|
||
sudo systemctl daemon-reload
|
||
sudo systemctl enable steuerkram # automatisch beim Systemstart
|
||
sudo systemctl start steuerkram
|
||
```
|
||
|
||
#### 3. Status prüfen
|
||
|
||
```bash
|
||
sudo systemctl status steuerkram
|
||
journalctl -u steuerkram -f # Live-Log inkl. Migrations-Ausgabe
|
||
```
|
||
|
||
#### Wichtige Service-Befehle
|
||
|
||
| Befehl | Wirkung |
|
||
|---|---|
|
||
| `sudo systemctl start steuerkram` | Container starten |
|
||
| `sudo systemctl stop steuerkram` | Container stoppen |
|
||
| `sudo systemctl restart steuerkram` | Neustart (z.B. nach Update) |
|
||
| `sudo systemctl status steuerkram` | Aktueller Status |
|
||
|
||
## Backup
|
||
|
||
```bash
|
||
bash scripts/backup.sh
|
||
```
|
||
|
||
Das Skript erstellt ein Dump der Datenbank sowie ein Archiv der Uploads im Verzeichnis `backups/`.
|
||
|
||
## Update
|
||
|
||
Seit dem 11.04.2026 bin ich mit meiner Software für mich selber produktiv. Ab diesem Zeitpunkt sollten keine breaking changes mehr vorkommen.
|
||
|
||
Datenbankmigrationen werden **automatisch** beim nächsten Container-Start eingespielt – kein manueller Eingriff nötig. Das Script `scripts/migrate.php` prüft beim Start, welche Migrations-Dateien noch nicht angewendet wurden, und führt sie der Reihe nach aus.
|
||
|
||
### Vollständige Update-Anleitung
|
||
|
||
Die folgenden Schritte sichern einen vollständigen und sicheren Update-Ablauf. Alle Befehle im Steuerkram-Verzeichnis ausführen.
|
||
|
||
#### Schritt 1 – Datenbank sichern
|
||
|
||
Vor jedem Update ein Backup erstellen:
|
||
|
||
```bash
|
||
bash scripts/backup.sh
|
||
```
|
||
|
||
Das Backup landet in `backups/`. Alternativ manuell:
|
||
|
||
```bash
|
||
docker compose exec db mariadb-dump -u steuerkram -psteuerkram steuerkram \
|
||
> ~/steuerkram_backup_$(date +%Y%m%d_%H%M).sql
|
||
```
|
||
|
||
#### Schritt 2 – Aktuellen Code holen
|
||
|
||
```bash
|
||
git pull
|
||
```
|
||
|
||
Prüfen, ob neue Migrations-Dateien enthalten sind:
|
||
|
||
```bash
|
||
git log --oneline -5
|
||
```
|
||
|
||
#### Schritt 3 – Container neu bauen und starten
|
||
|
||
```bash
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Dieser Befehl baut das PHP-Image neu (falls sich `Dockerfile` oder `composer.json` geändert haben) und startet alle Container. Der Web-Container führt beim Start automatisch `scripts/migrate.php` aus.
|
||
|
||
#### Schritt 4 – Migrationen prüfen
|
||
|
||
```bash
|
||
docker compose logs web | grep migrate
|
||
```
|
||
|
||
Erwartete Ausgabe bei erfolgreicher Migration:
|
||
|
||
```
|
||
[migrate] Starte Migrations-Prüfung...
|
||
[migrate] Führe aus: NNN_beschreibung.sql
|
||
[migrate] N Migration(en) erfolgreich angewendet.
|
||
```
|
||
|
||
Oder wenn alles bereits aktuell ist:
|
||
|
||
```
|
||
[migrate] Datenbank ist aktuell – keine Migrationen notwendig.
|
||
```
|
||
|
||
Falls die Ausgabe einen Fehler enthält, das Backup aus Schritt 1 einspielen:
|
||
|
||
```bash
|
||
docker compose exec -T db mariadb -u steuerkram -psteuerkram steuerkram \
|
||
< ~/steuerkram_backup_YYYYMMDD_HHMM.sql
|
||
```
|
||
|
||
#### Schritt 5 – Anwendung prüfen
|
||
|
||
```bash
|
||
docker compose ps # alle Container müssen "running" sein
|
||
docker compose logs web # keine PHP-Fehler oder Exceptions
|
||
```
|
||
|
||
Anschließend im Browser unter `http://localhost:8080` (oder dem konfigurierten Port) einloggen und stichprobenartig Belege und Buchungen prüfen.
|
||
|
||
---
|
||
|
||
## Dokumentation
|
||
|
||
| Dokument | Inhalt |
|
||
|---|---|
|
||
| [Installation](docs/installation.md) | Docker-Setup, Systemd-Service, Port, Upload-Limit |
|
||
| [Konfiguration](docs/konfiguration.md) | Firmendaten, Nummernkreise, KI-Beleganalyse, Nextcloud-Import |
|
||
| [Funktionen](docs/funktionen.md) | Alle Features im Detail |
|
||
| [Anlagevermögen](docs/anlagevermögen.md) | Anlagenspiegel, Buchungsworkflow, Nummernkreis |
|
||
| [Update & Backup](docs/update-backup.md) | Update-Anleitung, Backup, Datenpersistenz |
|
||
| [Automatisierung](docs/automatisierung.md) | Automatisierungsagent, Ideenagent, Support |
|
||
| [Datenbankstruktur](docs/datenbankstruktur.md) | Tabellen, Spalten, Fremdschlüssel, GoBD-Mechanismen |
|
||
| [Berechnungslogik](docs/berechnungslogik.md) | UStVA-Kennzahlen und EÜR-Zuordnungsregeln |
|
||
| [Kontenrahmen](docs/kontenrahmen.md) | Vollständige SKR03-Kontenliste |
|
||
|
||
---
|
||
|
||
## GoBD-Hinweise
|
||
|
||
- Gebuchte Sätze können nicht geändert oder gelöscht werden (MariaDB `BEFORE UPDATE/DELETE` Trigger).
|
||
- Korrekturen erfolgen ausschließlich über Stornobuchungen.
|
||
- Jeder hochgeladene Beleg erhält einen SHA-256 Hash zur Integritätsprüfung.
|