Zum Hauptinhalt springen
S-EDV news
← Alle Anleitungen
📘 Anleitung Docker 10.10.2026 · 11 min Lesezeit

Activepieces mit Docker Compose: Zapier-Alternative selbst hosten

Activepieces automatisiert Abläufe zwischen Webanwendungen wie Zapier, läuft aber auf dem eigenen Server. Die Anleitung zeigt Installation mit Docker Compose, Admin-Konto, einen Webhook-Flow mit curl, Nginx mit WebSockets, Backup und Restore der Datenbank sowie Updates und typische Fehler.

Geprüft am 10.10.2026 · für Activepieces 0.92.2, pgvector PostgreSQL 0.8.0-pg14, Redis 7.0.7

Mit KI erstellt – redaktionelle Prüfung ausstehend

WerbelinksMit * markierte Links sind Werbelinks: Bei einem Kauf erhalten wir eine Provision, der Preis bleibt gleich. Als Amazon-Partner verdiene ich an qualifizierten Verkäufen. Mehr dazu

Activepieces mit Docker Compose: Flow-Editor, Webhook und Backup als Symbolbild

Activepieces verbindet Webanwendungen, Formulare und interne Systeme zu automatischen Abläufen, ähnlich wie Zapier oder Make, läuft aber auf Ihrem eigenen Server. Für KMU heißt das: Kundendaten bleiben im eigenen Haus. Diese Anleitung installiert Activepieces 0.92.2 mit Docker Compose, PostgreSQL und Redis, baut einen ersten Flow mit Webhook-Auslöser, löst ihn per curl aus und zeigt Backup, Restore, Reverse Proxy und Updates.

Voraussetzungen

Die Projektdoku nennt mindestens 2 vCPU und 4 GB RAM. Direkt nach dem Start belegte der Stack im Test rund 1 GB: App 636 MiB, Worker 273 MiB, PostgreSQL 68 MiB, Redis 4 MiB. Laufende Flows kommen hinzu; für Produktion rechnet die Doku mit 0,5 vCPU und 1 GB je gleichzeitig laufendem Flow.

  • Linux-Server mit Docker Engine und Docker Compose v2, mindestens 2 CPU-Kerne und 4 GB RAM.
  • x86_64 oder ARM64: Das Image ghcr.io/activepieces/activepieces:0.92.2 gibt es für linux/amd64 und linux/arm64.
  • Rund 2 GB Platz für Images sowie Platz für die Datenbank. Sie war schon leer 257 MB groß, davon 244 MB Metadaten der mitgelieferten Bausteine (Pieces).
  • Ein DNS-Name wie automation.example.de mit TLS-Zertifikat, wenn externe Dienste Webhooks senden sollen.
  • Ausgehender Internetzugang, denn Bausteine werden bei der ersten Nutzung nachgeladen.

Nutzen, Lizenz und Grenzen

Activepieces bringt einen grafischen Flow-Editor, fertige Bausteine für gängige Dienste, Code-Schritte, Webhooks, Zeitpläne und KI-Schritte. Im Vergleich zu n8n ist der Editor einfacher und eher für Fachabteilungen gedacht; Windmill zielt stärker auf Entwickler mit Skripten.

Zur Lizenz: Der Code steht unter MIT, ausgenommen die Verzeichnisse packages/ee/ und packages/server/api/src/app/ee. Diese fallen unter eine eigene Enterprise-Lizenz, die den Produktivbetrieb nur mit gültigem Abonnement erlaubt. Ohne AP_EDITION startet die Community Edition, die Schnittstelle /api/v1/flags meldete im Test "EDITION":"ce". Im Admin-Bereich tragen SSO, Geheimmanager, Audit-Protokolle, API-Schlüssel, Embedding und Worker-Gruppen den Hinweis Requires a plan upgrade.

Schritt 1: Projektordner, compose.yaml und .env anlegen

Die Vorlage basiert auf der docker-compose.yml zum Tag 0.92.2 und dem offiziellen Installationsskript. Geändert: keine festen container_name (Kollisionsgefahr), Healthchecks für PostgreSQL und Redis, ein Worker statt replicas: 5.

