Hinatadocs

Konfigurationsreferenz

Jede Einstellung eines Hinata-Servers ist eine Umgebungsvariable. Du setzt sie in .env (für Docker Compose) oder direkt am Container. Die Tabellen zeigen je Bereich den Zweck, einen Standardwert oder ein Beispiel und ob die Variable Pflicht ist.

SSO, eingehende E-Mails, Push und die OAuth-Apps für Git liegen dagegen in der Datenbank. Du verwaltest sie im Adminbereich der App. Wie beides zusammenhängt, steht im letzten Abschnitt.

!!! tip "Alles geht auch ohne .env" .env ist nur ein bequemer Weg für Compose. Jeden Wert kannst du genauso über deinen Orchestrator als Umgebungsvariable am Container setzen, mit denselben Namen und derselben Bedeutung.

Kern / URLs

VariableZweckStandard / BeispielErforderlich
SPRING_PROFILES_ACTIVEAktives Profil: prod (Replikatset, X.509) oder dev (eigenständig)prodJa
HINATA_BASE_URLÖffentliche Basis-URL der API. Dient als JWT-Aussteller und als Basis für SSO-Redirectshttps://api.track.example.comJa
HINATA_WEB_BASE_URLBasis-URL der Flutter-Web-App. E-Mail-Deep-Links zeigen hierher. Leer ⇒ fällt auf die Basis-URL zurückhttps://track.example.comNein

Container-Images

VariableZweckStandard / BeispielErforderlich
HINATA_SERVER_TAGTag von ghcr.io/hinata-platform/hinata-server, das ausgeführt wirdlatest (z. B. 10.4.0 pinnen)Nein
HINATA_APP_TAGTag von ghcr.io/hinata-platform/hinata-app (Web-App als Overlay)latest (z. B. 10.4.0 pinnen)Nein

Pinne im Produktivbetrieb beide Tags auf eine feste Version. Dann läuft auf jedem Host derselbe Build, und ein Rollback ist eine einzeilige Änderung.

Sicherheit / JWT

VariableZweckStandard / BeispielErforderlich
HINATA_JWT_SECRETSignaturschlüssel für HS512, ≥ 64 Zeichen. Erzeugen: openssl rand -base64 64 | tr -d '\n'(leer)Ja (prod)

Im prod-Profil startet der Server nicht ohne gültiges HINATA_JWT_SECRET. Eine Rotation macht alle bestehenden Tokens ungültig.

MongoDB

VariableZweckStandard / BeispielErforderlich
MONGO_ROOT_USERNAMESCRAM-Root-Benutzername (nur intern für die Administration, die App authentifiziert sich per X.509)hinataJa
MONGO_ROOT_PASSWORDSCRAM-Root-Passworthinata-dev-secret (ändere es)Ja (prod)
HINATA_MONGODB_URIVerbindungszeichenkette für Mongo. In Prod steht die X.509-URI in docker-compose.yml. Nur für Dev oder externes Mongo selbst setzen(in Compose gesetzt)Nein (prod)
HINATA_MONGO_TLS_ENABLEDTLS für die Verbindung zu Mongo aktivierentrue (prod, in Compose)Nein
HINATA_MONGO_TLS_KEYSTOREPfad zum PKCS#12-Client-Keystore der App im Container/etc/hinata/x509/hinata-app.p12Nein (prod, in Compose)
HINATA_MONGO_TLS_KEYSTORE_PASSWORDPasswort für den Client-Keystorechangeit (ändere es)Ja (prod)
HINATA_MONGO_TLS_TRUSTSTOREPfad zum CA-Truststore im Container/etc/hinata/x509/truststore.p12Nein (prod, in Compose)
HINATA_MONGO_TLS_TRUSTSTORE_PASSWORDPasswort für den Truststorechangeit (ändere es)Ja (prod)

Wie du die PKI erzeugst und den $external-Benutzer registrierst, steht unter MongoDB & X.509.

Reverse Proxies

VariableZweckStandard / BeispielErforderlich
HINATA_TRUSTED_PROXIESKommagetrennte CIDRs der Reverse Proxies, die X-Forwarded-For setzen dürfen. Leer = keinem vertrauen172.16.0.0/12Empfohlen

Setze hier genau den Adressbereich, aus dem dein Proxy den Container erreicht.

  • Leer: Der Server ignoriert weitergeleitete Header. Rate Limiting und Logs sehen nur die IP des Proxys.
  • Zu weit: Clients können ihre Quell-IP fälschen.

SMTP (ausgehende Mail)

