Your fleet, live.
A real-time web UI for Docker, remote hosts and Kubernetes, in one small binary.
docker run -d --name fleetops -p 9000:9000 \
-v fleetops-data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add "$(stat -c %g /var/run/docker.sock)" \
fleets/fleetops
Then open http://localhost:9000. Apache-2.0. Other ways to install · Pricing
Replay: one container failure, fixed in FleetOps
14:01:58. All 12 containers are running on prod-eu. Press play, or press j to step.
14:02:07. Docker reports oom, then die with exit code 137. The strip moves to Needs attention and its holder flashes. Nothing polled and nobody refreshed. Live by default
14:02:09. What needs you is a keyboard list. j and k move from strip to strip, and Enter opens the logs. Keyboard and ⌘K
14:02:11. Memory climbs to the 512 MiB limit and the log stops. The viewer keeps 200k lines, searches by text or regex, and resumes after a restart without repeating a line. The log viewer
14:02:31. Raise the limit and recreate the container. If the new one fails to start, FleetOps puts the old one back. Recreate with rollback
14:02:36. Docker reports start and the holder turns green. The audit log keeps who recreated it, and when. Roles and audit
Manages
- DockerLocal socket or remote
- PodmanThrough its Docker API
- Remote hostsDial-out agent, no open port
- KubernetesKubeconfig or in-cluster agent
- HelmInstall, upgrade, roll back
Thirty seconds, five things it did right.
Each moment in the replay is a feature you would use on a bad afternoon.
Live by default
Lists and detail pages follow Docker's own events over one websocket. Only the rows on screen subscribe to stats. When the connection drops, the page says so and how old its data is; it never passes stale state off as current.
- Updates
- Docker events, Kubernetes watches
- Polling
- None for lists
- Disconnected
- Said plainly, with the data's age
Hands stay on the keys
The attention bay is a list you walk, not a table you scan. The command palette finds any container, image or Kubernetes object and runs an action on it.
- j k
- Next and previous strip
- ↵
- Open its logs
- ⌘ K
- Jump to anything, act on it
- /
- Filter the list
A log viewer that keeps up
Virtualized to the newest 200,000 lines, with follow mode that pauses when you scroll up. A reconnect or a restart picks up where the log left off, without repeating lines.
- Search
- Text or regex, next and previous
- Streams
stdoutandstderrtoggles- Colour
- ANSI, as the app wrote it
- Export
- Lines shown, or the full log
Honest when it matters
Recreate a container with changes and, if the new one fails to start, FleetOps rolls back to the old one. The terminal never silently starts a new shell after a dropped connection, and Docker's error messages are shown exactly as Docker wrote them.
- Recreate
- Rolls back on a failed start
- Duplicate
- Host ports cleared, no clash
- Terminal
- Resize, shell detection, no respawn
Every change on the record
Every mutating action, every terminal session and every refused request is in the audit log with who did it. Roles are per environment, and on Kubernetes a role can be limited to some namespaces. All of it is in the free edition.
- Viewer
- Reads lists, logs, stats, YAML
- Operator
- Also changes things, opens terminals
- Admin
- Users, environments, access
One UI past one host.
Add remote Docker hosts and Kubernetes clusters next to the local socket. Each gets its own colour and tag, so you always know where you are before you press restart.
prod-euDockerLocal socket12 runningedge-02DockerAgent, dialled out4 runningstaging-k8sKubernetesIn-cluster agent31 podslabDockerPodman socket3 runningRemote hosts run fleetops-agent, which dials out to the server. The host opens no port and never exposes its Docker socket. Logs, terminals, stats and image builds work there exactly as they do locally.
Kubernetes clusters connect by kubeconfig or an in-cluster agent. Lists follow watch streams; every YAML edit is a dry run shown as a diff before anything is written. Helm releases install, upgrade, roll back and uninstall with the same review step.
Made for the teams that run the hosts.
Five situations FleetOps was designed around.
- Shared Docker hostsA login and a role for everyone, instead of SSH and the socket.
- Platform teamsDocker hosts and Kubernetes clusters under one set of roles.
- On-call and incidentsThe failing container rises to the top. Logs are one key away.
- Edge and remote sitesHosts behind NAT join by dialling out. Nothing is exposed.
- Air-gapped and regulatedNo call home, offline licenses, an audit log you can export.
The same afternoon, from the command line.
FleetOps does not replace the CLI. It saves you from typing it under pressure.
| Step | With the docker CLI | With FleetOps |
|---|---|---|
| Find what broke | docker ps -a | grep -v Up | It is already at the top, under Needs attention. |
| Read why | docker logs --tail 500 -f orders-api | Enter. 200,000 lines, regex search, nothing repeated on reconnect. |
| Fix it safely | docker inspect, docker rm, docker run … by hand | Recreate with the change. A failed start rolls back to the old one. |
| Say who did it | Scroll the incident channel | In the audit log, with the user, the target and the outcome. |
A socket is root. FleetOps treats it that way.
Every touch of a Docker host is signed in, allowed by a role and written down.
- Signed in, every route
- Sessions and CSRF on every Docker call; the socket is never anonymous.
- Agents dial out
- Remote hosts open no port and never expose their socket.
- Written down
- Every change, terminal session and refused request, with who did it.
- No call home
- Offline licenses, no telemetry, a distroless non-root image.
Weight is a feature.
A Rust binary with the web UI and a SQLite database inside. Nothing else to run, nothing to upgrade in lockstep.
| Server | One static binary, about 15–17 MB | linux/amd64, linux/arm64 |
|---|---|---|
| Image | About 8 MB compressed per platform | distroless, runs as non-root |
| Storage | One SQLite file in WAL mode | no external database |
| Memory target | Under 50 MB idle with about 50 containers | a design target, not a benchmark |
| Heavy parts | Terminal and charts load only when opened | per tab, on demand |
Free to run. Priced by the node when you grow.
Community has no node or user limit. Paid plans add the Enterprise parts and support.
Community
Free
The whole product, for any team, forever.
Unlimited nodes and users
Starter
$9/ month for 5 nodes
Small teams that want the Enterprise parts.
5, 10 or 15 nodes
Scale
Recommended$19/ month for 5 nodes
Teams running FleetOps in production.
5 to 25 nodes
Enterprise
Custom
Larger fleets and procurement needs.
More than 25 nodes
Yearly billing: Starter $99, Scale $199 per 5 nodes. Full pricing
See your own containers in a minute.
docker run -d --name fleetops -p 9000:9000 \
-v fleetops-data:/data \
-v /var/run/docker.sock:/var/run/docker.sock \
--group-add "$(stat -c %g /var/run/docker.sock)" \
fleets/fleetops