mkdir -p /opt/activepieces && cd /opt/activepieces
services:
  app:
    image: ghcr.io/activepieces/activepieces:${AP_VERSION}
    restart: unless-stopped
    ports:
      - "${AP_HOST_PORT}:80"
    depends_on:
      postgres:
        condition: service_healthy
      redis:
        condition: service_healthy
    env_file: .env
    environment:
      - AP_CONTAINER_TYPE=APP
    volumes:
      - ./cache:/usr/src/app/cache
    networks:
      - activepieces

  worker:
    image: ghcr.io/activepieces/activepieces:${AP_VERSION}
    restart: unless-stopped
    depends_on:
      - app
    env_file: .env
    environment:
      - AP_CONTAINER_TYPE=WORKER
      # Der Worker erreicht die App im Docker-Netz, nicht über die öffentliche URL
      - AP_FRONTEND_URL=http://app
    volumes:
      - ./cache:/usr/src/app/cache
    networks:
      - activepieces

  postgres:
    image: pgvector/pgvector:0.8.0-pg14
    restart: unless-stopped
    environment:
      - POSTGRES_DB=${AP_POSTGRES_DATABASE}
      - POSTGRES_USER=${AP_POSTGRES_USERNAME}
      - POSTGRES_PASSWORD=${AP_POSTGRES_PASSWORD}
    volumes:
      - postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${AP_POSTGRES_USERNAME} -d ${AP_POSTGRES_DATABASE}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - activepieces

  redis:
    image: redis:7.0.7
    restart: unless-stopped
    volumes:
      - redis_data:/data
    healthcheck:
      test: ["CMD", "redis-cli", "ping"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - activepieces

volumes:
  postgres_data:
  redis_data:

networks:
  activepieces:

Die .env liegt im selben Ordner. Erzeugen Sie die Geheimnisse und tragen Sie sie ein:

openssl rand -hex 64   # AP_API_KEY
openssl rand -hex 16   # AP_ENCRYPTION_KEY (genau 32 Zeichen)
openssl rand -hex 32   # AP_JWT_SECRET
openssl rand -hex 32   # AP_POSTGRES_PASSWORD
chmod 600 .env
AP_VERSION=0.92.2
AP_HOST_PORT=8080
AP_ENVIRONMENT=prod
AP_FRONTEND_URL=https://automation.example.de
AP_EXECUTION_MODE=SANDBOX_CODE_ONLY
AP_ENGINE_EXECUTABLE_PATH=dist/packages/engine/main.js

# Geheimnisse mit openssl erzeugen, siehe unten
AP_API_KEY=ERSETZEN_openssl_rand_hex_64
AP_ENCRYPTION_KEY=ERSETZEN_openssl_rand_hex_16
AP_JWT_SECRET=ERSETZEN_openssl_rand_hex_32

AP_POSTGRES_HOST=postgres
AP_POSTGRES_PORT=5432
AP_POSTGRES_DATABASE=activepieces
AP_POSTGRES_USERNAME=postgres
AP_POSTGRES_PASSWORD=ERSETZEN_openssl_rand_hex_32
AP_REDIS_HOST=redis
AP_REDIS_PORT=6379

AP_WEBHOOK_TIMEOUT_SECONDS=30
AP_FLOW_TIMEOUT_SECONDS=600
AP_TELEMETRY_ENABLED=false

AP_HOST_PORT ist der Port auf dem Host. Setzen Sie nicht AP_PORT, das ist der Port im Container. AP_EXECUTION_MODE=SANDBOX_CODE_ONLY isoliert Code-Schritte; die Vorlage .env.example enthält UNSANDBOXED, was nur in der Community Edition startet.

Verifizieren: docker compose config --quiet läuft ohne Ausgabe durch, und grep -E '^AP_(ENCRYPTION_KEY|JWT_SECRET|POSTGRES_PASSWORD)=.+' .env liefert drei Zeilen.

Schritt 2: Stack starten und Healthchecks prüfen

docker compose up -d
docker compose ps
curl -s http://localhost:8080/api/v1/health

Beim ersten Start legt die App das Schema per Migration an. Das Image bringt einen eigenen Healthcheck auf /api/v1/health mit. Im Log des Workers stehen anfangs einige Zeilen Socket.IO connection error, bis die App bereit ist; nach rund 16 Sekunden folgte Connected to API server via Socket.IO.

Verifizieren: Alle vier Dienste stehen auf Up (healthy), die Health-Abfrage liefert {"status":"Healthy"}, und docker compose logs worker | grep -i socket endet mit Connected to API server via Socket.IO.

Schritt 3: Admin-Konto anlegen und Registrierung prüfen

Öffnen Sie die URL aus AP_FRONTEND_URL und registrieren Sie sich. Ein Standardkonto gibt es nicht: Das erste Konto wird Plattform-Admin. Danach ist die Registrierung geschlossen; ein zweiter Versuch ohne Einladung endete im Test mit HTTP 403 und INVITATION_ONLY_SIGN_UP, User is not invited to the platform. Legen Sie das Admin-Konto deshalb sofort nach dem Start an, bevor die Instanz öffentlich erreichbar ist. Weitere Personen laden Sie unter Plattform-Admin, Benutzer ein.

Unter Plattform-Admin, Operations, Arbeiter prüfen Sie, ob der Worker verbunden ist.

Activepieces Plattform-Admin, Seite Arbeiter mit einem Worker im Status online, Version 0.92.2 sowie CPU-, RAM- und Festplattenanzeige
Plattform-Admin, Arbeiter: Ein Worker ist online. Funktionen mit dem Hinweis „Requires a plan upgrade“ gehören zu den bezahlten Plänen.

Verifizieren: Die Seite Arbeiter zeigt mindestens einen Eintrag mit dem Status online und der Version 0.92.2. Ist die Liste leer, lesen Sie den Abschnitt Troubleshooting.

Schritt 4: Ersten Flow mit Webhook bauen

Als Beispiel nimmt ein Flow eine JSON-Anfrage entgegen, baut daraus eine Antwort und sendet sie direkt zurück.

  1. Automatisierungen, Neu erstellen, als Auslöser Webhook, Catch Webhook wählen, Authentifizierung zunächst Keine.
  2. Schritt Code hinzufügen. Unter Eingaben den Schlüssel kunde anlegen und per Data Selector das Feld body.kunde des Auslösers wählen.
  3. Schritt Webhook, Return Response mit Typ JSON, Ausführung Stop und dem Ergebnis des Code-Schritts als Body ergänzen.
  4. Oben rechts veröffentlichen. Der Schalter neben dem Flow-Namen steht danach auf aktiv.
export const code = async (inputs) => {
  return { gruss: "Hallo " + inputs.kunde, zeit: new Date().toISOString() };
};
Activepieces Flow-Editor mit den Schritten Catch Webhook, Antwort bauen und Antwort senden, rechts die Einstellungen des Webhook-Auslösers mit Live-URL
Der Flow im Editor: Webhook-Auslöser, Code-Schritt und Antwort. Rechts stehen Live-URL sowie die Hinweise zu /sync und /test.

Verifizieren: Der Flow trägt in der Liste Automatisierungen den Status aktiv, und der Auslöser zeigt eine Live-URL mit Ihrer Domain und der Flow-ID.

Schritt 5: Flow per curl auslösen

Die Live-URL hat die Form /api/v1/webhooks/<Flow-ID>. Mit angehängtem /sync wartet der Aufruf auf die Antwort des Flows:

FLOW=CJgyR172mGDXkQkUKLh38   # Flow-ID aus der Live-URL
curl -s -X POST -H 'Content-Type: application/json' \
  -d '{"kunde":"Muster GmbH"}' \
  https://automation.example.de/api/v1/webhooks/$FLOW/sync
# {"gruss":"Hallo Muster GmbH","zeit":"2026-10-10T00:21:29.989Z"}

Ohne /sync antwortet Activepieces sofort mit HTTP 200 und {} und arbeitet den Flow im Hintergrund ab. Die Statuscodes im Test sind für Skripte wichtig:

  • /sync ohne Schritt Return Response: HTTP 408.
  • Deaktivierter Flow: HTTP 404 mit leerem JSON.
  • Unbekannte, formal gültige Flow-ID: HTTP 410.
  • Flow-ID im falschen Format: HTTP 400, params/flowId Invalid string.
Activepieces Ausführungsansicht: alle drei Schritte erfolgreich, rechts die Ausgabe des Code-Schritts mit gruss Hallo Beispiel AG
Die Ausführung im Detail: Jeder Schritt zeigt Status, Dauer, Eingabe und Ausgabe.

Verifizieren: Unter Ausführungen erscheint je Aufruf ein Eintrag mit Succeeded; ein Klick zeigt Eingabe und Ausgabe jedes Schritts.

Schritt 6: Reverse Proxy mit TLS

Der Editor nutzt WebSockets unter /api/socket.io. Ohne Upgrade-Header funktionieren Test-Schaltflächen und Live-Anzeigen nicht. Eine passende Nginx-Konfiguration:

map $http_upgrade $connection_upgrade {
    default upgrade;
    ''      close;
}
server {
    listen 443 ssl;
    http2 on;
    server_name automation.example.de;
    ssl_certificate     /etc/ssl/automation/fullchain.pem;
    ssl_certificate_key /etc/ssl/automation/privkey.pem;
    client_max_body_size 25m;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection $connection_upgrade;
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_read_timeout 300s;
    }
}

