Zum Inhalt

Workspaces

Was auch immer Sie mit Polycrate bauen passiert in einem Workspace. Der Workspace enthält Konfiguration, Credentials und Lifecycle-Artefakte, die beim Ausführen von Blöcken entstehen. Ein Workspace ist im Grunde genommen nur ein Ordner auf Ihrer Festplatte der mit Hilfe von git oder anderen Mechanismen versioniert und synchronisiert werden kann.

Workspace-Pfad

Standardmäßig nimmt Polycrate an, dass der aktuelle Pfad ($PWD), von dem Polycrate ausgeführt wurde, ein Workspace ist. Sie können einen anderen Pfad mit --workspace oder -w angeben.

Der Workspace kann mit Hilfe der Workspace-Konfiguration zusammengestellt werden.

Keine Template-Substitution

In workspace.poly ist keine Template-Substitution möglich (kein Jinja2, kein Bash). Verwenden Sie secrets.poly für sensitive Werte und Ansible-Playbooks für dynamische Logik. → Details zu Konfigurationseinschränkungen

Workspace Directory Layout

Ein Workspace folgt einer definierten Verzeichnisstruktur:

graph TB
    WS[my-workspace/] --> Config[workspace.poly]
    WS --> Inv[inventory.yml]
    WS --> Secrets[secrets.poly]
    WS --> DF[Dockerfile.poly]
    WS --> CL[CHANGELOG.poly]
    WS --> Blocks[blocks/]
    WS --> Arts[artifacts/]

    Blocks --> B1[block-1/]
    Blocks --> B2[block-2/]

    B1 --> BP1[block.poly]
    B1 --> CL1[CHANGELOG.poly]
    B1 --> RM1[README.md]
    B1 --> IN1[install.yml]
    B1 --> T1[templates/]

    Arts --> SecretsDir[secrets/]
    Arts --> BlockArts[blocks/]

    SecretsDir --> IdRsa[id_rsa]
    SecretsDir --> IdRsaPub[id_rsa.pub]
    SecretsDir --> WSKube[kubeconfig.yml]
    SecretsDir --> B1Sec[block-1/]
    B1Sec --> DbPwd[database.pwd]

    BlockArts --> BA1[block-1/]

Wichtige Verzeichnisse und Dateien

Workspace-Root

Datei/Verzeichnis Pflicht Sensibel Beschreibung
workspace.poly Nein Workspace-Konfiguration
inventory.yml Nein Nein Ansible-Inventory im Workspace-Root (Standarddateiname; abweichender Name über Workspace-inventory möglich)
secrets.poly Nein ⚠️ Ja Sensitive Block-Konfiguration (unverschlüsselt)
secrets.poly.age Nein Nein Verschlüsselte Version von secrets.poly
.workspace-encrypted Nein Nein Encryption Marker
.state.poly Nein Nein Operationaler State (CLI/API/Operator-Koordination)
Dockerfile.poly Nein Nein Custom Docker-Image für den Workspace
CHANGELOG.poly Nein Nein Workspace-Changelog für Release-Tracking
blocks/ Nein Nein Template- und lokale Blocks
artifacts/ Nein Teilweise Von Blocks generierte und benötigte Dateien

blocks/ – Block-Verzeichnisse

Jeder Block hat sein eigenes Unterverzeichnis unter blocks/:

Datei/Verzeichnis Pflicht Beschreibung
block.poly Block-Konfiguration und Actions
CHANGELOG.poly Versionshistorie des Blocks
README.md Nein Dokumentation des Blocks
*.yml Nein Ansible-Playbooks (direkt im Block-Root)
templates/ Nein Jinja2-Templates für Ansible

artifacts/secrets/ – Sensible Dateien

Pfad Beschreibung
id_rsa SSH Private Key
id_rsa.pub SSH Public Key
kubeconfig.yml Kubernetes-Konfiguration (workspace-weit)
<BLOCKNAME>/ Block-spezifische Secrets

Niemals unverschlüsselt committen!

Alle Dateien unter artifacts/secrets/ werden bei aktivierter Verschlüsselung automatisch mit .age Suffix verschlüsselt.

artifacts/blocks// – Block-Artefakte

Unter artifacts/blocks/<BLOCKNAME>/ liegen vom jeweiligen Block erzeugte Dateien (je nach Block unterschiedlich). Eine Datei hosts_cache.json wird von aktuellen Polycrate-Versionen nicht mehr angelegt (ältere Workspaces können sie noch enthalten).

