Zum Inhalt

🐳 Der Polycrate Container

Container-Konzept

Ein Großteil der Magie von Polycrate passiert innerhalb eines Docker-Containers, der mit jeder Ausführung einer Action auf dem System gestartet wird, auf dem Polycrate ausgeführt wird.

Der Container basiert auf einem von ayedo entwickelten und öffentlich verfügbaren Docker-Image (cargo.ayedo.cloud/library/polycrate), das einen Großteil der best-practice Toolchain für den Einsatz von Infrastructure as Code und cloud-nativen Entwicklungsmethoden beinhaltet.

Der Container gibt Ihnen Zugang zu einer state-of-the-art DevOps runtime. Polycrate exportiert einen Snapshot des Workspaces als YAML-Datei und stellt diese Datei innerhalb des Containers zur Verfügung, sodass die gesamte Workspace-Konfiguration problemlos von den Tools innerhalb des Containers eingelesen werden kann.

Container Lifecycle

sequenceDiagram
    participant User
    participant CLI as Polycrate CLI
    participant Docker
    participant Container
    participant Tools as Ansible/kubectl/Helm

    User->>CLI: polycrate run myblock install
    CLI->>CLI: Erstelle Snapshot
    CLI->>CLI: Generiere Transaction-ID

    alt Custom Dockerfile.poly existiert?
        CLI->>Docker: Build Custom Image
        Docker->>Docker: FROM polycrate:latest + Custom layers
        Docker-->>CLI: Custom Image ready
    end

    CLI->>Docker: docker run polycrate
    Docker->>Container: Start Container
    CLI->>Container: Mount Workspace → /workspace
    CLI->>Container: Mount SSH Keys
    CLI->>Container: Injiziere Environment Variables
    CLI->>Container: Injiziere Snapshot (.snapshot.yml)

    Container->>Container: Setze Working Directory
    Container->>Tools: Führe Playbook/Script aus
    Tools->>Tools: Lese .snapshot.yml
    Tools->>Tools: Greife auf /workspace zu

    alt Action erfolgreich
        Tools-->>Container: Exit 0
        Container-->>Docker: Success
        Docker-->>CLI: Container beendet (Exit 0)
        CLI->>CLI: Schreibe Artifacts
        CLI-->>User: Success
    else Action fehlgeschlagen
        Tools-->>Container: Exit 1
        Container-->>Docker: Failure
        Docker-->>CLI: Container beendet (Exit 1)
        CLI-->>User: Failure mit Error-Output
    end

    CLI->>Docker: Cleanup Container
    Docker->>Docker: Remove Container

Was ist im Container enthalten?

Das Polycrate Base-Image (cargo.ayedo.cloud/library/polycrate) basiert auf python:3.11-slim (Debian) und enthält eine umfassende DevOps-Toolchain.

Kubernetes & Container Tools

Tool Version Beschreibung
kubectl 1.32.1 Kubernetes CLI
helm 3.18.4 Kubernetes Package Manager (+ helm-diff Plugin)
kustomize 5.8.0 Kubernetes Konfiguration
cilium 0.18.5 Cilium CNI CLI
argocd 3.0.6 Argo CD CLI für GitOps
velero 1.16.1 Kubernetes Backup & Migration
docker latest Docker CLI (from docker:dind)
skopeo system Container Image Management

Backup & Encryption Tools

Tool Version Beschreibung
restic 0.18.1 Backup Tool
kopia 0.22.2 Backup Tool (Velero Backend)
age 1.2.1 Moderne Verschlüsselung

Configuration Management

Tool Beschreibung
Ansible Configuration Management und Orchestrierung
ansible-core Ansible Core Engine

Utilities

Tool Beschreibung
git Version Control
jq JSON Processing
yq (v4.45.1) YAML Processing
curl / wget HTTP Clients
openssh-client SSH/SCP Tools
sshpass SSH Password Authentication
rsync File Synchronization
envsubst Environment Variable Substitution
htpasswd HTTP Basic Auth Password Generator