Setzen Sie AP_FRONTEND_URL auf die HTTPS-Adresse und starten Sie mit docker compose up -d neu. Binden Sie den Port danach mit "127.0.0.1:${AP_HOST_PORT}:80" nur an localhost. Wichtig: Der Server muss diese Adresse selbst auflösen und erreichen können, auch hinter NAT. Wer Caddy bevorzugt, findet die Unterschiede im Vergleich Caddy, Nginx und Traefik.

Verifizieren: curl -s https://automation.example.de/api/v1/health liefert Healthy, und ein WebSocket-Handshake auf /api/socket.io/?EIO=4&transport=websocket mit Upgrade-Headern antwortet mit HTTP 101.

Schritt 7: Backup und Restore

Flows, Ausführungen und verschlüsselte Verbindungen liegen im Volume postgres_data, nicht im Projektordner. ./cache enthält nur nachladbare Bausteine. Ohne AP_ENCRYPTION_KEY lassen sich gespeicherte Zugangsdaten auch aus einem vollständigen Dump nicht entschlüsseln, deshalb gehört die .env immer dazu.

cd /opt/activepieces && mkdir -p backup
docker compose exec -T postgres pg_dump -U postgres -d activepieces -Fc \
  > backup/activepieces-$(date +%F).dump
cp .env backup/env-$(date +%F).bak
chmod 600 backup/*

Der Dump war 107 MB groß. Für den Restore stoppen Sie App und Worker, sonst blockieren offene Verbindungen DROP DATABASE:

docker compose stop app worker
docker compose exec -T postgres psql -U postgres -d postgres \
  -c "DROP DATABASE activepieces;" -c "CREATE DATABASE activepieces;"
docker compose exec -T postgres pg_restore -U postgres -d activepieces \
  --no-owner --exit-on-error < backup/activepieces-2026-10-10.dump
docker compose start app worker

Im Test wurde die Datenbank gelöscht und neu angelegt, sie enthielt danach keine Tabellen. pg_restore endete mit Exit-Code 0, alle sieben Ausführungen waren wieder da, und derselbe Webhook antwortete mit {"gruss":"Hallo Nach Restore GmbH"}.

Verifizieren: docker compose exec -T postgres psql -U postgres -d activepieces -tAc "select count(*) from flow" zeigt dieselbe Zahl wie vor dem Backup, und ein Webhook-Aufruf liefert wieder die erwartete Antwort.

Schritt 8: Updates und Rollback

Lesen Sie vor jedem Update die Breaking Changes. Version 0.92.0 hat etwa die Abrechnung von KI-Schritten umgestellt. Dann:

cd /opt/activepieces
docker compose exec -T postgres pg_dump -U postgres -d activepieces -Fc \
  > backup/vor-update-$(date +%F).dump
sed -i 's/^AP_VERSION=.*/AP_VERSION=0.92.3/' .env   # Zielversion aus den Releases
docker compose pull && docker compose up -d

