Zum Inhalt springen

RSGo Manifest Schema

Das RSGo Manifest ist das native Stack-Definitionsformat für ReadyStackGo. Es bietet typisierte Variablen, reichhaltige Metadaten, Multi-Stack Unterstützung und modulare Zusammensetzung durch Includes.

version: "1.0" # Format-Version (optional)
metadata: # Product/Stack Metadaten
name: Mein Product
productVersion: "1.0.0" # Macht es zu einem Product (deploybar)
...
sharedVariables: # Variablen für alle Stacks (nur Multi-Stack)
REGISTRY: ...
variables: # Variablen für diesen Stack (Single-Stack oder Fragment)
PORT: ...
stacks: # Stack-Definitionen (nur Multi-Stack)
api:
include: api.yaml
db:
services: ...
services: # Service-Definitionen (Single-Stack oder Fragment)
app: ...
volumes: # Volume-Definitionen
data: {}
networks: # Netzwerk-Definitionen
frontend: {}

Ein Single-Stack Product enthält Services direkt auf Root-Ebene:

metadata:
name: Whoami
productVersion: "1.0.0" # ← Macht es zu einem Product
variables:
PORT:
type: Port
default: "8080"
services:
whoami:
image: traefik/whoami:latest
ports:
- "${PORT}:80"

Ein Multi-Stack Product enthält mehrere Stacks mit geteilten Variablen:

metadata:
name: Enterprise Platform
productVersion: "3.1.0" # ← Macht es zu einem Product
sharedVariables: # ← Verfügbar für alle Stacks
REGISTRY:
type: String
default: myregistry.io
stacks:
api:
include: api.yaml # ← Externes Fragment
monitoring:
services: # ← Inline Stack
prometheus: ...

Ein Fragment hat keine productVersion und kann nur aus einem Product inkludiert werden:

# identity.yaml - Fragment (keine productVersion!)
metadata:
name: Identity Access
description: Identity Provider
variables:
CERT_PATH:
type: String
default: /etc/ssl/certs/identity.pfx
services:
identity-api:
image: ${REGISTRY}/identity:latest # ← Nutzt geteilte Variable

EigenschaftTypPflichtBeschreibung
namestringJaAnzeigename des Products
productIdstringNeinEindeutiger Product-Identifier zur Gruppierung von Versionen über verschiedene Sources hinweg. Verwendet Reverse-Domain-Notation (z.B. com.example.myproduct). Falls nicht gesetzt, wird sourceId:name verwendet.
descriptionstringNeinBeschreibung des Products
productVersionstringJa*Version (z.B. “3.1.0”). *Pflicht für Products
authorstringNeinAutor oder Maintainer
documentationstringNeinURL zur Dokumentation
iconstringNeinURL zum Icon für die UI
categorystringNeinKategorie (z.B. “Database”, “CMS”)
tagsstring[]NeinTags für Suche und Filter

Das productId-Feld wird verwendet, um verschiedene Versionen desselben Products zu gruppieren - auch wenn sie aus unterschiedlichen Quellen stammen (lokales Verzeichnis, Git-Repository, Registry).

Anwendungsfälle:

  • Ein Product von der lokalen Entwicklung in ein Git-Repository migrieren, ohne die Versionshistorie zu verlieren
  • Upgrades zwischen Versionen aus verschiedenen Sources ermöglichen
  • Versehentliche Gruppierung von nicht zusammenhängenden Products mit demselben Namen verhindern

Empfehlungen:

  • Reverse-Domain-Notation verwenden: com.ihrefirma.produktname
  • Über Versionen hinweg stabil halten - eine Änderung der productId erstellt eine neue Product-Gruppe
  • Falls nicht angegeben, generiert RSGO eine ID als sourceId:name

Beispiel:

metadata:
name: WordPress
productId: org.wordpress.stack # Eindeutiger Identifier über alle Sources
description: Produktionsreifer WordPress Stack mit MySQL Backend
productVersion: "6.0.0"
author: ReadyStackGo Team
documentation: https://docs.example.com/wordpress
icon: https://example.com/icons/wordpress.png
category: CMS
tags:
- wordpress
- cms
- blog
- mysql
KategorieBeschreibung
CMSContent Management Systeme
DatabaseDatenbanken und Datenspeicher
MonitoringMonitoring, Logging, Observability
IdentityAuthentifizierung und Autorisierung
MessagingMessage Broker und Queues
CacheCaching-Systeme
StorageDateispeicher und Object Storage
TestingTest- und Debug-Tools
EnterpriseEnterprise-Anwendungen
ExamplesBeispiel-Stacks

Variablen ermöglichen Benutzern die Konfiguration eines Products vor dem Deployment. Sie werden als Formularfelder in der ReadyStackGo UI angezeigt.

EigenschaftTypPflichtBeschreibung
labelstringNeinLesbare Bezeichnung
descriptionstringNeinHilfetext in der UI
typestringNeinVariablentyp (Standard: String)
defaultstringNeinStandardwert
requiredbooleanNeinOb die Variable ausgefüllt werden muss
placeholderstringNeinPlatzhaltertext im Eingabefeld
patternstringNeinRegex-Pattern zur Validierung
patternErrorstringNeinFehlermeldung bei Validierungsfehler
optionsarrayNeinOptionen für Select-Typ
minnumberNeinMinimalwert für Number-Typ
maxnumberNeinMaximalwert für Number-Typ
groupstringNeinGruppenname für UI-Organisation
orderintegerNeinAnzeigereihenfolge in der Gruppe

Für die vollständige Variablentyp-Referenz siehe Variablentypen.

Variablen können für bessere UX in Gruppen organisiert werden:

variables:
# Netzwerk-Gruppe
HTTP_PORT:
label: HTTP Port
type: Port
default: "80"
group: Network
order: 1
HTTPS_PORT:
label: HTTPS Port
type: Port
default: "443"
group: Network
order: 2
# Datenbank-Gruppe
DB_HOST:
label: Datenbank-Host
type: String
default: localhost
group: Database
order: 1

Services definieren die zu deployenden Docker Container.

EigenschaftTypPflichtBeschreibung
imagestringJaDocker Image (z.B. nginx:latest)
containerNamestringNeinContainer-Name (Standard: stack_servicename)
portsstring[]NeinPort-Mappings (host:container)
environmentobjectNeinUmgebungsvariablen
volumesstring[]NeinVolume-Mappings
networksstring[]NeinZu verbindende Netzwerke
dependsOnstring[]NeinService-Abhängigkeiten
restartstringNeinRestart-Policy
commandstringNeinCommand-Override
entrypointstringNeinEntrypoint-Override
workingDirstringNeinArbeitsverzeichnis
userstringNeinBenutzer für Ausführung
labelsobjectNeinContainer-Labels
healthCheckobjectNeinHealth-Check Konfiguration
services:
api:
image: ${REGISTRY}/api:${VERSION}
containerName: my-api
ports:
- "${API_PORT}:8080"
- "8443:8443"
environment:
ASPNETCORE_ENVIRONMENT: ${ENVIRONMENT}
ConnectionStrings__Database: ${DB_CONNECTION}
LOG_LEVEL: ${LOG_LEVEL}
volumes:
- api_data:/app/data
- ./config:/app/config:ro
networks:
- frontend
- backend
dependsOn:
- database
- cache
restart: unless-stopped
healthCheck:
test: ["CMD", "curl", "-f", "http://localhost:8080/health"]
interval: 30s
timeout: 10s
retries: 3
startPeriod: 40s
ports:
- "8080:80" # host:container
- "${PORT}:80" # Variablen-Substitution
- "127.0.0.1:8080:80" # Bindung an spezifische IP
- "8080-8090:80-90" # Port-Bereich
PolicyBeschreibung
noNie neu starten (Standard)
on-failureBei Fehler neu starten
unless-stoppedImmer neu starten, außer explizit gestoppt
alwaysImmer neu starten
healthCheck:
test: ["CMD", "curl", "-f", "http://localhost/health"]
interval: 30s
timeout: 10s
retries: 3
startPeriod: 40s