Database Clients

Tool Beschreibung
mariadb-client MySQL/MariaDB CLI
postgresql-client PostgreSQL CLI (psql)

Netzwerk-Tools

Tool Beschreibung
dnsutils DNS Tools (dig, nslookup)
telnet Telnet Client

Python Libraries

Library Beschreibung
kubernetes Kubernetes Python Client
openshift OpenShift Python Client
hcloud Hetzner Cloud Python SDK
pynetbox NetBox API Client
pyvmomi VMware vSphere API Client
docker-compose Docker Compose Python Library
cryptography Cryptographic Primitives
passlib Password Hashing

Ansible Collections

Collection Beschreibung
community.general Allgemeine Module
community.docker Docker Module
community.vmware VMware Module
netbox.netbox NetBox Module

Ansible Roles

Role Beschreibung
geerlingguy.docker Docker Installation
geerlingguy.ntp NTP Konfiguration

Cloud Provider CLIs

Cloud Provider CLIs (AWS, Azure, GCloud) sind nicht im Base-Image enthalten. Installieren Sie diese bei Bedarf über ein Dockerfile.poly:

FROM cargo.ayedo.cloud/library/polycrate:latest

# AWS CLI
RUN pip install awscli

# Azure CLI
RUN pip install azure-cli

# Google Cloud SDK
RUN curl https://sdk.cloud.google.com | bash

Container-Umgebung

Mounts

Wenn der Container startet, werden folgende Pfade gemountet:

graph LR
    Host[Host-System] --> WS[Workspace-Root]
    Host --> SSH[SSH-Keys]
    Host --> Docker[Docker Socket optional]

    WS -->|mount| CWS[Container: /workspace]
    SSH -->|mount| CSSH[Container: ~/.ssh/]
    Docker -->|mount| CDocker[Container: /var/run/docker.sock]

Host → Container Mappings:

  • $WORKSPACE_ROOT/workspace (read/write)
  • $WORKSPACE_ROOT/id_rsa~/.ssh/id_rsa (read-only)
  • /var/run/docker.sock/var/run/docker.sock (optional, für Docker-in-Docker)

Environment Variables

Der Container erhält automatisch folgende Environment Variables:

POLYCRATE_WORKSPACE_NAME="my-workspace"
POLYCRATE_BLOCK_NAME="my-block"
POLYCRATE_ACTION_NAME="install"
POLYCRATE_TRANSACTION_ID="550e8400-e29b-41d4-a716-446655440000"
POLYCRATE_SNAPSHOT_FILE="/workspace/.snapshot.yml"

Working Directory

Das Working Directory wird automatisch auf den Block-Pfad gesetzt:

# Bei lokalem Block
WORKDIR=/workspace/blocks/my-block

# Bei geertem Block (from: parent-block)
WORKDIR=/workspace/blocks/parent-block

Siehe Vererbung für Details zum Working Directory bei geerbten Blocks.

Dockerfile.poly

Polycrate sucht standardmäßig nach einem Dockerfile im Workspace (standardmäßig erwartet Polycrate eine Datei namens Dockerfile.poly; der Dateiname kann mit Hilfe des Flags --dockerfile $FILENAME angepasst werden). Wenn ein Dockerfile existiert, wird Polycrate ein Image auf Basis des Dockerfiles bauen und den Container auf Basis dieses Images starten statt des Standard-Images.

Mit Hilfe dieses Custom-Images können Anpassungen am Workspace, z.B. das Installieren von Packages oder Libraries im Polycrate-Container, persistiert werden.

Per Konvention sollte das Dockerfile.poly auf dem offiziellen Polycrate Image basieren, um existente Funktionalität nicht zu brechen:

FROM cargo.ayedo.cloud/library/polycrate:latest

RUN pip install hcloud==1.16.0

Custom Dockerfile.poly Beispiele

Beispiel 1: Python Packages installieren

FROM cargo.ayedo.cloud/library/polycrate:latest