Die App migriert beim Start die Datenbank. Für ein Rollback tragen Sie die alte Version ein und spielen den Dump wie in Schritt 7 zurück.

Verifizieren: curl -s http://localhost:8080/api/v1/flags | grep -o '"CURRENT_VERSION":"[^"]*"' zeigt die neue Version, und die Seite Arbeiter nennt dieselbe Nummer.

Troubleshooting

Flow lässt sich nicht veröffentlichen, Fehler fetch failed. Die API meldete TRIGGER_UPDATE_STATUS mit "standardError":"fetch failed", im Worker-Log stand [pieceInstaller] Skipping pieces whose bundle download failed after retries. Ursache: Der Worker lädt Bausteine über die Adresse aus AP_FRONTEND_URL, die der Server selbst nicht erreichte. Abhilfe: DNS und Hairpin-NAT prüfen oder die Domain per extra_hosts auf die interne Proxy-Adresse zeigen lassen.

App startet nicht, Execution mode UNSANDBOXED is no longer supported in this edition. Tritt auf, sobald AP_EDITION=ee gesetzt ist. Stellen Sie auf SANDBOX_CODE_ONLY um.

AP_ENCRYPTION_KEY is missing or invalid. Der Schlüssel fehlt oder hat nicht genau 32 Hex-Zeichen. Der Container läuft dann in einer Neustartschleife. Erzeugen Sie ihn mit openssl rand -hex 16; bei bestehender Datenbank muss es der alte Schlüssel sein.

