Umgebungskonfiguration

Goat verwendet Umgebungsvariablen zur Konfiguration der Anwendung, der Datenbankverbindungen, der Arbeitsverzeichnisse sowie der umgebungsspezifischen Einstellungen.

In der lokalen Entwicklung werden diese Werte in der Regel in folgender Datei gespeichert:

.env

Die Namen der von der Anwendung verwendeten Variablen beginnen mit folgendem Präfix:

GOAT_

Die Datei .env sollte ausschließlich Konfiguration enthalten, die für die lokale Umgebung bestimmt ist. Betrachte sie nicht als Ort zur Speicherung von Produktionsgeheimnissen und füge keine echten Passwörter, Token oder Schlüssel in ein öffentliches Repository ein.

Wichtigste Variablen

VariableBedeutung
GOAT_DEVAktiviert den Entwicklungsmodus der Anwendung.
GOAT_DB_MAIN_HOSTHost der primären PostgreSQL-Datenbank.
GOAT_DB_MAIN_PORTPort der primären PostgreSQL-Datenbank.
GOAT_DB_MAIN_USERBenutzer der primären Datenbank.
GOAT_DB_MAIN_PASSPasswort des Benutzers der primären Datenbank.
GOAT_DB_MAIN_NAMEName der primären Datenbank.
GOAT_DB_TEST_HOSTHost der von Tests verwendeten Datenbank.
GOAT_DB_TEST_PORTPort der Testdatenbank.
GOAT_DB_TEST_USERBenutzer der Testdatenbank.
GOAT_DB_TEST_PASSPasswort des Benutzers der Testdatenbank.
GOAT_DB_TEST_NAMEName der Testdatenbank.
GOAT_JWT_SECRETGeheimnis zum Signieren von JWT-Token.
GOAT_URL_BASEÖffentliche Basis-URL der Anwendung.
GOAT_DIR_DATADatenverzeichnis der Anwendung.
GOAT_DIR_TMPLokales Verzeichnis für temporäre Dateien.
GOAT_DIR_SHARED_TMPTemporäres Verzeichnis, das zwischen Prozessen oder Containern geteilt wird.
GOAT_DOMAINDomain, die von der Zielumgebungskonfiguration verwendet wird.

Beispiel einer lokalen Konfiguration

Eine minimale Konfiguration für die lokale Umgebung kann wie folgt aussehen:

GOAT_DEV=TRUE

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=admin
GOAT_DB_MAIN_PASS=local-password
GOAT_DB_MAIN_NAME=maindb

GOAT_JWT_SECRET=zmien-na-dlugi-losowy-sekret

GOAT_URL_BASE=http://localhost:8080/

Die Werte aus dem Beispiel sind ausschließlich für die Entwicklung vorgesehen.

Zugangsdaten für gemeinsam genutzte, Staging- und Produktionsumgebungen sollten über den für die jeweilige Umgebung geeigneten Konfigurationsmechanismus bereitgestellt werden.

Entwicklungsmodus

Verwende die Variable:

GOAT_DEV

um festzulegen, ob die Anwendung im Entwicklungsmodus ausgeführt wird.

Beispiel:

GOAT_DEV=TRUE

Der Entwicklungsmodus kann das Verhalten der Anwendung beeinflussen, unter anderem in Bezug auf:

  • Protokollierung,
  • Diagnose,
  • Fehlerbehandlung,
  • Cache,
  • Hilfswerkzeuge,
  • die Art, wie Frontend oder Backend gestartet werden.

Gehe nicht davon aus, dass die Entwicklungskonfiguration für die Produktionsumgebung geeignet ist.

Konfiguration der primären Datenbank

Die primäre PostgreSQL-Verbindung wird durch einen Satz von Variablen festgelegt:

GOAT_DB_MAIN_HOST
GOAT_DB_MAIN_PORT
GOAT_DB_MAIN_USER
GOAT_DB_MAIN_PASS
GOAT_DB_MAIN_NAME

Beispiel:

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=admin
GOAT_DB_MAIN_PASS=local-password
GOAT_DB_MAIN_NAME=maindb

Diese Werte werden von der Anwendung sowie von den Skripten verwendet, die für die Arbeit mit der Hauptdatenbank zuständig sind.

