Installation
Sie installieren heinzelhaus auf einem eigenen Server, entweder mit einem Skript auf einem Proxmox-Host oder mit dem Installationsskript auf einem Debian- oder Ubuntu-Server. Beide Wege richten Docker, die Konfiguration und alle Dienste ein. Am Ende öffnen Sie die Adresse im Browser und legen das erste Administratorkonto an.
Damit heinzelhaus auf Ihrem Server läuft und Ihre Mitarbeitenden es im Browser öffnen können.
Sie brauchen: root-Zugang zum Server oder zum Proxmox-Host, einen Server nach den Systemvoraussetzungen und den Zugang zum Programmstand (siehe unten).
Haben Sie heinzelhaus schon vor Version 1.0 unter dem Namen CasaTastic eingerichtet? Dann installieren Sie nicht neu, sondern ziehen einmalig um: Umzug von CasaTastic auf heinzelhaus.
Zwei Wege im Überblick
Abschnitt betitelt „Zwei Wege im Überblick“| Weg | Wann | Was Sie tun |
|---|---|---|
| A: Proxmox | Sie betreiben einen Proxmox-Host und möchten heinzelhaus in einem eigenen Container | Auf dem Proxmox-Host ein Skript laden und ausführen. Es legt den Container an und installiert darin alles. |
| B: Server oder virtuelle Maschine | Debian oder Ubuntu läuft bereits, als eigener Rechner, virtuelle Maschine oder bei einem Cloud-Anbieter | Programmstand mit git holen und install.sh ausführen |
Weg A installiert zunächst für das lokale Netz (Port 3000). Eine Domain mit https wählen Sie bei Weg B gleich bei der Installation.
Der Zugang zum Programmstand
Abschnitt betitelt „Der Zugang zum Programmstand“heinzelhaus liegt in einem privaten Repository des Herstellers unter https://git.it-flores.de/l.flores/heinzelhaus. Für den Abruf brauchen Sie ein Lesetoken. Dasselbe Token braucht später der Updater, damit das Ein-Klick-Update neue Stände holen kann: Es bleibt deshalb in der Git-Adresse (origin) im Projektordner gespeichert, in der Datei .git/config, die nur root lesen darf.
Weg A: Proxmox
Abschnitt betitelt „Weg A: Proxmox“Damit heinzelhaus in einem eigenen, leichtgewichtigen Container (LXC) läuft, getrennt von allem anderen auf dem Host.
Sie brauchen: root auf dem Proxmox-Host (nicht im Container) und das Lesetoken.
-
Geben Sie das Token auf dem Proxmox-Host an:
Terminal-Fenster export HH_TOKEN=<Lesetoken>Ohne die Variable fragt das Skript später nach dem „Forgejo-Lesetoken“.
-
Laden Sie das Skript herunter. Der Abruf in zwei Schritten sorgt dafür, dass ein fehlgeschlagener Download sichtbar scheitert, bevor etwas angelegt wird:
Terminal-Fenster curl -fsSL -H "Authorization: token $HH_TOKEN" \"https://git.it-flores.de/api/v1/repos/l.flores/heinzelhaus/raw/scripts/proxmox-install.sh?ref=main" \-o proxmox-install.sh -
Führen Sie es aus:
Terminal-Fenster bash proxmox-install.sh -
Warten Sie einige Minuten. Das Skript meldet jeden Schritt, zum Beispiel „Container 105 anlegen“ und „Im Container installieren (das dauert einige Minuten)“.
-
Am Ende nennt es die Adresse, den Hostnamen und das Root-Passwort des Containers, zum Beispiel
http://192.168.1.20:3000. Notieren Sie das Root-Passwort. Es ist nur nötig, wenn Sie sich später im Container anmelden. -
Öffnen Sie die Adresse im Browser und fahren Sie mit der Ersten Einrichtung fort.
Was das Skript einrichtet
Abschnitt betitelt „Was das Skript einrichtet“- Es prüft, ob es auf einem Proxmox-Host läuft (
pct,pveam,pvesh,pvesm). - Es wählt den Speicher: bevorzugt
local-lvm, sonstlocal-zfs, sonst den ersten aktiven Speicher mit Inhalt „rootdir“. Es nimmt die nächste freie Container-ID. - Es lädt bei Bedarf die neueste Debian-12-Vorlage.
- Es legt einen unprivilegierten Container an, der beim Start des Hosts mitstartet, und erlaubt darin Docker (
nesting=1,keyctl=1). - Es überträgt das Token als Datei in den Container, nicht über die Befehlszeile, klont das Repository nach
/opt/heinzelhausund ruft dortinstall.shim Modus für das lokale Netz mit der IP-Adresse des Containers auf.
Einstellbar mit Umgebungsvariablen
Abschnitt betitelt „Einstellbar mit Umgebungsvariablen“Setzen Sie die Variablen vor dem Aufruf, zum Beispiel HH_CTID=120 bash proxmox-install.sh. Die Vorgaben stehen in der Klammer.
| Variable | Bedeutung (Vorgabe) |
|---|---|
HH_TOKEN |
Lesetoken, Pflicht |
HH_CTID |
Container-ID (die nächste freie) |
HH_HOSTNAME |
Hostname des Containers (heinzelhaus) |
HH_STORAGE |
Speicher für das Wurzeldateisystem (wird ermittelt) |
HH_TPL_STORAGE |
Speicher für die Vorlage (local) |
HH_BRIDGE |
Netzbrücke (vmbr0) |
HH_NET |
dhcp oder eine feste Adresse wie 10.0.0.5/24,gw=10.0.0.1 (dhcp) |
HH_DISK_GB |
Platte in GB (20) |
HH_CORES |
Prozessorkerne (2) |
HH_MEM_MB |
Arbeitsspeicher in MB (4096) |
HH_SWAP_MB |
Auslagerungsspeicher in MB (2048) |
HH_BRANCH |
Git-Zweig (main) |
HH_REPO_URL |
Repository-Adresse ohne Zugangsdaten |
HH_ROOT_PW |
Root-Passwort im Container (zufällig, wird am Ende genannt) |
HH_APPARMOR_UNCONFINED |
Schutzprofil des Containers lockern, siehe den Hinweis darunter (1 = ja) |
Alle Variablen gelten auch unter ihrem alten Namen, etwa CASA_TOKEN, solange die HH_-Fassung fehlt.
Weg B: Debian- oder Ubuntu-Server
Abschnitt betitelt „Weg B: Debian- oder Ubuntu-Server“Damit heinzelhaus auf einem vorhandenen Server oder einer virtuellen Maschine läuft.
Sie brauchen: einen Server mit Debian oder Ubuntu, root-Zugang, git und openssl (siehe Systemvoraussetzungen) und das Lesetoken.
-
Holen Sie den Programmstand in den Projektordner. Die Zugangsdaten gehören in die Adresse, weil der Updater sie später aus der Datei
.git/configliest:Terminal-Fenster git clone https://<Benutzer>:<Lesetoken>@git.it-flores.de/l.flores/heinzelhaus.git /opt/heinzelhauschmod 600 /opt/heinzelhaus/.git/configcd /opt/heinzelhausDer Projektordner darf auch woanders liegen. Das Installationsskript trägt den Pfad als
REPO_PFADin die.envein./opt/heinzelhausist die Vorgabe. -
Starten Sie die Installation:
Terminal-Fenster sudo bash install.sh -
Das Skript installiert Docker, falls es fehlt („Docker wird installiert…“).
-
Gibt es noch keine
.env, fragt das Skript „Wie soll heinzelhaus erreichbar sein?“. Wählen Sie eine Antwort, siehe „Wie heinzelhaus erreichbar ist“:- „1) Im lokalen Netz per IP-Adresse“ (Vorgabe, die erkannte Adresse steht dabei)
- „2) Hinter einem Reverse-Proxy mit Domain (https)“. Das Skript fragt dann nach der „Domain (ohne https://)“, zum Beispiel
verwaltung.example.de. - „3) Nur auf diesem Host (localhost)“
-
Das Skript schreibt die
.envmit zufälligen Kennwörtern und meldet „.env geschrieben — erreichbar unter …“. Dann legt es die Dateidocker-compose.override.ymlaus der Vorlage an. -
Es baut und startet alle Container: „Container werden gebaut und gestartet (das dauert beim ersten Mal einige Minuten)…“
-
Am Ende steht „Fertig! heinzelhaus läuft und ist erreichbar unter …“. Öffnen Sie die Adresse im Browser und fahren Sie mit der Ersten Einrichtung fort.
Ohne Tastatur installieren
Abschnitt betitelt „Ohne Tastatur installieren“Läuft das Skript ohne Tastatur, etwa aus einem Auftrag, wählt es das lokale Netz. Steuern lässt es sich mit Umgebungsvariablen:
| Variable | Bedeutung |
|---|---|
HH_ZUGANG |
lan (lokales Netz), proxy (Domain mit https) oder local (nur auf dem Server selbst) |
HH_IP |
IP-Adresse des Servers bei lan |
HH_DOMAIN |
Domain bei proxy |
HH_PROJEKT |
Name der Installation, Vorgabe heinzelhaus. Eine zweite Installation auf demselben Server braucht einen eigenen Namen. |
Auch diese Variablen gelten unter ihrem alten Namen weiter (CASA_ZUGANG, CASA_IP, CASA_DOMAIN).
Das Skript erneut aufrufen
Abschnitt betitelt „Das Skript erneut aufrufen“Das Skript ist wiederholbar. Eine vorhandene .env und eine vorhandene docker-compose.override.yml überschreibt es nie. Es baut und startet die Container nur neu. Fehlen in einer vorhandenen .env die Kennwörter der Import-Server, ergänzt es sie.
Wie heinzelhaus erreichbar ist
Abschnitt betitelt „Wie heinzelhaus erreichbar ist“Die Wahl bei der Installation bestimmt die Adresse, unter der Ihre Mitarbeitenden heinzelhaus im Browser öffnen.
Im lokalen Netz per IP-Adresse
Abschnitt betitelt „Im lokalen Netz per IP-Adresse“Die Adresse lautet http://<IP-Adresse des Servers>:3000. Das Skript trägt BETTER_AUTH_URL=http://<IP>:3000 und APP_BIND=0.0.0.0 in die .env ein. APP_BIND entscheidet, wer den Port erreicht: Mit 0.0.0.0 auch die Rechner im Netz, mit 127.0.0.1 nur der Server selbst.
- Geben Sie dem Server eine feste Adresse (zum Beispiel über eine Reservierung im Router). Die Adresse steht in
BETTER_AUTH_URL. Aus Sicherheitsgründen vergleicht heinzelhaus die Herkunft jeder Anfrage mit dieser Adresse, als Schutz vor gefälschten Anfragen. Wer heinzelhaus unter einer anderen Adresse aufruft, kann sich deshalb unter Umständen nicht anmelden. Ändert sich die IP-Adresse, tragen Sie die neue in der.envein und übernehmen Sie die Änderung (siehe „Docker Compose von Hand aufrufen“). - Über http gehen Anmeldung und Sitzung im Klartext durchs Netz. Administratoren sehen deshalb unter „Sicherheit“ den Hinweis „Verbindung ist unverschlüsselt“. Abhilfe schafft https vor der Anwendung.
- Passkeys setzen eine Domain mit https voraus. Im lokalen Netz bleibt in der Regel die Authenticator-App für die starke Anmeldung, siehe Anmeldesicherheit und Zwei-Faktor-Pflicht.
Mit Domain und https
Abschnitt betitelt „Mit Domain und https“Die Domain ermöglicht https und Passkeys. Wählen Sie bei der Installation „2) Hinter einem Reverse-Proxy mit Domain (https)“ und geben Sie die Domain ein.
Vorher muss der DNS-Eintrag (A-Record) der Domain auf den Server zeigen, und die Ports 80 und 443 müssen erreichbar sein.
Das Skript trägt dann BETTER_AUTH_URL=https://<Domain>, DOMAIN=<Domain>, PASSKEY_RP_ID=<Domain> und APP_BIND=127.0.0.1 ein. Es startet zusätzlich den Dienst Caddy:
- Caddy holt das Zertifikat beim ersten Aufruf automatisch bei Let’s Encrypt und erneuert es.
- Die Anwendung ist nur noch über Caddy erreichbar, nicht mehr direkt über Port 3000.
- Caddy setzt Sicherheits-Kopfzeilen (unter anderem HSTS) und erlaubt Uploads bis 5 GB, denn Karthago-Sicherungen sind groß.
- Caddy führt ein Zugriffsprotokoll
zugriff.logim Speicherbereichcaddy-data. Eine Datei wird bei 20 MiB abgeschlossen, fünf bleiben erhalten. - Sind die Ports 80 und 443 schon belegt, ändern Sie
CADDY_HTTP_PORTundCADDY_HTTPS_PORTin der.env. Let’s Encrypt nutzt aber nur 80 und 443. Davor muss dann etwas weiterleiten.
Nur auf dem Server selbst
Abschnitt betitelt „Nur auf dem Server selbst“Die Adresse lautet http://localhost:3000, und APP_BIND steht auf 127.0.0.1. Das eignet sich für Tests oder für einen Zugriff über einen SSH-Tunnel. Soll die Anwendung unter einer weiteren Adresse aufrufbar sein, tragen Sie diese kommagetrennt unter BETTER_AUTH_TRUSTED_ORIGINS ein, zum Beispiel http://localhost:3000 für einen Tunnel während der Einrichtung.
Was auf dem Server liegt
Abschnitt betitelt „Was auf dem Server liegt“Die Dienste
Abschnitt betitelt „Die Dienste“heinzelhaus besteht aus mehreren Containern. docker compose ps -a im Projektordner zeigt sie alle.
| Dienst | Aufgabe |
|---|---|
db |
Die Datenbank (PostgreSQL 17) |
init-daten |
Läuft einmalig und legt im Datenverzeichnis die Ordner an und setzt die Rechte |
migrate |
Läuft bei jedem Start einmal und spielt Anpassungen der Datenbankstruktur ein |
app |
Die Anwendung, im Container auf Port 3000 |
worker |
Der Hintergrunddienst: prüft jede Minute Fristen-Erinnerungen, geplante Sicherungen und Zahlungsrückstände, beendet unterbrochene Importe und Serienbriefe und prüft einmal täglich auf eine neue Version |
pdf |
Der PDF-Dienst (WeasyPrint) für Abrechnungen, Briefe und Kontenblätter |
updater |
Führt das Ein-Klick-Update aus und startet bei Bedarf die Import-Datenbankserver. Nur er hat Zugriff auf Docker. |
caddy |
Nur mit Domain: stellt https bereit |
mssql, firebird |
Nur während einer Datenübernahme: die Import-Datenbankserver für Karthago und PowerHaus |
Die Einmal-Dienste init-daten und migrate stehen nach getaner Arbeit als beendet (Exited) in der Liste. Das ist richtig.
Die Daten
Abschnitt betitelt „Die Daten“Die Daten liegen in Docker-Volumes. Ihre Namen beginnen mit dem Projektnamen aus HH_PROJEKT, also heinzelhaus_.
| Volume | Inhalt |
|---|---|
heinzelhaus_db-data |
Die Datenbank |
heinzelhaus_app-data |
Das Datenverzeichnis /data: Dokumente, hochgeladene Dateien, Logos, Sicherungen und der Update-Status |
heinzelhaus_mssql-data, heinzelhaus_firebird-data |
Nur für die Datenübernahme |
heinzelhaus_caddy-data, heinzelhaus_caddy-config |
Nur mit Domain: Zertifikate und Zugriffsprotokoll |
Die Anwendung läuft im Container als Benutzer ohne Sonderrechte (Nummer 100, Gruppe 101).
Die Konfigurationsdateien
Abschnitt betitelt „Die Konfigurationsdateien“Ihre eigenen Einstellungen gehören in zwei Dateien, die Updates nie anfassen:
.env: Zugangsdaten, Adresse, Ports, Domain, Zeitzone. Die Datei enthält Kennwörter und den SchlüsselBETTER_AUTH_SECRET. Sie ist nur für root lesbar. Die Sicherungen aus heinzelhaus enthalten sie nicht. Bewahren Sie deshalb eine Kopie getrennt vom Server auf, siehe Datensicherung und Wiederherstellung.docker-compose.override.yml: alles Übrige, etwa Speichergrenzen und Ablageorte. Das Installationsskript legt sie aus der Vorlagedocker-compose.override.yml.examplean.
Die Programmdateien docker-compose.yml, docker-compose.prod.yml, Dockerfile und Caddyfile verwaltet das Update. Änderungen daran gehen beim nächsten Update verloren. Der Updater legt sie vorher als Patch unter /data/update ab.
Wichtige Einträge der .env
Abschnitt betitelt „Wichtige Einträge der .env“Fehlt ein Pflichteintrag, startet Docker Compose gar nicht und nennt ihn, zum Beispiel mit „POSTGRES_PASSWORD fehlt in .env“.
| Eintrag | Bedeutung |
|---|---|
HH_PROJEKT |
Pflicht. Name des Docker-Projekts, bestimmt Container- und Volume-Namen. Das Installationsskript trägt heinzelhaus ein. |
POSTGRES_PASSWORD |
Pflicht. Kennwort der Datenbank, vom Skript zufällig erzeugt. |
BETTER_AUTH_SECRET |
Pflicht. Geheimer Schlüssel für die Anmeldung, vom Skript zufällig erzeugt. Ändern Sie ihn nicht, sonst melden sich alle neu an. |
MSSQL_SA_PASSWORD, FIREBIRD_PASSWORD |
Pflicht. Kennwörter der Import-Datenbankserver, vom Skript zufällig erzeugt. |
BETTER_AUTH_URL |
Adresse der Installation, zum Beispiel https://verwaltung.example.de oder http://192.168.1.20:3000 |
PASSKEY_RP_ID |
Domain für Passkeys, ohne https:// und ohne Port. Sie muss zur aufgerufenen Adresse passen. Bei der Installation mit Domain setzt das Skript sie. Sonst gilt localhost. |
BETTER_AUTH_TRUSTED_ORIGINS |
Weitere erlaubte Adressen, kommagetrennt |
APP_BIND, APP_PORT |
Wer den Port erreicht (127.0.0.1 nur der Server, 0.0.0.0 das ganze Netz) und welcher Port (Vorgabe 3000) |
DOMAIN |
Domain bei Betrieb mit Caddy. Ist sie gesetzt, bindet der Updater docker-compose.prod.yml ein. |
CADDY_HTTP_PORT, CADDY_HTTPS_PORT |
Ports von Caddy (80 und 443) |
HH_2FA_PFLICHT |
aus hebt die Pflicht zur starken Anmeldung auf, siehe Anmeldesicherheit und Zwei-Faktor-Pflicht |
TZ |
Zeitzone, Vorgabe Europe/Berlin. Ohne sie wären Fristen und Zeitstempel um Stunden versetzt. |
REPO_PFAD |
Pfad des Projektordners auf dem Server, Vorgabe /opt/heinzelhaus. Er muss stimmen, sonst scheitern Updates mit „not a directory“. |
Docker Compose von Hand aufrufen
Abschnitt betitelt „Docker Compose von Hand aufrufen“Ändern Sie etwas in der .env, übernehmen Sie es mit docker compose up -d im Projektordner. Das erneuert nur die Container, deren Einstellungen sich geändert haben. Wie Sie es aufrufen, hängt vom Zugang ab:
cd /opt/heinzelhaus
# Im lokalen Netz (kein DOMAIN in der .env)docker compose up -d
# Mit Domain (DOMAIN in der .env): alle drei Dateien nennendocker compose -f docker-compose.yml -f docker-compose.prod.yml -f docker-compose.override.yml up -dBeim Betrieb mit Domain brauchen Sie die Dateiliste. Ohne sie lässt Compose den Dienst Caddy aus. Dieselbe Dateiwahl treffen das Installationsskript und der Updater. Die Override-Datei nennen Sie ausdrücklich, weil Compose sie bei einer ausdrücklichen Dateiliste nicht von selbst lädt.
Bequemer ist eine Zeile in der .env, dann genügt ein einfaches docker compose up -d:
COMPOSE_FILE=docker-compose.yml:docker-compose.prod.yml:docker-compose.override.ymlEigene Anpassungen
Abschnitt betitelt „Eigene Anpassungen“Die Vorlage docker-compose.override.yml.example zeigt Beispiele. Zum Aktivieren entfernen Sie die Kommentarzeichen bei services: und bei dem gewünschten Block. Steht services: allein und leer da, bricht jeder Compose-Aufruf ab.
- Portbindung: einfacher über
APP_BINDundAPP_PORTin der.env. - Speichergrenzen:
mem_limitfürapp,dbundworker. Auf kleinen Servern verhindert das, dass der Kernel bei Speichermangel wahllos einen Dienst beendet, auch mitten im Update. - Abweichende Ablageorte: Die Daten statt in Volumes auf einer eigenen Platte oder einem NAS halten. Der Wechsel verschiebt keine vorhandenen Daten. Sichern Sie zuerst (Einstellungen → Reiter „Backup“), stellen Sie dann um und spielen Sie die Daten zurück.
- Protokollgrenzen: Ohne Deckel wächst das Docker-Protokoll unbegrenzt und füllt irgendwann die Platte.
- Eigene Caddy-Konfiguration oder eigene zusätzliche Dienste.
Ein zusätzliches Laufwerk für Sicherungen binden Sie in beide Dienste app und worker ein, denn der Hintergrunddienst schreibt die geplanten Sicherungen. Das Beispiel hängt /mnt/nas/heinzelhaus-backups als /backups ein:
services: app: volumes: - /mnt/nas/heinzelhaus-backups:/backups worker: volumes: - /mnt/nas/heinzelhaus-backups:/backupsDanach wählen Sie /backups in den Einstellungen als Speicherort, siehe Datensicherung und Wiederherstellung.
Nach der Installation
Abschnitt betitelt „Nach der Installation“Öffnen Sie die Adresse im Browser. Solange noch kein Benutzer existiert, führt die Anmeldeseite von selbst zur Ersteinrichtung. Dort legen Sie das erste Administratorkonto an: Erste Einrichtung.
Häufige Meldungen
Abschnitt betitelt „Häufige Meldungen“| Meldung | Bedeutung und Abhilfe |
|---|---|
| „Bitte als root ausführen (oder mit sudo).“ | Das Installationsskript braucht root-Rechte. |
| „Docker-Dienst nicht bereit — bitte prüfen (systemctl status docker).“ | Docker startet nicht. Prüfen Sie den Dienst, in einem Proxmox-Container auch die Optionen „nesting“ und „keyctl“. |
| „HH_PROJEKT fehlt in .env - vor 1.0 eingerichtete Installation? …“ | Die Installation stammt aus der Zeit vor Version 1.0. Siehe Umzug von CasaTastic auf heinzelhaus. |
| „POSTGRES_PASSWORD fehlt in .env“, „BETTER_AUTH_SECRET fehlt in .env“ | Ein Pflichteintrag fehlt in der .env. Tragen Sie ihn ein. |
| „DOMAIN fehlt in .env“ | docker-compose.prod.yml ist eingebunden, aber DOMAIN ist nicht gesetzt. Setzen Sie die Domain, oder lassen Sie die Datei weg. |
| „not a directory“ beim Start oder bei einem Update | REPO_PFAD in der .env stimmt nicht mit dem Projektordner überein. |
| „Bitte als root auf dem Proxmox-Host ausführen.“ | Das Proxmox-Skript gehört auf den Host, nicht in den Container, und braucht root. |
| „Kein Token (HH_TOKEN) angegeben — …“ | Setzen Sie das Lesetoken, siehe Weg A. |
| „Container … existiert bereits. Andere HH_CTID wählen oder ihn zuerst entfernen …“ | Die Container-ID ist belegt. Wählen Sie eine andere mit HH_CTID. |
| „Keinen Speicher mit Inhalt ‘rootdir’ gefunden. …“ | Geben Sie den Speicher mit HH_STORAGE an. Das Skript nennt die vorhandenen Speicher. |
| „Container hat nach 60 s keine IP-Adresse. Netzbrücke (vmbr0) und DHCP prüfen.“ | Prüfen Sie HH_BRIDGE und den DHCP-Dienst, oder geben Sie mit HH_NET eine feste Adresse vor. |
| „Installation im Container fehlgeschlagen. Hineinsehen mit: pct enter …“ | Sehen Sie in den Container und lesen Sie die Ausgabe. Häufig fehlt Internetzugang, das Token ist falsch oder der Platz reicht nicht. |
Weiter geht es hier
Abschnitt betitelt „Weiter geht es hier“- Erste Einrichtung: Das erste Administratorkonto und die Angaben Ihrer Verwaltung.
- Benutzer, Rollen und Rechte: Das Team einladen.
- Datensicherung und Wiederherstellung: Sichern Sie, bevor Sie echte Daten eingeben.
- Updates: Neue Versionen per Knopfdruck.
heinzelhaus ist ein Produkt und eine Marke der IT Systeme Flores UG (haftungsbeschränkt), Bergisch Gladbach.
© 2026 IT Systeme Flores UG