Prodios Labs

$ ./projects/fleetbase

01Advanced

Fleetbase

Fleetbase is a self-hosted deployment platform built on Docker Swarm

// docs

README

Fleetbase

Fleetbase is a self-hosted, open-source deployment platform — think of it as your own private Dokploy or Heroku that you run on your own servers. You point Fleetbase at a Git repository or a Docker image, and it builds, ships, and runs your application for you.

Under the hood, Fleetbase uses Docker Swarm as its orchestration engine. Swarm turns one or many machines into a single logical cluster, handles scheduling containers across nodes, keeps the desired number of replicas alive, and provides rolling updates, service discovery, and an internal load balancer out of the box. Fleetbase is the friendly control plane on top of it.

The goal of the hackathon project is to build a working slice of this platform: a control plane (API + web UI) that can take an app from a Git repo to a running, publicly-reachable service on a Swarm cluster.


What you are building

At a high level, a user of Fleetbase should be able to:

  1. Connect a source — a GitHub repository or a prebuilt Docker image.
  2. Create an application — configure the build, environment variables, ports, and domain.
  3. Deploy — Fleetbase builds an image, pushes it to a registry, and creates/updates a Docker Swarm service.
  4. Expose it — a reverse proxy routes myapp.example.com to the right container, with automatic HTTPS.
  5. Observe & operate — view logs, metrics, deployment history, and roll back to a previous release.

Architecture overview

Fleetbase is split into a control plane (the brains: API, UI, database) and a data plane (the muscle: the Swarm cluster running user workloads).

Rendering diagram…

The pieces

1. Web UI (control plane frontend) A single-page app where users manage projects, trigger deploys, watch build/runtime logs stream in real time, and edit environment variables and domains. Talks to the API over REST for actions and WebSockets (or SSE) for live logs.

2. API Server (control plane backend) The core of Fleetbase. Responsibilities:

  • Authentication & authorization — users, teams, and API tokens.
  • Domain model — projects, applications, deployments, environment variables, domains.
  • Orchestration — translates high-level intent ("deploy this app") into Docker Swarm API calls.
  • Job dispatch — hands long-running work (git clone, image build, push) to background workers.

3. Build workers / job queue Building images is slow and resource-intensive, so it must happen asynchronously. A queue holds deploy jobs; workers pick them up and run the pipeline: clone repo → build image → push to registry → update Swarm service. Each step's output is streamed back so the UI can show live build logs.

4. State database (PostgreSQL) The source of truth for the control plane: who owns what, deployment history, config, secrets (encrypted), and domain mappings. Note that Swarm keeps its own state about running services — Fleetbase's DB stores the user's intent and history, and reconciles it against the cluster.

5. Container registry A place to store the built images. Can be self-hosted (the registry:2 image) or an external one (GHCR, Docker Hub). Swarm nodes pull images from here when scheduling tasks.

6. Docker Swarm cluster (data plane) One or more machines joined into a Swarm. Manager nodes hold the cluster state and schedule work; worker nodes run the actual containers. Fleetbase creates one Swarm service per application, with N replicas, and relies on Swarm to keep them running and to perform rolling updates.