In der lokalen Umgebung wird PostgreSQL standardmäßig durch Goat-Skripte in Docker gestartet.

Separate Datenbank für Tests

Tests können eine separate Verbindung verwenden:

GOAT_DB_TEST_HOST
GOAT_DB_TEST_PORT
GOAT_DB_TEST_USER
GOAT_DB_TEST_PASS
GOAT_DB_TEST_NAME

Die Trennung der Testdatenbank von der Entwicklungsdatenbank verringert das Risiko einer versehentlichen Löschung oder Änderung von Daten, die bei der täglichen Arbeit verwendet werden.

Beispielkonfiguration:

GOAT_DB_TEST_HOST=localhost
GOAT_DB_TEST_PORT=5433
GOAT_DB_TEST_USER=admin
GOAT_DB_TEST_PASS=local-password
GOAT_DB_TEST_NAME=testdb

Besonders wichtig ist, dass destruktive Operationen, die während der Tests ausgeführt werden, niemals auf die Produktionsdatenbank verweisen.

JWT-Secret

Die Variable:

GOAT_JWT_SECRET

wird von der Anwendung zum Signieren von JWT-Tokens verwendet.

Der Wert sollte:

  • lang,
  • zufällig,
  • für die jeweilige Umgebung eindeutig,
  • nicht öffentlich zugänglich

sein.

Verwende das Beispiel-Secret nicht in der Produktionsumgebung.

Speichere das tatsächliche GOAT_JWT_SECRET nicht in Dateien, die von Git verfolgt werden.

Jede Umgebung sollte einen eigenen Wert besitzen. Insbesondere sollten die lokale, die Test- und die Produktionsumgebung nicht dasselbe Secret gemeinsam verwenden.

Öffentliche Adresse der Anwendung

Verwende die Variable:

GOAT_URL_BASE

zur Festlegung der öffentlichen Basisadresse der Anwendung.

Lokal kann dies sein:

GOAT_URL_BASE=http://localhost:8080/

In der Zielumgebung sollte der Wert der tatsächlichen Adresse entsprechen, die von den Nutzern der Anwendung verwendet wird.

Sie kann unter anderem beim Generieren folgender Elemente verwendet werden:

  • absoluter Links,
  • Callbacks,
  • Adressen in Nachrichten,
  • Metadaten,
  • Links zu Anwendungsressourcen.

Daten- und temporäre Dateiverzeichnisse

Goat ermöglicht die Konfiguration der Speicherorte, die zur Ablage von Daten und temporären Dateien verwendet werden.

Dafür dienen:

GOAT_DIR_DATA
GOAT_DIR_TMP
GOAT_DIR_SHARED_TMP

GOAT_DIR_DATA verweist auf das Verzeichnis für Anwendungsdaten.

GOAT_DIR_TMP kann von einem einzelnen Prozess zur Ablage temporärer Dateien verwendet werden.

GOAT_DIR_SHARED_TMP ist für temporäre Daten vorgesehen, die für mehr als einen Prozess oder Container verfügbar sein müssen.

Die explizite Definition dieser Verzeichnisse erleichtert die Anpassung der Anwendung an verschiedene Laufzeitumgebungen.

Domäne der Umgebung

Die Variable:

GOAT_DOMAIN

kann zur Festlegung der Domäne verwendet werden, die mit der aktuellen Umgebung verbunden ist.

Der Wert kann von der Bereitstellungskonfiguration, einem Reverse Proxy, der Adressgenerierung oder anderen Infrastrukturkomponenten verwendet werden.

Beispielsweise:

GOAT_DOMAIN=example.com

Sie sollte nicht automatisch mit GOAT_URL_BASE gleichgesetzt werden.

GOAT_DOMAIN beschreibt die Domäne, während GOAT_URL_BASE eine vollständige Adresse einschließlich Protokoll, Port und Basispfad enthalten kann.

Secrets und Versionskontrolle

Konfigurationsdateien, die im Repository gespeichert werden, sollten nur sichere Beispielwerte enthalten.

Bewahre die tatsächlichen Secrets außerhalb der Versionskontrolle auf.

Dies betrifft insbesondere:

GOAT_DB_MAIN_PASS
GOAT_DB_TEST_PASS
GOAT_JWT_SECRET

In der lokalen Umgebung können sie sich in .env befinden.

In gemeinsam genutzten und Produktionsumgebungen ist es besser, sie bereitzustellen über:

  • Umgebungsvariablen der Plattform,
  • CI/CD-System,
  • Secret-Manager,
  • von der Deployment-Plattform bereitgestellte Mechanismen.

Eine bewährte Praxis ist, eine Beispieldatei im Repository zu speichern, z. B.:

.env.example

die die Namen der erforderlichen Variablen enthält, jedoch keine tatsächlichen Secrets.

Beispiel:

GOAT_DEV=TRUE

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=
GOAT_DB_MAIN_PASS=
GOAT_DB_MAIN_NAME=

GOAT_JWT_SECRET=

GOAT_URL_BASE=http://localhost:8080/

Eine solche Datei erleichtert die Einrichtung einer neuen Umgebung, ohne vertrauliche Daten offenzulegen.

Container-Konfiguration

Lokale Goat-Skripte verwenden Docker, um Teile der Projektinfrastruktur zu starten.

Insbesondere starten die Datenbankskripte PostgreSQL in einem Container und stellen es lokal auf folgendem Port bereit:

5433

Aus Sicht eines Prozesses, der direkt auf dem Host ausgeführt wird, kann die Verbindung daher wie folgt aussehen:

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433

Anders sieht es aus, wenn die Anwendung selbst innerhalb eines Containers ausgeführt wird.

Für einen Prozess innerhalb von Docker bedeutet:

localhost

seinen eigenen Container und nicht das Hostsystem.

Daher kann das Entwicklungsskript den Datenbankhost überschreiben mit:

host.docker.internal

Der Ablauf sieht dann vereinfacht wie folgt aus:

Anwendung im Container
        ↓
host.docker.internal:5433
        ↓
vom Host bereitgestellter Port
        ↓
PostgreSQL

Dadurch kann dieselbe Projektkonfiguration verwendet werden, unabhängig davon, ob ein bestimmter Befehl direkt auf dem Host oder innerhalb eines Containers ausgeführt wird.

Lokale Konfiguration und Zielkonfiguration

Es ist nicht sinnvoll, die lokale .env unverändert auf den Server zu kopieren.

Lokal ist die Konfiguration auf eine komfortable Entwicklung optimiert:

localhost
von Docker bereitgestellte Ports
GOAT_DEV=TRUE
lokale Passwörter
lokale Verzeichnisse

Die Produktionsumgebung kann hingegen Folgendes verwenden:

internen PostgreSQL-Host
von der Plattform bereitgestellte Secrets
HTTPS
persistente Volumes
andere Datenverzeichnisse
GOAT_DEV=FALSE

Die Konfiguration sollte daher als umgebungsabhängiges Element und nicht als Teil des Anwendungscodes betrachtet werden.

Typischer lokaler Workflow

Die Einrichtung der lokalen Konfiguration kann wie folgt aussehen:

cp .env.example .env

Ergänze anschließend die vom Projekt benötigten Werte:

GOAT_DEV=TRUE

GOAT_DB_MAIN_HOST=localhost
GOAT_DB_MAIN_PORT=5433
GOAT_DB_MAIN_USER=admin
GOAT_DB_MAIN_PASS=local-password
GOAT_DB_MAIN_NAME=maindb

GOAT_JWT_SECRET=lokalny-losowy-sekret

GOAT_URL_BASE=http://localhost:8080/

Nach dem Speichern der Konfiguration kannst du die Umgebung starten:

bash child/dev.sh

Die Goat-Skripte bereiten die übrigen Elemente der Umgebung gemäß der Projektkonfiguration vor.

Wichtigste Regel

Der Anwendungscode sollte festlegen, welche Konfiguration er benötigt, während die konkreten Werte aus der Umgebung stammen sollten, in der die Anwendung ausgeführt wird.

Dadurch kann derselbe Code lokal, in Tests, in CI, auf Staging und in Produktion ausgeführt werden, ohne dass Änderungen direkt in den Quellen erforderlich sind.

Behandle Secrets als Umgebungsdaten, nicht als Teil des Projekts.