Neues Projekt: von goat init zum ersten Modell

Diese Anleitung zeigt, wie Sie ein Projekt aus dem Starter goatcms-child erstellen, .env konfigurieren, die Umgebung mit herd/dev.goat starten und die erste eigene Entität hinzufügen.

Voraussetzungen

  • Goat CLI (goat) im PATH,
  • Docker (gestartet),
  • Git,
  • Python 3 und qtc — nur für die Skripte child/*.sh,
  • Go 1.25+ — optional, für Tests auf dem Host.

PostgreSQL, Node.js und der Go-Compiler für das Backend laufen in Containern.

1. Projekt erstellen

goat init ./my-app \
  --template goatcms-child \
  --name my-app \
  --git-repo https://github.com/acme/my-app.git
FlagBedeutung
--templateEingebettete Vorlage. goatcms-child ist ein kleiner Anwendungsstarter: Anmeldung, Admin-Panel, Seiten, ein Beispielmodell note, ein Angular-Frontend. Die Standardvorlage goatcms ist die vollständige Website mit Blog, Dokumentation und Shop.
--nameProjektname (Buchstaben, Ziffern, ., _, -). Pflicht.
--git-repoRepository-URL. Pflicht; wird als origin eingetragen.
--default-language, --supported-languagesSprachen der Anwendung (Standard: en und pl,en,de).
--terminal-prefixPräfix der Terminalvariablen (Standard APP).

Das Zielverzeichnis muss leer sein oder darf nicht existieren. goat init kopiert die Vorlage, führt git init aus und fügt origin hinzu — es wird nichts gebaut oder heruntergeladen.

Der Starter goatcms-child behält vorerst den ursprünglichen Go-Modulpfad (code.pozoga.eu/spozoga/goatcms.com) und den Binärnamen goatcms. Das Projekt funktioniert unverändert; wenn Sie sie ändern möchten, tun Sie es sofort in go.mod, in --go-prefix in herd/_model.goat und in den Importen unter child/, bevor das Projekt wächst.

Erstellen Sie gleich den ersten Commit — jede spätere Regenerierung ist dann in git diff gut lesbar.

2. .env konfigurieren

cd my-app
cp .env.example .env

Setzen Sie mindestens GOAT_JWT_SECRET_KEY, zum Beispiel mit:

openssl rand -hex 32

Wichtige Variablen:

VariableBeispielHinweise
GOAT_DEV_APP_PORT8091Anwendungsport in der Entwicklung.
GOAT_HOST:8091Listen-Adresse; synchron zum Port halten.
GOAT_URL_BASEhttp://localhost:8091Öffentliche Adresse — Links in E-Mails, SEO.
GOAT_DOMAINlocalhostDomain der Umgebung (ohne Schema und Port).
GOAT_DB_MAIN_HOST / PORTlocalhost / 55432Entwicklungsdatenbank. Pro Projekt ein anderer Port.
GOAT_DB_MAIN_NAME / USER / PASSstarterZugangsdaten des erzeugten PostgreSQL-Containers.
GOAT_JWT_SECRET_KEYzufälliges HexPflicht. Eine Änderung macht Sitzungen ungültig.
GOAT_DIR_TMP, GOAT_DIR_DATA, GOAT_DIR_DIST, GOAT_DIR_SHARED_TMP./data usw.Arbeitsverzeichnisse; Standardwerte beibehalten.
GOAT_SMTP_*leerOptional. Ohne SMTP werden keine E-Mails versendet.
GOAT_AI_OPENAI_API_KEY, GOAT_AI_OPENAI_MODELleer, gpt-4o-miniOptional — aktiviert den KI-Assistenten im Panel.

Zugangsdaten für Commits und Pushes durch Goat-Skripte gehören in .private.env (Vorlage: .example.private.env).

.env und .private.env gelangen niemals ins Repository. Wenn mehrere Projekte gleichzeitig laufen, ändern Sie GOAT_DEV_APP_PORT, GOAT_HOST, GOAT_URL_BASE und GOAT_DB_MAIN_PORT gemeinsam.

Mehr: [Umgebungskonfiguration](/doc/de/umgebungskonfiguration).

3. Projekt mit herd/dev.goat starten

goat run:script --path herd/dev.goat

Das Skript lädt .env und startet child/dev/runtime.goat, das:

  1. re ausführt — die Module aus herd/_modules.goat nach .goat/modules/ holt und goatapp/ generiert,
  2. drei Aufgaben parallel startet:
  • database — PostgreSQL 17 auf GOAT_DB_MAIN_PORT, Daten in .cache/postgres,
  • backend — baut die Binärdatei in einem Go-Container, wartet auf die Datenbank, führt db:migrate, child:db:migrate aus, lädt herd/fixture.goat und startet serve,
  • frontend — installiert Abhängigkeiten und startet die Angular-Watcher (Panel, child-app, Foundation-Elemente) gemäß herd/dev/frontends.json.

Der erste Start dauert einige Minuten (Docker-Images, npm-Abhängigkeiten, erste Angular-Builds). Warten Sie, bis die Watcher ihren ersten Build abgeschlossen haben, bevor Sie das Frontend öffnen.

Nach dem Start:

AdresseInhalt
http://localhost:8091/Öffentliche Seiten (SSR), /pl für die polnische Version
http://localhost:8091/app/Admin-Panel
http://localhost:8091/child/Die eigene Angular-Anwendung des Projekts

Entwicklungskonten aus den Fixtures: admin / starter-dev-123 und user / starter-dev-123. Ändern Sie die Passwörter, bevor Sie die Instanz mit anderen teilen.

Praktische Hinweise:

  • Die Datenbank bleibt zwischen Starts erhalten; nur ausstehende Migrationen werden ausgeführt. Fixtures werden bei jedem Backend-Start geladen und müssen daher idempotent sein.
  • herd/dev.goat generiert den Code einmal beim Start. Nach einer Modelländerung das Skript stoppen (Ctrl+C) und neu starten.
  • Für automatische Neustarts bei Änderungen an Modell, Vorlagen und Backend den Supervisor verwenden: bash child/setup.sh (einmalig), dann bash child/dev.sh. Der Supervisor nutzt einen eigenen Container goat-starter-<port> auf demselben Port — beide Varianten nicht gleichzeitig ausführen (docker stop goat-starter-55432).
  • Der Fehler „port is already allocated“ bedeutet fast immer ein anderes Projekt oder die andere Dev-Variante auf demselben Port.

4. Wo was liegt

herd/_model.goat        Modell: Entitäten, Rollen, Module, Dashboard
herd/_modules.goat      Framework-Module (goatcore, goatcms)
herd/fixtures/          Beispieldaten, geladen von herd/fixture.goat
child/app/              Ihr Go-Code: Layout, Routen, Services, Befehle, Migrationen
child/web/              Ihre Angular-Anwendung (/child/)
child/static/raw/       Ihre statischen Assets (Theme-CSS, Bilder)
goatapp/                generierter Code — niemals manuell bearbeiten

Die Regel: Was sich aus dem Modell ergibt, wird in herd/ beschrieben; was anwendungsspezifisch ist, wird in child/ geschrieben. Alles in goatapp/ wird beim nächsten goat re überschrieben.

5. Die erste eigene Entität

Fügen Sie herd/_model.goat eine Aufgaben-Entität hinzu, die einem Benutzer zugewiesen ist:

entity:add --name=task --label=title --base=base_entity --doc=<<DOCEOF
    A task assigned to a team member.
DOCEOF --properties=<<PROPERTIESEOF
    def --write=admin,manager --read=admin,manager,user
    add --name=title --type=short_text --required --doc="Short task name."
    add --name=description --type=short_text
    add --name=due_at --type=date_time
    add --name=done --type=bool
PROPERTIESEOF --relations=<<RELATIONSEOF
    def --onremove
    add --name=assignee --to=user --doc="User responsible for the task."
RELATIONSEOF --system=<<ENTITYSYSTEMEOF
    module:add --name=crud --property:list:list="title,due_at,done" --property:list:persist="title,description,due_at,done"
    module:add --name=crud_cli --property:list:list="title,done" --property:list:persist="title,description,due_at,done"
    module:add --name=harness --property:list:list="title,done" --property:list:persist="title,description,due_at,done"
ENTITYSYSTEMEOF

Fügen Sie einen Link zur Dashboard-Navigation hinzu (im Block --navigation von app:module:add --name=dashboard):

link:add --label="Tasks" --entity=task

Was die Module liefern:

  • crud — API und Formulare im Panel /app/,
  • crud_cli — Befehle crud:task:*, darunter crud:task:persist für Fixtures,
  • harness — Werkzeuge des KI-Assistenten für diese Entität (weglassen, wenn die Daten nicht für KI freigegeben werden sollen),
  • seo und ssr — nur für öffentliche Inhalte (Vorbild: Entität page).

Anschließend:

goat re                 # goatapp/ neu generieren
git diff                # Änderungen in herd/ und child/ prüfen

Bei einer bestehenden Datenbank eine Modellmigration erzeugen, das SQL prüfen und herd/dev.goat neu starten:

goat run:script --path=@goatcms/herd/db/migration_generate.goat

Die Migration landet in child/app/migrations/sql/0000_goatmigrations/. Prüfen Sie Typkonvertierungen, destruktive Operationen und Tabellensperren. Handgeschriebenes Anwendungs-SQL gehört nach 0001_childigrations/.

Fügen Sie zum Schluss Beispieldaten hinzu, z. B. herd/fixtures/tasks/fixture.goat:

crud:task:persist --title="Prepare release notes" --done=false

und binden Sie sie in herd/fixture.goat ein:

run:script --path herd/fixtures/tasks/fixture.goat

Vollständige Modellsyntax: [Datenmodell und Codegenerierung](/doc/de/datenmodell-und-codegenerierung).

Bewährte Praktiken

Modell

  • Beginnen Sie mit dem Modell. Entitäten, Felder, Relationen, Berechtigungen und Spaltenlisten gehören in herd/_model.goat, nicht in handgeschriebenen Code.
  • Versehen Sie jede Entität und jedes Feld mit --doc. Diese Beschreibungen landen im Code, in der API und beim KI-Assistenten.
  • Setzen Sie Berechtigungen explizit mit def --write=... --read=.... Verlassen Sie sich nicht auf Standardwerte.
  • Verwenden Sie semantische Typen (web_slug, seo_description, language, image, block_content) statt des allgemeinen short_text, wo sie passen — sie bringen Validierung und passende Bedienelemente.
  • Lagern Sie gemeinsame Felder in eine Basis aus (entity:base:add) und erben Sie mit entity:extended, wie bei content → page.
  • Deklarieren Sie Eindeutigkeit im Modell (--unique oder unique:add --fields=lang,slug) — idempotente persist-Fixtures bauen darauf auf.
  • Ändern Sie das Modell in kleinen Schritten: eine Änderung → goat re → git diff → Tests → Commit.

Code

  • Bearbeiten Sie niemals goatapp/. Passt der generierte Code nicht, ändern Sie das Modell oder eine Vorlage in herd/gen/.
  • Geschäftslogik, eigene Routen und Services gehören nach child/; die Foundation wird über den vollständigen Paketpfad importiert.
  • Committen Sie herd/ und child/; goatapp/ wird generiert und von Git ignoriert.

Datenbank und Daten

  • Angewendete Migrationen niemals umbenennen oder ändern — neue hinzufügen.
  • Fixtures nur über crud:*:persist mit eindeutigem Schlüssel schreiben, damit wiederholte Läufe denselben Zustand erzeugen.
  • Entwicklungs-Fixtures (Konten, Passwörter) dürfen niemals in die Produktion gelangen.

Umgebung

  • Ein Projekt — ein Satz Ports in .env.
  • Geheimnisse nur in .env / .private.env, niemals im Repository.
  • Vor dem Commit die Tests ausführen: goat run:script --path=herd/test.goat.

Nächste Schritte

  • [Projektarchitektur](/doc/de/projektarchitektur)
  • [Datenmodell und Codegenerierung](/doc/de/datenmodell-und-codegenerierung)
  • [Datenbank und Migrationen](/doc/de/datenbank-und-migrationen)
  • [Testdaten und Fixtures](/doc/de/testdaten-und-fixtures)
  • [Das Harness-Modul: KI-Assistent](/doc/de/harness-modul)