Contents

Komodo vs Portainer: Container Management Compared

One is a mature web UI over the Docker API. The other wants your compose files in Git.

Contents

I have four machines running containers: a mini PC that does the always-on services, a noisier box with disks in it, an old laptop in a cupboard doing nothing important, and a Pi at the edge of the network. Managing them means four SSH sessions and a decent memory for which stack lives where. That memory has failed me often enough that I have twice gone looking for a control plane.

Portainer is what most people find. It has been around since 2016, it is the default answer on every forum, and it does exactly what the screenshots suggest. Komodo is the other end of the spectrum: a Rust project that spent most of its life called Monitor and was renamed only a few weeks ago, which means the documentation, the GitHub URL and half the community’s bookmarks are still catching up. I have run both against the same four machines for a couple of months. They are solving different problems while appearing to solve the same one.

The architectural split

Advertisement

Portainer is a web UI over the Docker API. On the machine you install it, it talks to the local socket. On the other machines, you install the Portainer Agent, which exposes the remote Docker API back to the server over a TLS tunnel. Everything you can do in the UI maps onto an API call: create a container, pull an image, inspect a network, exec into a shell. It is a good UI for that API — the container detail view, the network diagram and the log viewer are all better than anything I would build.

Komodo splits into Core and Periphery. Core is the server and web UI; Periphery is a small agent you install on each managed host. So far, identical. The difference is the unit of work. Portainer’s mental model is the container. Komodo’s is the resource: a Stack, a Build, a Repo, a Procedure, an Alerter — each one a named object with a definition, a history, and a toggle to sync it from a Git repository.

That distinction is the whole comparison. If you want to look at a running container and poke it, Portainer wins on the first click. If you want the definition of your homelab to live in a repo and the UI to be a view onto it, Komodo was built for that and Portainer has bolted it on.

Config as code, honestly assessed

Komodo’s headline feature is Resource Sync. You put TOML in a Git repo, point Komodo at it, and it reconciles:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
[[stack]]
name = "media"
[stack.config]
server = "cupboard-01"
git_provider = "git.mylab.local"
repo = "smarc/homelab"
branch = "main"
run_directory = "stacks/media"
file_paths = ["compose.yaml"]
poll_for_updates = true
environment = """
PUID=1000
PGID=1000
TZ=Europe/Copenhagen
"""

[[alerter]]
name = "ntfy"
[alerter.config]
endpoint_type = "Custom"
[alerter.config.endpoint.params]
url = "https://ntfy.mylab.local/homelab"

Commit that, hit sync, and the stack exists on the right host with the right environment. Delete it from the repo and Komodo offers to delete the stack. The diff view before execution is genuinely good — it shows you what will change before it changes, which is the part every GitOps tool gets wrong at least once.

This is a lighter version of the loop I described in GitOps with Flux, with the important difference that Komodo’s sync is push-button by default rather than continuously reconciling. Drift is possible; Komodo shows it to you and waits. For a homelab I have come to prefer that. Continuous reconciliation means a 3am git push from a phone can restart a service, and I have been that idiot.

Portainer has GitOps too — “Stacks from Git”, with optional polling and a webhook. It works. What it lacks is the layer above: the repo defines the compose file, and Portainer holds everything around the compose file — which host it runs on, its environment variables, its access policy — in its own database. Rebuilding a Portainer server from scratch means restoring that database or rebuilding the configuration by hand. Rebuilding a Komodo core means pointing it at the repo again.

I tested that claim, because it is the kind of claim that sounds better than it performs. Wiping Komodo’s core database and re-syncing from the repo restored nineteen stacks across four servers in about six minutes, and the only manual step was re-entering the registry credentials, which correctly are not in Git. That is the strongest single argument in this comparison.

Builds, and where Komodo overreaches

Advertisement

Komodo also builds images. Point a Build resource at a repo with a Dockerfile, give it a version, and it builds on any Periphery host and pushes to a registry. It handles versioning with an auto-incrementing scheme and can trigger a Stack redeploy on completion.

I used this for a fortnight and stopped. The builds worked, but I already have a CI runner that does this properly, with layer caching, multi-arch output and a log I can link to. Komodo’s builder is fine for a small Dockerfile and thin for anything else, and having two systems that can both build the same image is how you get an image nobody can account for. Use one or the other.

Portainer, to its credit, has never pretended to be a build system.

The socket question

Both tools need the Docker API on every managed host, and both are therefore holding root on every machine they manage. Mounting /var/run/docker.sock into a container gives that container the ability to start a new container with the host filesystem mounted at /, and no amount of :ro on the mount changes that.

Portainer’s Agent listens on a TCP port with mutual TLS and a shared secret. Komodo’s Periphery listens on a port with an API key and an allowlist of caller addresses, and can optionally use TLS. Both are reasonable. Both are also a network service running as root on every box you own, which is a meaningful expansion of your attack surface in exchange for convenience. Neither should ever be exposed to the internet, and both should sit behind whatever internal access control you already run — for me, that is a reverse proxy with forward auth and no route in from outside at all.

Komodo is somewhat better here on defaults: Periphery ships with the API key requirement on and a passkeys-or-nothing local login. Portainer’s default admin setup is a password form on port 9443 and the onus is on you.

Resource use

On the mini PC, measured with docker stats after a week of uptime:

1
2
3
4
5
6
CONTAINER          MEM USAGE     CPU %
portainer          148MiB        0.4%
portainer-agent    28MiB         0.1%
komodo-core        61MiB         0.2%
komodo-periphery   19MiB         0.1%
komodo-mongo       340MiB        1.1%

Komodo’s core is a Rust binary and it shows. Its database does not — the default deployment uses MongoDB, which eats more RAM than the rest of the stack combined and feels absurd for storing a few hundred resource definitions. There is a FerretDB variant in the documentation that speaks the Mongo wire protocol over Postgres or SQLite, and on the Pi that is what I run. It works, though it is the part of the deployment most likely to surprise you.

Portainer is a single container with an embedded database and no such decision to make. For a two-host setup, that simplicity is worth real money.

Day-to-day, which one do you actually open

Advertisement

I kept a rough tally for a month, because the feature comparison above is the kind of thing that decides an argument and not a Tuesday.

Portainer got opened for: reading logs when something broke (about a dozen times), exec-ing into a container to look at a config file (four), checking why a container was restarting (three), and one memorable session where the network diagram showed me two containers on different networks that I had assumed were talking to each other. Its container detail view is genuinely the best in this comparison and I have never wanted for information in it.

Komodo got opened for: deploying a new stack from the repo (six), syncing a config change (a dozen or so), and looking at the resource list to remember where something lives (often). Its log view is adequate and I used Portainer’s instead, twice, while both were installed.

That split is the honest summary. Portainer is a better tool for inspecting a running system. Komodo is a better tool for defining one. If your homelab is stable and you touch it when it breaks, Portainer’s strengths are the ones you will use. If you are still building it out and stacks come and go, Komodo’s are.

Running both is possible — they will happily coexist on the same socket — and I would not. Two tools that can each stop a container while the other’s UI keeps showing it running is a specific kind of confusion, and I gave myself an unnecessary twenty minutes of it during the comparison.

Multi-user, and why it matters even alone

Portainer’s free edition gives you users and teams, and gates the useful part — granular role assignment per environment — behind the Business licence. There is a free Business tier for three nodes, which covers a lot of homelabs, and which I have avoided purely because I dislike features that expire.

Komodo has users, permission levels per resource, and OIDC. Wiring it to the SSO I already run took ten minutes and now the container manager is behind the same login as everything else, with the same second factor. Portainer CE has no OIDC.

This sounds like a corporate concern that does not apply to a household of one. It applies more than you think, for a boring reason: a tool with root on four machines should authenticate against the thing you have already hardened, rather than holding its own password that you set eighteen months ago and have not rotated since. Every service with its own credential store is another credential you are personally responsible for. Komodo lets me delete one of those. Portainer CE does not, and that weighed more heavily in my decision than any feature comparison.

Troubleshooting

Portainer agent shows “environment unreachable” after a reboot. The agent’s TLS certificate is generated on first start and stored in its volume; if the volume was recreated, the server no longer trusts it. Remove the environment in the UI and re-add it. Ten minutes of my life I will not get back.

Komodo Periphery refuses connections. Check the PERIPHERY_ALLOWED_IPS setting. It defaults to permissive in the sample compose and to nothing useful once you start tightening it, and the error surfaced in Core is a generic timeout rather than “I rejected you”. docker logs komodo-periphery on the target host tells you plainly.

Komodo sync reports “no changes” when the repo clearly changed. Core clones the repo itself and caches it. If you are using a self-hosted Git server with a self-signed certificate, the clone fails silently in some versions and you get a stale tree. Put your internal CA into Core’s trust store; do not disable verification.

Portainer stack deployed from Git will not redeploy. Portainer’s polling only redeploys if the commit hash changed on the tracked branch. Force-pushing the same content or changing an env var in the UI does nothing. The “Pull and redeploy” button is the escape hatch and it is easy to miss.

Either tool shows containers it did not create. Both enumerate everything on the socket, including containers started by hand or by another tool. Portainer will let you delete one of Komodo’s stacks without either tool noticing anything is wrong. Pick one manager per host and mean it.

The verdict

Portainer if you have one or two hosts, want a good UI over the Docker API, and treat compose files as something you edit in a text box. It is more mature, better documented, has a decade of forum answers behind it, and the free edition is generous. It is also the right recommendation for anyone else in the house who needs to restart something while you are out.

Komodo if your homelab already lives in a Git repo and you resent the manager holding state your repo should own. The rebuild test sold me: a control plane whose entire configuration reconstructs from a git clone is a different class of tool, and it turns the manager into something you can lose without consequence. That is the property I want from anything with this much privilege.

The honest caveat is age. Komodo is a young project that changed its name last month, with one primary maintainer and documentation that assumes you already know what a Periphery is. I have hit two bugs in two months, both fixed quickly, both in areas Portainer settled years ago. If you want to install a thing and never think about it again, that is a real cost.

Neither is compulsory. Four hosts, four SSH sessions and a compose repo works fine, and for two years that was my setup. What tipped me was wanting one page that shows what is running everywhere without me remembering which box has the disks in it. Both tools give you that page. Komodo gives you it back after you wipe the machine.

Advertisement
Advertisement
Smarc
Written by Smarc

Founder and editor of vo.rs. A lifelong tinkerer who self-hosts far more than is sensible, hardens Linux boxes for fun, and prods the latest AI tools to see what they can really do. The how-to guides here are the notes Smarc wishes had existed the first time round.