VariableZweckStandard / BeispielErforderlich
HINATA_SMTP_HOSTHost des SMTP-Relayssmtp.example.com (mailpit in Dev)Ja (für Mail)
HINATA_SMTP_PORTSMTP-Port587 (1025 für Mailpit)Ja (für Mail)
HINATA_SMTP_USERNAMEBenutzername für SMTP-Auth(leer)Wenn Auth
HINATA_SMTP_PASSWORDPasswort für SMTP-Auth(leer)Wenn Auth
HINATA_SMTP_AUTHSMTP-Authentifizierung aktivierentrue (false in Dev)Nein
HINATA_SMTP_STARTTLSSTARTTLS aktivierentrue (false in Dev)Nein
HINATA_MAIL_FROMAbsenderadresse ausgehender Mailshinata@example.comJa (für Mail)

E-Mails mit Deep Links (Verifizierung, Passwort zurücksetzen, Zuweisungsbenachrichtigungen) kommen nur mit einem echten Relay an. Siehe E-Mail & SMTP.

Objektspeicher (S3 / MinIO / GCS / Azure)

VariableZweckStandard / BeispielErforderlich
HINATA_STORAGE_PROVIDERBackend: s3 (MinIO, AWS S3, GCS per Interop, R2, Spaces, …) oder azure (Azure Blob Storage)s3Nein
COMPOSE_PROFILESlocal-storage betreibt das mitgelieferte MinIO. Leer bei externem Speicherlocal-storageNein
MINIO_ROOT_USERMinIO-Root-Benutzer (in Compose auch als S3 Access Key genutzt)hinataMit mitgeliefertem MinIO
MINIO_ROOT_PASSWORDMinIO-Root-Passwort (in Compose auch als S3 Secret Key genutzt)hinata-dev-secret (ändere es)Mit mitgeliefertem MinIO (prod)
HINATA_S3_ENDPOINTS3-Endpunkt, mit dem der Server sprichthttp://minio:9000 (in Compose)Externes S3
HINATA_S3_ACCESS_KEYS3 Access Key (Dev / externes S3)hinataDev / extern
HINATA_S3_SECRET_KEYS3 Secret Key (Dev / externes S3)hinata-dev-secretDev / extern
HINATA_S3_BUCKETBucket (S3) oder Container (Azure) für Anhänge und AvatarehinataNein
HINATA_S3_REGIONRegion des Buckets (AWS und Anbieter mit Regionen)us-east-1Externes S3
HINATA_S3_ADDRESSING_STYLEAdressierung der S3-URLs: auto, virtual-host oder pathautoNein
HINATA_AZURE_CONNECTION_STRINGConnection String des Azure-Speicherkontos (bei provider=azure)(leer)Azure

Im Compose für den Produktivbetrieb fallen HINATA_S3_ACCESS_KEY / HINATA_S3_SECRET_KEY automatisch auf MINIO_ROOT_USER / MINIO_ROOT_PASSWORD zurück. Die Einrichtung je Anbieter (AWS, GCS, Azure, R2, …) steht unter Objektspeicher.

App-Integration

VariableZweckStandard / BeispielErforderlich
HINATA_PRIVACY_POLICY_URLURL der Datenschutzerklärung in der App (Pflicht für Store-Releases)https://example.com/privacyEmpfohlen
HINATA_APP_MIN_VERSIONMindestversion der App. Ältere Clients müssen updaten1.0.0Nein
HINATA_CORS_ALLOWED_ORIGINSKommagetrennte Browser-Origins, die per CORS zugreifen dürfen (die Web-App ruft von einer anderen Origin auf)https://track.example.comJa (Web)
HINATA_DOCS_ENABLEDDie API-Dokumentation mit Scalar freigebenfalseNein

Hinata Connect Gateway

VariableZweckStandard / BeispielErforderlich
HINATA_GATEWAY_BASE_URLURL des Gateways für Push und Universal Links. Standard ist das gehostete Gateway. Nur ändern, wenn du eine eigene App unter deiner Marke mit eigenem Gateway ausrollsthttps://connect.hinata.ahmadre.comNein

Siehe Hinata Connect Gateway.

Setup (erster Start)

VariableZweckStandard / BeispielErforderlich
HINATA_SETUP_AUTO_COMPLETEDen Einrichtungsassistenten beim ersten Start überspringenfalseNein
HINATA_SETUP_ORGANIZATION_NAMEOrganisationsname (mit Auto-Complete)(leer)Bei Auto-Complete
HINATA_SETUP_ADMIN_EMAILE-Mail des ersten Admins(leer)Bei Auto-Complete
HINATA_SETUP_ADMIN_USERNAMEBenutzername des ersten Admins(leer)Bei Auto-Complete
HINATA_SETUP_ADMIN_PASSWORDPasswort des ersten Admins(leer)Bei Auto-Complete
HINATA_SETUP_ADMIN_DISPLAY_NAMEAnzeigename des ersten Admins(leer)Bei Auto-Complete

