diff --git a/plugins/docker/routes.py b/plugins/docker/routes.py index 98d10a8..3dc9f55 100644 --- a/plugins/docker/routes.py +++ b/plugins/docker/routes.py @@ -175,6 +175,23 @@ async def rows(): else: g["stopped"] += 1 + # Sub-group each host's containers by compose project (or swarm service), + # preserving the running-first ordering. Containers with neither label fall + # into an unlabelled bucket rendered flat, so plain hosts look unchanged. + for g in groups.values(): + subs: dict[str, dict] = {} + order: list[str] = [] + for item in g["containers"]: + c = item["container"] + label = c.compose_project or c.service_name or None + key = label or "" + if key not in subs: + subs[key] = {"label": label, "containers": []} + order.append(key) + subs[key]["containers"].append(item) + g["subgroups"] = [subs[k] for k in order] + g["grouped"] = any(s["label"] for s in g["subgroups"]) + host_groups = sorted(groups.values(), key=lambda g: g["host_name"].lower()) running = sum(g["running"] for g in host_groups) total = len(containers) diff --git a/plugins/docker/templates/docker/rows.html b/plugins/docker/templates/docker/rows.html index 66088c0..9d3b058 100644 --- a/plugins/docker/templates/docker/rows.html +++ b/plugins/docker/templates/docker/rows.html @@ -47,7 +47,11 @@
- {% for item in g.containers %} + {% for sub in g.subgroups %} + {% if g.grouped and sub.label %} +