Architecture
┌──────────────┐ Browser ────────┤ Traefik │ TLS termination + Host-rule routing └──┬───────┬───┘ │ │ ┌─────────────▼───┐ ┌─▼──────────────┐ ┌──────────┐ │ pipebase- │ │ pipebase- │ │pipebase- │ │ designer │ │ runtime │ │docs │ │ (Hono on :3000) │ │ (Camel on :8080)│ │(nginx) │ └─────┬───────────┘ └─┬──────────────┘ └──────────┘ │ token-auth │ Camel routes │ /_api/* │ ▼ ▼ ┌─────────────────────────┐ │ Internal Docker │ │ network: coolify │ │ │ │ ┌──────────┐ ┌────────┐│ Opt-in (--profile mesh): │ │ kafka │ │ pulsar ││ cross-runtime message bus │ └──────────┘ └────────┘│ └─────────────────────────┘
Volumes: ipaas_ipaas-runtime-routes ← Camel YAML files ipaas_ipaas-designer-flows ← flow definitions, layouts, params pipebase-{kafka,pulsar}-data ← broker logs (only with profiles)Three-tier separation
Section titled “Three-tier separation”- Designer (Hono backend + React SPA) — owns the YAML on disk,
talks to the runtime over
/_api/*to deploy/test/undeploy. Stateless — all persistent state lives in the volume. - Runtime (Camel) — owns the running routes, exposes
platform-http:for user-defined HTTP triggers. Hot-reloads viaPUT /_api/flows/:id. - Mesh (Kafka + Pulsar) — opt-in. Lets flows on different runtimes communicate via topics rather than direct HTTP.
Request lifecycle: deploying a flow
Section titled “Request lifecycle: deploying a flow”- Author in
https://designer.<root>— visual edit on canvas - Save — designer writes
flow.camel.yaml + flow.layout.jsonto its disk volume (ipaas_ipaas-designer-flows) - Deploy — designer reads the YAML, applies parameter
substitution (global → per-runtime → per-flow overrides), and
PUTs to the runtime’s/_api/flows/:id - Runtime validates the YAML with an ephemeral
DefaultCamelContext, stops + removes any existing routes for that flow id, andaddRoutesto the live context - Traffic — incoming HTTP at
runtime.<root>/<route-path>hits the new route immediately
Request lifecycle: a webhook trigger
Section titled “Request lifecycle: a webhook trigger”- Client POSTs to
https://runtime.<root>/api/<route-id> - Traefik terminates TLS, routes to
pipebase-runtime - Camel platform-http dispatches to the matching route
- Steps execute — each step’s elapsed time is captured by Camel’s
MessageHistoryfor the run-history feature - Response — the last step’s body is the response body
- Run-history notifier persists the exchange to the in-memory
ring buffer; the designer’s RunPanel polls
/_api/runs?routeId=<id>to render it
Why YAML is canonical
Section titled “Why YAML is canonical”Three reasons:
- Camel speaks YAML. Translating BPMN→YAML→Camel happens at designer save time; runtime never sees BPMN.
- Diffable. Git diffs on Camel YAML are readable; BPMN XML is not.
- No bidirectional drift. Edits via the designer round-trip
through the translator’s parser/serializer; we test
serialize(parse(yaml)) === yamlto guarantee stability.
The BpmnLayout (shapes/edges/extras) is the SPA’s concern, persisted
next to the YAML by the designer backend. The runtime treats layout
data as opaque — it never reads flow.layout.json.
Where data lives
Section titled “Where data lives”| Data | Location | Survives container rebuild? |
|---|---|---|
| Flow YAML (canonical) | ipaas_ipaas-runtime-routes volume | ✓ |
| Flow definitions + layouts | ipaas_ipaas-designer-flows volume | ✓ |
| Run history | runtime in-memory ring buffer | ✗ |
| Live trace + logs | runtime SSE stream | ✗ |
| TLS certs | Traefik’s acme.json | ✓ (Traefik volume) |
.env | repo / orchestrator | depends on backup |
Related
Section titled “Related”- Concepts: Flows — what a flow is
- API reference — exact endpoints
- Operations: Backup — what to copy