Siehe Setup & Erststart.

Demo-Seed (nur Dev)

VariableZweckStandard / BeispielErforderlich
HINATA_DEMO_SEEDLegt einen realistischen Workspace mit englischen Demodaten an. Login rebar / hinata-demo-2026. Unter prod übersprungen (Seeder ist @Profile("!prod"))falseNein
HINATA_DEMO_RESETLöscht den Workspace bei jedem Start und legt ihn neu an. Erfordert HINATA_DEMO_SEED=truefalseNein

Demo-Seed nie im Produktivbetrieb aktivieren

Er legt einen Admin mit bekanntem Passwort und Wegwerfdaten an. Unter dem prod-Profil ist der Seeder herauskompiliert. Setze im Produktivbetrieb trotzdem immer HINATA_DEMO_SEED=false.

Rate Limiting / Brute Force

VariableZweckStandard / BeispielErforderlich
HINATA_RATE_LIMIT_ENABLEDRate Limiting pro IP aktivieren (bucket4j)trueNein
HINATA_RATE_LIMIT_APIAllgemeines API-Budget (Anfragen / Minute)300Nein
HINATA_RATE_LIMIT_AUTHBudget für Auth-Endpunkte (Anfragen / Minute)10Nein
HINATA_RATE_LIMIT_REFRESHBudget für das Erneuern eines Zugangstokens (Anfragen / Minute). Eigenes Budget, weil das Vorzeigen eines Tokens, das dieser Server signiert hat, kein Rateversuch auf ein Passwort ist — und weil sich alle Clients hinter einer Adresse das Anmelde-Budget teilen60Nein
HINATA_RATE_LIMIT_SSOBudget für die beiden Weiterleitungen einer Single-Sign-on-Anmeldung (Anfragen / Minute). Eigenes Budget, weil ein ganzes Büro hinter einer Adresse sich darüber anmeldet, die Callback-Adresse aber jeder erreicht60Nein
HINATA_MAX_LOGIN_FAILURESFehlgeschlagene Logins, bevor ein Konto blockiert wird5Nein
HINATA_LOGIN_BLOCK_MINUTESWie lange ein blockiertes Konto gesperrt bleibt (Minuten)15Nein

Die Login-Sperre liegt in der Datenbank und übersteht deshalb Neustarts. Siehe das Sicherheitsmodell.

Ports

VariableZweckStandard / BeispielErforderlich
HINATA_PORTVeröffentlichter Host-Port der API (Container 8080). Der Reverse Proxy leitet hierher weiter3356Nein
HINATA_APP_PORTVeröffentlichter Host-Port der Web-App (Container 80)3456Nein

Git-Integration

Plattformweite OAuth-Zugangsdaten, um Projekte mit GitHub, GitLab oder Bitbucket zu verbinden. Du kannst sie auch zur Laufzeit unter Admin → Git-Integration setzen. Diese Werte überschreiben die Umgebung. Siehe Git-Integration.

VariableZweckStandard / BeispielErforderlich
HINATA_GIT_GITHUB_CLIENT_IDClient-ID der GitHub-OAuth-App(leer)Wenn GitHub
HINATA_GIT_GITHUB_CLIENT_SECRETClient-Secret der GitHub-OAuth-App(leer)Wenn GitHub
HINATA_GIT_GITLAB_CLIENT_IDClient-ID der GitLab-OAuth-App(leer)Wenn GitLab
HINATA_GIT_GITLAB_CLIENT_SECRETClient-Secret der GitLab-OAuth-App(leer)Wenn GitLab
HINATA_GIT_BITBUCKET_CLIENT_IDConsumer Key für Bitbucket OAuth(leer)Wenn Bitbucket
HINATA_GIT_BITBUCKET_CLIENT_SECRETConsumer Secret für Bitbucket OAuth(leer)Wenn Bitbucket
HINATA_GIT_WEBHOOK_BASE_URLÖffentliche Basis der API für OAuth-Callback und Webhook-Registrierung. Fällt auf HINATA_BASE_URL + /api/v1 zurückhttps://api.track.example.com/api/v1Nein
HINATA_GIT_TOKEN_SECRETAES-GCM-Schlüssel, der gespeicherte Access Tokens verschlüsselt. Im Produktivbetrieb den Standard ändern(Standard; ändere es)Empfohlen