Seite Arbeiter leer. Der Worker hat die öffentliche URL statt http://app erhalten. Prüfen Sie den Override im worker-Dienst und docker compose logs worker | grep -i socket.

Code-Schritt erhält leere Werte. Wer Flows als JSON importiert oder per API baut: Im Test lieferte der Ausdruck {{trigger.body.kunde}} ohne Fehlermeldung einen leeren String, {{trigger.output.body.kunde}} dagegen den Wert. Nutzen Sie im Editor den Data Selector.

Häufige Fragen

Brauche ich Redis und mehrere Worker?

Redis ist die Warteschlange und Pflicht. Für mehr parallele Flows erhöhen Sie deploy.replicas beim worker.

Wie sichere ich Webhooks ab?

Der Auslöser Catch Webhook kennt die Authentifizierung Basic Auth, Header Auth und HMAC-Signatur. Ohne Einstellung kann jeder, der die URL kennt, den Flow starten. Wählen Sie für produktive Flows mindestens Header Auth.

Ist das Installationsskript eine Alternative?

Ja. curl -fsSL https://get.activepieces.com | sh erzeugt Compose-Datei und .env automatisch, setzt aber AP_EDITION=ee. Mit dem manuellen Weg sehen Sie jede Datei vor dem Start.

Activepieces entfernen

Warnung: down -v löscht das Volume postgres_data und damit alle Flows, Ausführungen und gespeicherten Zugangsdaten unwiderruflich. Sichern Sie vorher wie in Schritt 7.

cd /opt/activepieces
docker compose down        # Container weg, Daten bleiben
docker compose down -v     # zusätzlich alle Volumes löschen
rm -rf /opt/activepieces

Fazit

Activepieces läuft mit vier Containern zuverlässig und ist nach wenigen Minuten bereit. Im Test funktionierten Webhook-Flow, Antwort per /sync, Registrierungssperre sowie Backup und Restore auf Anhieb. Die Stolpersteine liegen in der Konfiguration: AP_FRONTEND_URL muss vom Server erreichbar sein, der Worker braucht http://app, und ohne AP_ENCRYPTION_KEY ist jedes Backup nur die halbe Sicherung.

EckdatenWert
Version0.92.2 (Release vom 07.10.2026)
Imageghcr.io/activepieces/activepieces:0.92.2 (amd64, arm64)
Weitere Imagespgvector/pgvector:0.8.0-pg14, redis:7.0.7
Port8080 auf dem Host, 80 im Container
DatenVolume postgres_data, Cache ./cache
Wichtige VariablenAP_FRONTEND_URL, AP_ENCRYPTION_KEY, AP_JWT_SECRET, AP_EXECUTION_MODE
Healthcheck/api/v1/health, im Image enthalten
LizenzMIT, Enterprise-Verzeichnisse unter eigener Lizenz

Weiterführende Anleitungen und Quellen

ActivepiecesAutomatisierungDocker ComposeWebhookPostgreSQLZapier-AlternativeSelfhosting