7. Reverse proxy / ingress (Traefik or Caddy) User apps run on private overlay networks and are not directly exposed. A reverse proxy sits at the edge, routes incoming requests by hostname to the correct Swarm service, and terminates TLS (automatic Let's Encrypt certificates). Traefik is especially popular here because it can auto-discover Swarm services via labels.


How a deployment flows

Understanding this end-to-end path is the heart of the project:

  1. Trigger — user clicks Deploy (or a GitHub webhook fires on push). The API creates a deployment record in pending state and enqueues a job.
  2. Fetch source — a worker clones the Git repo at the target commit (or pulls the specified image).
  3. Build — the worker builds a Docker image. Two common strategies:
    • a Dockerfile in the repo, or
    • buildpacks (e.g. Nixpacks / Cloud Native Buildpacks) that auto-detect the language and produce an image with no Dockerfile.
  4. Push — the image is tagged (usually with the commit SHA) and pushed to the registry.
  5. Release — the worker calls the Docker API to docker service create or docker service update with the new image, environment variables, resource limits, and proxy labels.
  6. Rolling update — Swarm spins up new tasks, waits for them to be healthy, then drains the old ones. If health checks fail, Swarm can automatically roll back.
  7. Route — the proxy detects the (updated) service and begins routing the app's domain to it over HTTPS.
  8. Report — the deployment record is marked success (or failed), and logs/metrics become available in the UI.

Technologies to use

The whole stack is TypeScript / JavaScript end-to-end — pick what your team is fastest in within that ecosystem. The concepts matter more than the exact library.

LayerOptions
RuntimeNode.js or Bun (TypeScript throughout)
API serverHono (with @hono/node-server), or Hono on Bun
Talking to DockerDockerode, or the raw Engine API over the Unix socket via fetch / undici
DatabasePostgreSQL with Drizzle ORM (or Prisma)
Job queueBullMQ + Redis, or a Postgres-backed queue (e.g. pg-boss)
Web UIReact (Next.js or Vite) — anything that can stream logs
Live logsWebSockets (ws) or Server-Sent Events (SSE) — both first-class in Hono
ValidationZod (shared types between API and UI)
Image buildsdocker build shelled out via execa, Nixpacks, or BuildKit
RegistrySelf-hosted registry:2, or GHCR / Docker Hub
Reverse proxyTraefik (great Swarm integration) or Caddy
TLSLet's Encrypt via the proxy (ACME)

Concepts to understand

Before writing code, make sure the team is comfortable with these ideas.

Docker fundamentals

  • Image vs. container — an image is an immutable, layered blueprint; a container is a running instance of it.
  • Dockerfile & layers — how builds are cached and why layer order matters.
  • Registries — how images are pushed, pulled, and tagged.

Docker Swarm

  • Swarm modedocker swarm init / docker swarm join; managers vs. workers.
  • Services vs. tasks — a service is the declared desired state (image + replicas); a task is a single container instance scheduled onto a node.
  • Declarative & self-healing — you declare "I want 3 replicas"; Swarm makes reality match and restarts failed tasks.
  • Rolling updates & rollbacksdocker service update with --update-parallelism and --rollback.
  • Overlay networks — multi-host virtual networks that let services on different nodes talk to each other privately.
  • Ingress & the routing mesh — Swarm's built-in load balancer that makes a published port reachable on every node.
  • Secrets & configs — Swarm's native mechanism for delivering sensitive data to services.

The control plane / data plane split

  • Why the thing that manages deployments should be separate from the thing that runs the workloads.
  • Reconciliation — comparing desired state (your DB) with actual state (the cluster) and closing the gap. This is the same idea Kubernetes controllers use.

Reverse proxying & networking

  • Host-based routing — mapping app.example.com → an internal service.
  • TLS termination and automatic certificate issuance (ACME / Let's Encrypt).
  • Service discovery — how the proxy finds services (e.g. Docker labels + the Swarm API).

Asynchronous work

  • Why builds must be async — long jobs can't block an HTTP request.
  • Queues, workers, idempotency, and retries — deploys should be safe to re-run.
  • Streaming output — piping build/runtime logs to the browser in real time.

Operational concerns

  • Zero-downtime deploys via health checks and rolling updates.
  • Secrets management — never storing plaintext credentials; encrypting env vars at rest.
  • Observability — logs, metrics, and deployment history for debugging.

Suggested milestones

A realistic path for a hackathon, from smallest useful slice to full loop:

  1. Talk to Swarm — a CLI/API endpoint that creates a Swarm service from an existing image and lists running services.
  2. Persist state — model projects, apps, and deployments in Postgres; wire up the API + a minimal UI.
  3. Build from a Dockerfile — a worker that clones a repo, builds an image, and pushes it to a local registry.
  4. Close the loop — the full flow: trigger → build → push → service update, with live logs in the UI.
  5. Expose it — add Traefik so a deployed app is reachable at a real hostname over HTTPS.
  6. Polish — rollbacks, environment variables, health checks, and deployment history.

Stretch goals

  • GitHub webhook auto-deploys on push.
  • Preview environments per pull request.
  • Multi-node clusters with node labels / placement constraints.
  • Resource metrics (CPU / memory) per service.
  • Buildpack support so users don't need a Dockerfile.
  • Databases-as-a-service (one-click Postgres/Redis running as Swarm services).