Kalender, Feiertage und Arbeitszeiten

Organisationsadmins pflegen Feiertagskalender auf der Seite Organisation und können ein Jahr Feiertage aus einer Kalenderadresse importieren, zum Beispiel aus einem Feiertagskalender von Google, Apple oder Outlook. Diese Adresse ruft der Server selbst ab. Mit einer privaten oder Loopback-Adresse verbindet er sich nie, egal was in den Listen unten steht. Die Arbeitszeiten plant jede Person in ihren Einstellungen, die Abwesenheiten in der Zeiterfassung. Das alles setzt die erweiterte Zeiterfassung voraus (HINATA_TIME_TRACKING_ADVANCED_ENABLED). Siehe Zeit erfassen.

VariableZweckStandard / BeispielErforderlich
HINATA_ICS_SECRETSchlüssel, mit dem gespeicherte Kalenderadressen verschlüsselt werden. Base64 von mindestens 32 Bytes. Erzeugen: openssl rand -base64 32. Ohne ihn speichert der Server keine Kalenderadresse, und Feiertage lassen sich nur von Hand eintragen(leer)Für Kalenderadressen
HINATA_ICS_ALLOWED_HOSTSKommagetrennte Hosts, von denen Kalender abgerufen werden dürfen: ein Hostname oder *.example.org für dessen Subdomains. Leer heißt jeder öffentliche Host(leer)Nein
HINATA_ICS_DENIED_HOSTSKommagetrennte Hosts, von denen nie abgerufen wird, in derselben Schreibweise. Wird vor der Erlaubnisliste geprüft(leer)Nein
HINATA_AVAILABILITY_DEFAULT_WEEKDAY_MINUTESGeplante Minuten je Wochentag, beginnend mit Montag, für alle, die keine eigenen Stunden festgelegt haben480,480,480,480,480,0,0Nein
HINATA_TIME_TRACKING_ABSENCE_MANAGEMENT_ENABLEDSchaltet die Abwesenheitsverwaltung ein: Arten, Ansprüche, Konten, Anträge und Krankmeldungen. Setzt die erweiterte Zeiterfassung voraus. Der Schalter unter Organisation → Zeiterfassung hat Vorrang vor diesem WertfalseNein
HINATA_TIME_TRACKING_ABSENCE_CALENDAR_VISIBILITYDer Team-Abwesenheitskalender: OFF, BUSY_ONLY (nur, dass jemand abwesend ist) oder TYPE (die Art, Krankheit nie). Wirkt nur mit eingeschalteter Abwesenheitsverwaltung. Die Auswahl unter Organisation → Zeiterfassung hat Vorrang vor diesem WertOFFNein
HINATA_TIME_TRACKING_WORKLOAD_REPORTS_ENABLEDSchaltet den Auslastungsbericht unter Zeiterfassung → Berichte ein: Kapazität gegen gebuchte Zeit je Person, nur für Organisationsadmins und Projektleitungen. Setzt die erweiterte Zeiterfassung voraus. Der Schalter unter Organisation → Zeiterfassung hat Vorrang vor diesem Wert. Siehe Datenschutz der ZeiterfassungfalseNein
HINATA_RATE_LIMIT_TIME_OFF_REQUESTS_PER_DAYAbwesenheitsanträge und Krankmeldungen je Person und Tag. Ein Tag statt einer Minute, weil ein Antrag eine bewusste Handlung ist und ein Minutenbudget eine Schleife trotzdem durchließe50Nein

Wer die Abwesenheiten führt

Ohne weiteres Zutun führen sie die Organisationsadmins. Unter Organisation → Zeiterfassung lassen sich daneben einzelne Personen als Abwesenheitsverwaltung benennen. Sie pflegen Arten, teilen Ansprüche zu, buchen Korrekturen und entscheiden Anträge, ohne sonst Adminrechte zu haben. Der Weg dorthin steht in ihren eigenen Einstellungen. Die Liste ist bewusst leer voreingestellt: Wer in ihr steht, sieht Krankheitstage als Krankheitstage (Art. 9 DSGVO), und der engere Kreis ist die richtige Vorgabe. Sobald jemand benannt ist, sehen Organisationsadmins bei einer Krankheit nur noch, dass die Person abwesend ist, aber nicht, warum. Ohne benannte Personen führen die Organisationsadmins die Abwesenheiten weiter selbst.

Das Limit sperrt keine Krankmeldung

