Architecture
How the control plane, agents and Traefik fit together.
ZenSailor is a microservices platform running entirely on Docker. A single installer brings up every component, and a remote node only needs the agent.
Control Plane
The Next.js dashboard and API server. It manages state, users, projects and orchestration, and coordinates every deployment.
Agent
Runs on every node — including the main one. It listens for commands via NATS and executes Docker operations, and reports node health every 30 seconds.
NATS
A lightweight messaging system used for all communication between the Control Plane and the agents, with a JetStream queue for deployments.
Traefik
The edge router. It automatically discovers running services and routes traffic, and handles SSL termination with Let's Encrypt.
PostgreSQL
Stores platform data — users, projects, services and deployment history.
Local Registry
Every node runs a Docker Registry 2 on localhost so build artifacts and images travel node-to-node over the agent transport.
How a deployment flows#
- You push to your repository (or trigger a redeploy webhook).
- The control plane schedules the deployment and tells the build agent to start through NATS.
- The agent builds the image — with Cloud Native Buildpacks, a Dockerfile, or a compose file — and pushes it to the node's local registry.
- The new container is started behind Traefik; once its health check passes, the previous one is stopped (blue/green), so traffic never drops.
- The deployment, its logs and its placement are written back to the control plane and stream to the dashboard.
Main node and remote nodes#
The first node is the main node: it runs the control plane, the database, NATS and Traefik next to an agent. Every additional node runs only the agent and Docker — you add it from System → Nodes in the dashboard. Agents are pinned to the platform version and update themselves automatically when the control plane updates.
A node that stops reporting for 90 seconds is marked offline. Services are never scheduled onto an offline or pressured node.