volumes:
# Named Volume (von Docker verwaltet)
app_data: {}
# Volume mit Driver-Optionen
db_data:
driver: local
driverOpts:
type: none
o: bind
device: /mnt/data
# Externes Volume (existiert bereits)
shared_data:
external: true

networks:
# Standard Bridge-Netzwerk
frontend:
driver: bridge
# Externes Netzwerk (existiert bereits)
proxy:
external: true

In sharedVariables definierte Variablen sind für alle Stacks verfügbar:

sharedVariables:
REGISTRY:
label: Docker Registry
type: String
default: docker.io
LOG_LEVEL:
label: Log Level
type: Select
options:
- value: debug
- value: info
- value: error
default: info
stacks:
api:
services:
api:
image: ${REGISTRY}/api:latest # Nutzt REGISTRY
environment:
LOG_LEVEL: ${LOG_LEVEL} # Nutzt LOG_LEVEL

Jeder Stack kann sein:

  • Include: Referenz auf eine externe Fragment-Datei
  • Inline: Vollständige Stack-Definition innerhalb des Products
stacks:
# Externe Datei einbinden
identity:
include: identity/identity-access.yaml
# Include mit Variable Override
api:
include: api/api.yaml
variables:
LOG_LEVEL:
default: debug # Override für diesen Stack
# Inline-Definition
monitoring:
metadata:
name: Monitoring
services:
prometheus:
image: prom/prometheus:latest

Stacks können geteilte Variablen-Defaults überschreiben:

sharedVariables:
LOG_LEVEL:
type: Select
options:
- value: debug
- value: info
- value: error
default: info # Standard für die meisten Stacks
stacks:
identity:
include: identity.yaml
variables:
LOG_LEVEL:
default: debug # Identity benötigt mehr Logging

Wert-Auflösung:

PrioritätQuelle
1 (höchste)Benutzereingabe
2Stack-Variable Override
3Shared Variable Default
4 (niedrigste)Leer

Include-Pfade sind relativ zum Product-Manifest:

stacks/
└── myproduct/
├── myproduct.yaml # include: identity/stack.yaml
└── identity/
└── stack.yaml # ← Wird hier aufgelöst

Services können aus mehreren Dateien inkludiert werden, um große Service-Definitionen besser zu organisieren:

# business-services.yaml - Fragment (keine productVersion!)
metadata:
name: Business Services
description: Alle Business-Service-Komponenten
variables:
REDIS_CONNECTION:
label: Redis Connection
type: String
default: cachedata:6379
services:
include:
- Contexts/projectmanagement.yaml
- Contexts/memo.yaml
- Contexts/discussions.yaml
# Direkte Services können auch kombiniert werden:
health-monitor:
image: monitor:latest
ports:
- "5100:80"

Die inkludierten Dateien enthalten Services:

Contexts/projectmanagement.yaml
metadata:
name: ProjectManagement
services:
project-api:
image: myregistry/project-api:latest
environment:
REDIS_CONNECTION: ${REDIS_CONNECTION}
project-web:
image: myregistry/project-web:latest

Service-Include Merkmale:

  • Services aus allen Include-Dateien werden in ein einzelnes Dictionary gemergt
  • Kann mit direkten Service-Definitionen kombiniert werden
  • Perfekt für große Fragments mit vielen Services (z.B. Microservices nach Bounded Contexts organisiert)
  • Include-Pfade sind relativ zum Fragment-Manifest

Variablen werden mit ${VARIABLE_NAME} Syntax ersetzt:

variables:
REGISTRY:
default: docker.io
VERSION:
default: "1.0.0"
PORT:
type: Port
default: "8080"
services:
app:
image: ${REGISTRY}/myapp:${VERSION} # docker.io/myapp:1.0.0
ports:
- "${PORT}:80" # 8080:80
environment:
API_URL: http://${HOST}:${PORT} # http://host:8080

stacks/
├── whoami.yaml # Einfaches Single-Stack Product
└── wordpress.yaml # WordPress Product
stacks/
└── enterprise-platform/
├── enterprise-platform.yaml # Product-Manifest
├── IdentityAccess/
│ └── identity-access.yaml # Fragment
└── Infrastructure/
└── monitoring.yaml # Fragment

metadata:
name: Whoami
description: Einfacher HTTP-Service für Tests
productVersion: "1.0.0"
category: Testing
tags:
- whoami
- testing
variables:
PORT:
label: Port
description: Port für den Service
type: Port
default: "8081"
group: Network
services:
whoami:
image: traefik/whoami:latest
ports:
- "${PORT}:80"
restart: unless-stopped
metadata:
name: PostgreSQL
description: PostgreSQL Datenbankserver
productVersion: "15.0.0"
category: Database
variables:
POSTGRES_PORT:
label: Port
type: Port
default: "5432"
group: Network
POSTGRES_USER:
label: Benutzername
type: String
default: postgres
group: Authentication
POSTGRES_PASSWORD:
label: Passwort
type: Password
required: true
group: Authentication
POSTGRES_DB:
label: Datenbankname
type: String
default: postgres
group: Database
services:
postgres:
image: postgres:15
ports:
- "${POSTGRES_PORT}:5432"
environment:
POSTGRES_USER: ${POSTGRES_USER}
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
POSTGRES_DB: ${POSTGRES_DB}
volumes:
- postgres_data:/var/lib/postgresql/data
restart: unless-stopped
healthCheck:
test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
interval: 10s
timeout: 5s
retries: 5
volumes:
postgres_data: {}
metadata:
name: Enterprise Platform
description: Vollständige Enterprise-Plattform mit modularen Komponenten
productVersion: "3.1.0"
category: Enterprise
sharedVariables:
REGISTRY:
label: Docker Registry
type: String
default: myregistry.io
group: Registry
ENVIRONMENT:
label: Umgebung
type: Select
options:
- value: development
label: Entwicklung
- value: staging
label: Staging
- value: production
label: Produktion
default: development
group: General
LOG_LEVEL:
label: Log Level
type: Select
options:
- value: Debug
- value: Information
- value: Warning
- value: Error
default: Warning
group: Logging
DB_CONNECTION:
label: Datenbankverbindung
type: SqlServerConnectionString
group: Database
stacks:
identity:
include: IdentityAccess/identity-access.yaml
variables:
LOG_LEVEL:
default: Debug # Identity benötigt ausführliches Logging
api:
include: API/api.yaml
monitoring:
metadata:
name: Monitoring
variables:
GRAFANA_PORT:
label: Grafana Port
type: Port
default: "3000"
services:
prometheus:
image: prom/prometheus:latest
ports:
- "9090:9090"
restart: unless-stopped
grafana:
image: grafana/grafana:latest
ports:
- "${GRAFANA_PORT}:3000"
dependsOn:
- prometheus
restart: unless-stopped

  1. Scannen: Rekursiv stacks/ nach *.yaml und *.yml Dateien durchsuchen
  2. Parsen: Jede Manifest-Datei parsen
  3. Klassifizieren:
    • Hat metadata.productVersionProduct (laden)
    • Keine productVersionFragment (überspringen, via include laden)
  4. Includes auflösen: Include-Pfade relativ zum Product-Manifest auflösen
  5. Variablen mergen: sharedVariables mit Stack-Variablen zusammenführen