Inventory und Kubeconfig

  • Ansible Inventory: liegt als inventory.yml im Workspace-Root
  • Kubeconfig: liegt unter artifacts/secrets/kubeconfig.yml (Pflichtpfad für Workspace-Verschlüsselung)

Ausführliche Dokumentation zu Artefakten

.state.poly – Operationaler State

.state.poly wird automatisch von der CLI nach jedem Action Run aktualisiert und im Workspace-Root abgelegt. Es dient der Koordination zwischen CLI, API und Operator: welche Komponente verwaltet welchen Block.

# .state.poly – Beispiel
cli:
  polycrate-operator:
    last_action: install
    last_action_at: "2026-02-25T10:00:00Z"
    last_action_exit_code: 0
api:
  polycrate-operator:
    managed_since: "2026-02-01T00:00:00Z"
  • Kein Config-Override.state.poly enthält keinen Block-Inhalt, nur operationalen State.
  • Git-versioniert – Das File wird committed und ist für alle sichtbar.
  • Konflikt-Erkennung – Wenn ein Block sowohl von der CLI als auch von der API verwaltet wird, bricht polycrate run mit einer Fehlermeldung ab.
  • Fehlendes File ist kein Fehler – Der erste Action Run erstellt die Datei.

Konflikt auflösen: Ein Block darf nur von einer Komponente verwaltet werden. Bei Konflikt wählen Sie einen dieser Wege:

Ziel Vorgehen
API übernimmt Block aus workspace.poly und secrets.poly entfernen → nächster Action Run entfernt den Eintrag aus .state.poly[cli] → API kann den Block registrieren.
CLI behält API deregistriert den Block (.state.poly[api]-Eintrag entfernen) → Block in workspace.poly eintragen → nächster Action Run registriert ihn in .state.poly[cli].

Keine manuelle Bearbeitung von .state.poly

Lösen Sie Konflikte nicht durch manuelles Editieren von .state.poly. Der State muss die tatsächliche Verwaltungszuständigkeit widerspiegeln. Manuelle Änderungen werden beim nächsten Run überschrieben.

Git-Integration

Ein Workspace kann (und sollte) ein Git-Repository sein. Nutzen Sie die Git-Commands (polycrate git sync) für einfache Synchronisation.

Secrets verschlüsseln

Polycrate bietet eingebaute Verschlüsselung für sensible Daten in secrets.poly und artifacts/secrets/. Siehe Workspace-Verschlüsselung.

Workspace initialisieren

# Neuen Workspace erstellen
polycrate workspace init
# oder Kurzform:
polycrate init

# Mit SSH-Keys (werden in artifacts/secrets/ abgelegt)
polycrate workspace init --with-ssh-keys

# Mit Git-Repository
polycrate workspace init --git

Workspace-Organisation

Empfohlene Verzeichnisstruktur

Workspaces sollten unter $HOME/.polycrate/workspaces/ organisiert werden. Empfohlen ist die Segmentierung:

$HOME/.polycrate/workspaces/<organization>/<name>

Das ist keine Pflicht – jeder beliebige Pfad funktioniert, solange Sie ihn mit --workspace/-w angeben. Die Struktur hilft aber insbesondere im Zusammenspiel mit der Polycrate API und wenn Sie als Managed Service Provider viele Organisationen betreuen: bessere Übersicht, klare Zuordnung und angemessene Isolation zwischen Kunden-Workspaces.

$HOME/.polycrate/workspaces/
├── acme/                        # organization: acme
│   ├── acme-production-1/       # name: acme-production-1
│   ├── acme-staging-1/
│   └── acme-development-1/
├── other-org/
│   └── other-org-production-1/

Naming-Schema

Workspace-Namen folgen oft dem Schema: $org-$purpose-$count

Komponente Beschreibung Beispiel
$org Organisation (slugified) acme
$purpose Zweck/Umgebung production, staging, dev
$count Nummer (beginnend bei 1) 1, 2, 3

Beispiele:

  • acme-production-1 – Erste Produktionsumgebung von Acme
  • acme-staging-1 – Staging-Umgebung
  • startup-dev-1 – Entwicklungsumgebung

name und organization müssen zudem den gleichen Namensregeln wie alle Polycrate-Bezeichner genügen (Regex, erlaubte Zeichen).