# Python Packages für Custom Ansible Modules
RUN pip install \
    hcloud==1.16.0 \
    proxmoxer==2.0.1 \
    requests==2.31.0

Beispiel 2: Node.js Tools hinzufügen

FROM cargo.ayedo.cloud/library/polycrate:latest

# Node.js und NPM installieren (Ubuntu-basiert!)
RUN apt-get update && apt-get install -y --no-install-recommends \
    nodejs npm \
    && rm -rf /var/lib/apt/lists/*

# Global NPM Packages
RUN npm install -g \
    cdktf-cli \
    serverless

Beispiel 3: Custom CLIs und Tools

FROM cargo.ayedo.cloud/library/polycrate:latest

# Tailscale CLI
RUN wget https://pkgs.tailscale.com/stable/tailscale_1.56.1_amd64.tgz && \
    tar xzf tailscale_1.56.1_amd64.tgz && \
    mv tailscale_1.56.1_amd64/tailscale /usr/local/bin/ && \
    rm -rf tailscale_*

# Velero (Kubernetes Backup Tool)
RUN wget https://github.com/vmware-tanzu/velero/releases/download/v1.12.0/velero-v1.12.0-linux-amd64.tar.gz && \
    tar xzf velero-v1.12.0-linux-amd64.tar.gz && \
    mv velero-v1.12.0-linux-amd64/velero /usr/local/bin/ && \
    rm -rf velero-*

Beispiel 4: Ansible Collections hinzufügen

FROM cargo.ayedo.cloud/library/polycrate:latest

# Custom Ansible Collections
RUN ansible-galaxy collection install \
    community.hashi_vault:4.0.0 \
    community.vmware:3.9.0 \
    netbox.netbox:3.13.0

Beispiel 5: Multi-Cloud Setup

FROM cargo.ayedo.cloud/library/polycrate:latest

# Oracle Cloud CLI
RUN pip install oci-cli

# DigitalOcean CLI
RUN wget -O /usr/local/bin/doctl https://github.com/digitalocean/doctl/releases/download/v1.100.0/doctl-1.100.0-linux-amd64 && \
    chmod +x /usr/local/bin/doctl

# Linode CLI
RUN pip install linode-cli

Image Building

Wenn ein Dockerfile.poly im Workspace existiert:

# Polycrate buildet das Image automatisch vor jeder Action
polycrate run myblock install

# Das entspricht intern:
docker build -f Dockerfile.poly -t polycrate-workspace:latest .
docker run polycrate-workspace:latest ...

Das Image wird nur neu gebaut, wenn sich das Dockerfile.poly geändert hat.

Container Debugging

polycrate debug Command

Der einfachste Weg, eine interaktive Debug-Shell im Polycrate-Container zu starten:

# Debug-Container im aktuellen Workspace starten
polycrate debug

# Mit explizitem Workspace-Pfad
polycrate debug -w /path/to/workspace

# Mit zusätzlichen Mounts
polycrate debug -m /local/path:/container/path

# Mit zusätzlichen Environment-Variablen
polycrate debug -e MY_VAR=value

Funktionsweise:

  1. Der aktuelle Workspace wird geladen (inkl. aller Blöcke)
  2. Das Workspace-Image wird gepullt (oder gebaut bei Dockerfile.poly)
  3. Container startet mit allen Mounts, Environment-Variablen und Netzwerk-Konfiguration wie bei einem Action Run
  4. Interaktive Bash-Shell öffnet sich

Beispiel-Session:

$ polycrate debug
✓ Pulling image cargo.ayedo.cloud/library/polycrate:0.28.0

Starting debug container: polycrate-debug-a1b2c3d4
Workspace: /home/user/my-workspace
Image: cargo.ayedo.cloud/library/polycrate:0.28.0
Type 'exit' to leave the container

root@polycrate:/workspace# ls -la
drwxr-xr-x 5 root root 4096 Dec 15 10:00 blocks
-rw-r--r-- 1 root root  512 Dec 15 10:00 workspace.poly

root@polycrate:/workspace# env | grep POLYCRATE
POLYCRATE_WORKSPACE=/workspace
POLYCRATE_VERSION=0.28.0

root@polycrate:/workspace# exit
$

Use Cases:

  • Playbook-Debugging: Ansible-Playbooks manuell ausführen und testen
  • Environment-Inspektion: Prüfen welche Variablen im Container gesetzt sind
  • Pfad-Validierung: Überprüfen ob Mounts korrekt im Container ankommen
  • Tool-Verfügbarkeit: Testen ob benötigte Tools im Image vorhanden sind
  • Netzwerk-Debugging: Prüfen ob Netzwerkverbindungen aus dem Container funktionieren

→ Siehe CLI-Referenz für alle Optionen.

Container-Logs anzeigen

Polycrate zeigt standardmäßig die gesamte Container-Ausgabe an:

polycrate run myblock install
# Zeigt stdout/stderr vom Container

Manuelle interaktive Shell

Alternativ können Sie auch manuell eine Shell im Container starten:

# Mit Standard-Image
docker run -it --rm \
  -v $(pwd):/workspace \
  cargo.ayedo.cloud/library/polycrate:latest \
  /bin/bash

# Mit Custom Dockerfile.poly
docker build -f Dockerfile.poly -t polycrate-workspace:latest .
docker run -it --rm \
  -v $(pwd):/workspace \
  polycrate-workspace:latest \
  /bin/bash

Snapshot inspizieren

Im Container können Sie den Snapshot direkt inspizieren:

# Im Container
cat /workspace/.snapshot.yml
yq eval '.block.config' /workspace/.snapshot.yml

Container-Konfiguration

Container-Flags in workspace.poly

# workspace.poly
name: my-workspace

config:
  container:
    image: cargo.ayedo.cloud/library/polycrate:latest
    dockerfile: Dockerfile.poly

    # Zusätzliche Docker Run Flags
    docker_flags:
      - "--privileged"  # Für Docker-in-Docker
      - "--network=host"  # Host-Netzwerk verwenden

    # Environment Variables
    env:
      MY_CUSTOM_VAR: "value"
      API_KEY: "secret-key"

Docker Socket Mount für Docker-in-Docker

Um Docker-Befehle innerhalb des Containers auszuführen:

config:
  container:
    docker_flags:
      - "-v /var/run/docker.sock:/var/run/docker.sock"

Beispiel-Verwendung:

# Block mit Docker-in-Docker
actions:
  - name: build-and-push
    playbook: playbooks/build-and-push.yml

Docker Native Mode

Ab Version 0.28.0 bietet Polycrate einen optionalen Native Docker Mode, der das Docker Go SDK direkt verwendet statt die Docker CLI aufzurufen.

Aktivierung

# Via Flag
polycrate --docker-native run myblock install
polycrate -N run myblock install

# Via Umgebungsvariable
export POLYCRATE_DOCKER_NATIVE=true
polycrate run myblock install

# Via Konfigurationsdatei (~/.polycrate/config.yml)
# docker:
#   native: true

Vorteile

Aspekt Docker CLI Docker Native
Docker CLI Installation Erforderlich Nicht erforderlich
Performance ~50-100ms Overhead pro Aufruf Direkte API-Aufrufe
Fehlerbehandlung Text-Parsing Typisierte Errors
Output-Streaming Umständlich Native Streams

Spinner-Feedback

Im Native Mode zeigt Polycrate animierte Spinner während Docker-Operationen:

⠹ Pulling image cargo.ayedo.cloud/library/polycrate:0.28.0...
✓ Pulling image cargo.ayedo.cloud/library/polycrate:0.28.0

⠼ Building container image my-workspace:0.28.0...
✓ Building container image my-workspace:0.28.0

⠧ Cleaning up containers...
✓ Cleaning up containers

Bei höherem Loglevel (--loglevel 3) werden Spinner deaktiviert und der vollständige Output gestreamt.

Podman-Kompatibilität

Der Native Docker Mode ist auch mit Podman kompatibel. Podman kann einen Docker-kompatiblen API-Socket bereitstellen:

# 1. Podman API-Service starten (rootless)
podman system service --time=0 &

# 2. DOCKER_HOST auf Podman-Socket setzen
export DOCKER_HOST=unix:///run/user/$(id -u)/podman/podman.sock

# 3. Polycrate mit Native Backend verwenden
polycrate -N run myblock myaction
polycrate -N debug

Einschränkungen mit Podman

Multi-Arch Builds und Buildx-Features sind mit Podman nicht verfügbar. Für Production-Builds wird weiterhin Docker mit Buildx empfohlen.

Best Practices

1. Pinne Image-Versionen

# ✅ Gut: Spezifische Version
FROM cargo.ayedo.cloud/library/polycrate:1.2.3

# ❌ Schlecht: Latest (kann brechen)
FROM cargo.ayedo.cloud/library/polycrate:latest

2. Minimiere Layer

# ✅ Gut: Kombinierte RUN statements (Ubuntu-basiert!)
FROM cargo.ayedo.cloud/library/polycrate:latest
RUN apt-get update && apt-get install -y --no-install-recommends curl wget && \
    pip install --no-cache-dir boto3 requests && \
    rm -rf /var/lib/apt/lists/*

# ❌ Schlecht: Viele separate RUN statements
FROM cargo.ayedo.cloud/library/polycrate:latest
RUN apt-get update && apt-get install -y curl
RUN apt-get install -y wget
RUN pip install boto3
RUN pip install requests

3. Cleanup in derselben Layer

FROM cargo.ayedo.cloud/library/polycrate:latest

RUN wget https://example.com/tool.tar.gz && \
    tar xzf tool.tar.gz && \
    mv tool /usr/local/bin/ && \
    rm -rf tool*  # Cleanup im selben Layer

4. Versioniere dein Dockerfile.poly

# Im Workspace
git add Dockerfile.poly
git commit -m "Add custom Python packages to container"
git push

5. Teste Custom Images lokal

# Image bauen
docker build -f Dockerfile.poly -t test-polycrate .

# Interaktiv testen
docker run -it --rm test-polycrate /bin/bash

# Tools testen
docker run --rm test-polycrate ansible --version
docker run --rm test-polycrate kubectl version --client

Troubleshooting

Image Build schlägt fehl

# Prüfen Sie das Dockerfile
cat Dockerfile.poly

# Manuell builden für bessere Fehler-Ausgabe
docker build -f Dockerfile.poly -t polycrate-workspace:latest .

Package Installation schlägt fehl

# APT Cache aktualisieren (Ubuntu-basiert!)
FROM cargo.ayedo.cloud/library/polycrate:latest
RUN apt-get update && apt-get install -y --no-install-recommends my-package \
    && rm -rf /var/lib/apt/lists/*

Container startet nicht

# Container-Logs prüfen
docker ps -a
docker logs <container-id>

# Image inspizieren
docker images | grep polycrate
docker inspect cargo.ayedo.cloud/library/polycrate:latest

Permission-Probleme mit Mounts

Wenn Sie Permission-Probleme mit gemounteten Verzeichnissen haben:

config:
  container:
    docker_flags:
      - "--user $(id -u):$(id -g)"  # Als aktueller User ausführen

Zusammenhang mit anderen Konzepten

  • Snapshot: Wird in den Container als .snapshot.yml injiziert
  • Actions: Werden im Container ausgeführt
  • Workspaces: Werden in den Container gemountet
  • Integrationen: Alle Tools laufen im Container

Container-Vorteile

Der Container-basierte Ansatz garantiert: - Reproduzierbarkeit: Gleiche Umgebung auf jedem System - Isolation: Keine Konflikte mit Host-System - Portabilität: Läuft überall wo Docker läuft - Versionierung: Dockerfile.poly im Git versioniert