Eine Krankmeldung zählt auf dasselbe Tagesbudget, wird davon aber nie abgewiesen: § 5 EFZG kennt eine Anzeige, keine Erlaubnis. Erreicht jemand die Grenze, werden nur weitere Anträge abgelehnt.

Den Schlüssel aufbewahren

Eine Kalenderadresse, die mit einem HINATA_ICS_SECRET verschlüsselt wurde, lässt sich mit einem anderen nicht lesen. Ändert sich der Schlüssel, scheitern Importe aus gespeicherten Adressen, bis ein Organisationsadmin die Adresse neu einträgt. Bereits importierte Feiertage bleiben.

Projektvorlagen und relative Fristen

Ein Projekt lässt sich kopieren, als Vorlage kennzeichnen und mit einem Termin versehen, an dem die Fristen seiner Vorgänge hängen. Ist das ausgeschaltet, verhalten sich Projekte genau wie bisher, und die Wege zum Kopieren gibt es nicht. Siehe Projektvorlagen.

VariableZweckStandard / BeispielErforderlich
HINATA_PROJECT_TEMPLATES_ENABLEDSchaltet Projektvorlagen und relative Fristen ein: Projekt kopieren, als Vorlage kennzeichnen, Projekt aus einer Vorlage anlegen und eine Frist als Versatz zum Termin des Projekts pflegen. Der Schalter unter Adminbereich → Plattform hat Vorrang vor diesem WertfalseNein
HINATA_PROJECT_TEMPLATES_DEFAULT_BASISWorin neue relative Fristen zählen, solange weder die Organisation noch das Projekt etwas anderes festlegt: CALENDAR (Kalendertage) oder WORKING (Werktage). Organisationsadmins wählen den Standard auf der Seite Organisation, jedes Projekt kann davon abweichen. Bestehende Fristen behalten ihre ZählweiseCALENDARNein

Werktage brauchen einen Feiertagskalender

Eine Frist, die in Werktagen rechnet, überspringt immer Wochenenden. Feiertage überspringt sie nur, wenn am Projekt ein Feiertagskalender gewählt ist. Ohne einen solchen Kalender zählt sie Feiertage wie gewöhnliche Werktage.

Laufzeiteinstellungen (DB) vs. Umgebung

Hinata hat zwei Konfigurationsebenen.

Umgebungsvariablen (diese Seite) liest der Server beim Start. Sie betreffen Infrastruktur und Secrets: URLs, JWT-Secret, Verbindung zu Datenbank und Speicher, TLS, SMTP, Ports, CORS, vertrauenswürdige Proxies und Rate Limits. Für eine Änderung bearbeitest du .env und startest den Container neu.

Laufzeiteinstellungen liegen in MongoDB. Du bearbeitest sie im Adminbereich der App, während der Server läuft:

  • SSO-Anbieter: OpenID Connect, OAuth 2.0, SAML 2.0, LDAP (SSO)
  • IMAP-Abruf für E-Mail → Ticket (E-Mail zu Vorgang). Mails leiten Administratoren nur in Projekte, in denen sie selbst Mitglied sind
  • Push über das Gateway
  • OAuth-Zugangsdaten der Git-Integration (die HINATA_GIT_*-Werte oben)
  • Plattform-Einstellungen unter Admin → Plattform: minVersion, die Datenschutz-URL, wie sich Menschen anmelden (localAuthEnabled, registrationEnabled, requireAdminApproval) und was die Plattform anbietet

Zeiterfassung, Abwesenheiten, Feiertage und der Standard für relative Fristen liegen ebenfalls in MongoDB. Sie gehören aber nicht zum Adminbereich, sondern zur Seite Organisation, die Organisationsadmins bearbeiten.

Dafür gelten drei Regeln:

  1. DB überschreibt Umgebung. Gibt es eine Einstellung in beiden, gewinnt der Wert aus der Datenbank. Das betrifft vor allem die OAuth-Zugangsdaten für Git und die App-Einstellungen (hinata.app.*). Umgebungswerte sind nur Startwert und Rückfall.
  2. Kein Neustart nötig. Änderungen im Adminbereich wirken sofort, ohne neues Deployment.
  3. Secrets sind nur schreibbar. OAuth-Secrets, Tokens und Passwörter gibt die Admin-API nach dem Speichern nie zurück. Du kannst sie setzen oder ersetzen, aber nicht lesen.

Faustregel

Ist es eine Verbindungszeichenkette, ein Transport-Secret oder etwas, das der Prozess vor der ersten Anfrage braucht, ist es eine Umgebungsvariable. Ist es eine Integration, die du im laufenden Betrieb änderst, ist es eine Laufzeiteinstellung im Adminbereich.