Namenskonventionen – zentrale Referenz inkl. Muster ^[a-zA-Z]+([-/_]?[a-zA-Z0-9_]+)+$ und Beispiele

Beim Laden des Workspaces validiert Polycrate diese Felder; bei Verstößen erscheint eine entsprechende Fehlermeldung.

Ausführliche Best Practices

Workspaces auflisten

Der workspace list Command zeigt Workspaces aus der Polycrate API oder aus dem lokalen Workspace-Verzeichnis an.

Remote-Modus (Standard)

Wenn die Polycrate API konfiguriert ist, werden Workspaces aus der API geladen:

# API-Workspaces (Standard)
polycrate workspace list

# Mit Filter
polycrate workspace list --filter production

# Tabellenausgabe
polycrate workspace list --no-pager

Action-Menü bei Auswahl (Remote):

  • open – Öffnet den Workspace in der Polycrate UI
  • gitlab – Öffnet das GitLab-Repository
  • clone – Klont das Repository lokal

Lokal-Modus

Mit --local werden Workspaces aus ~/.polycrate/workspaces/ gescannt:

# Lokale Workspaces
polycrate workspace list --local

# Mit Filter
polycrate workspace list --local --filter production

# Detaillierte Tabellenausgabe
polycrate workspace list --local --no-pager -v

Action-Menü bei Auswahl (Lokal):

  • open – Zeigt Workspace-Details und Pfad
  • status – Ruft den Workspace-Status ab
  • git-sync – Synchronisiert Git-Änderungen

Automatischer Fallback

Wenn keine API konfiguriert ist, wechselt workspace list automatisch in den lokalen Modus und zeigt einen entsprechenden Hinweis an.

CLI-Referenz: workspace list

Hybride Workspaces (Code + Workspace)

In der Praxis werden Workspaces oft gemeinsam mit Quellcode verwaltet – beispielsweise bei Softwareprojekten, die mit Polycrate gebaut und deployed werden. Die polycrate-cli selbst ist ein solches Beispiel: Go-Quellcode und Polycrate-Workspace koexistieren im selben Repository.

Workspace Core-Dateien

Diese Dateien und Ordner gehören exklusiv zum Polycrate-Workspace und sollten von Build-Prozessen (Docker, CI/CD) ausgeschlossen werden:

Pflicht-Dateien

Datei Beschreibung
workspace.poly Workspace-Konfiguration (einzige Pflichtdatei)

Optionale Workspace-Dateien

Datei/Ordner Beschreibung Sensibel?
secrets.poly Unverschlüsselte Block-Secrets ⚠️ Ja
secrets.poly.age Verschlüsselte Secrets Nein
.state.poly Operationaler State (CLI/API/Operator) Nein
CHANGELOG.poly Workspace-Changelog Nein
Dockerfile.poly Custom Container-Image Nein
.workspace-encrypted Encryption Marker Nein
inventory.yml Ansible-Inventory im Workspace-Root (Standard) Optional

Standard-Verzeichnisse

Verzeichnis Beschreibung Sensibel?
blocks/ Block-Definitionen Nein
artifacts/ Generierte Dateien ⚠️ Teilweise

Sensible Dateien (artifacts/secrets/)

Pfad Beschreibung
artifacts/secrets/id_rsa SSH Private Key
artifacts/secrets/id_rsa.pub SSH Public Key
artifacts/secrets/kubeconfig.yml Kubernetes Config
artifacts/secrets/<block>/ Block-spezifische Secrets

Niemals in Git oder Docker-Images!

Die Dateien unter artifacts/secrets/ und secrets.poly dürfen niemals unverschlüsselt in Git-Repositories oder Docker-Images landen. Nutzen Sie die Workspace-Verschlüsselung und konfigurieren Sie .gitignore/.dockerignore entsprechend.

.gitignore für hybride Workspaces

Bei hybriden Workspaces (Code + Polycrate) sollte .gitignore alle sensiblen Polycrate-Dateien ausschließen:

# ============================================
# Polycrate Workspace - Sensitive Files
# ============================================

# Unverschlüsselte Secrets (NIEMALS committen!)
secrets.poly
id_rsa
id_rsa.pub

# Sensible Artifacts
artifacts/secrets/*
!artifacts/secrets/*/
!artifacts/secrets/*.age
artifacts/secrets/*/*
!artifacts/secrets/*/*.age

# Kubeconfig (liegt unter artifacts/secrets/kubeconfig.yml – wird durch artifacts/secrets/* erfasst)
# Inventory im Workspace-Root ist nicht sensibel und wird committed
# inventory.yml

# ============================================
# Polycrate Workspace - Optional excludes
# ============================================

# Build-Artefakte (falls vorhanden)
dist/

# Verschlüsselungs-Marker beibehalten
!.workspace-encrypted

Verschlüsselte Dateien committen

Dateien mit .age Suffix (z.B. secrets.poly.age, artifacts/secrets/id_rsa.age) können und sollten committed werden – sie sind mit AGE verschlüsselt.

.dockerignore für hybride Workspaces

Bei Docker-Builds ist es kritisch, dass keine Workspace-spezifischen Dateien ins Image gelangen:

# ============================================
# Polycrate Workspace - ALLE ausschließen!
# ============================================

# Workspace-Konfiguration (nicht für Runtime benötigt)
workspace.poly
secrets.poly
secrets.poly.age
CHANGELOG.poly
inventory.yml

# Workspace-Verzeichnisse
blocks/
artifacts/

# SSH-Keys (NIEMALS ins Image!)
id_rsa
id_rsa.pub
ssh-passphrase.poly

# Encryption Marker
.workspace-encrypted

# Custom Polycrate Dockerfile (nicht für App-Build)
Dockerfile.poly

# ============================================
# Development & Documentation
# ============================================

# Specs und Cursor Rules
.specs/
.cursor/

# Documentation
*.md
!README.md  # Optional: README im Image behalten

# Git
.git/
.gitignore
.gitlab-ci.yml

# IDE
.vscode/
.idea/

Beispiel: polycrate-cli Repository

Die polycrate-cli demonstriert einen hybriden Workspace:

polycrate-cli/
├── # === Go-Quellcode ===
├── main.go
├── go.mod
├── go.sum
├── cmd/                    # CLI-Commands
├── pkg/                    # Packages
├── # === Docker ===
├── Dockerfile              # Production-Build
├── Dockerfile.poly         # Polycrate Container (optional)
├── # === Polycrate Workspace ===
├── workspace.poly          # ← Workspace-Konfiguration
├── CHANGELOG.poly          # ← Release-Changelog
├── blocks/                 # ← Block-Definitionen
│   ├── app/                #    Release-Management
│   ├── cargo.ayedo.cloud/  #    Registry-Blocks
│       └── ayedo/
│           └── build-tools/
│               ├── golang/ #    Go-Build
│               └── docker/ #    Docker-Build
├── artifacts/              # ← Generierte Dateien
│   ├── secrets/            #    SSH-Keys, Kubeconfigs
│   └── blocks/             #    Block-Artefakte
├── # === Build Output ===
├── dist/                   # Go-Binaries + Archives
├── # === Sonstiges ===
├── .gitignore
├── .dockerignore
├── Makefile
└── README.md

Best Practices für hybride Workspaces

  1. Klare Trennung: Workspace-Dateien (workspace.poly, blocks/, artifacts/) sind Infrastruktur-Konfiguration, nicht Quellcode.

  2. Secrets nie unverschlüsselt: Aktivieren Sie Workspace-Verschlüsselung bevor Sie committen.

  3. Git-Hooks nutzen: Polycrate kann automatisch Pre-Commit-Hooks installieren, die vor unverschlüsselten Secrets warnen:

    polycrate workspace encrypt --install-git-hook
    

  4. CI/CD-Separation: In CI/CD-Pipelines sollte der Workspace separat behandelt werden:

    # .gitlab-ci.yml Beispiel
    build:
      script:
        - polycrate run golang build
        - polycrate run docker push
      only:
        changes:
          - "**/*.go"
          - "go.mod"
          - "Dockerfile"
    

  5. Docker Multi-Stage: Nutzen Sie Multi-Stage-Builds um sicherzustellen, dass nur benötigte Binaries im finalen Image landen:

    # Build-Stage
    FROM golang:1.23 AS builder
    COPY . /src
    RUN go build -o /app/binary .
    
    # Runtime-Stage (minimal, keine Workspace-Dateien)
    FROM alpine:latest
    COPY --from=builder /app/binary /usr/local/bin/
    

Zusammenhang mit anderen Konzepten