{# docker/rows.html — HTMX fragment for the Docker page (#5298–#5301): a verdict line; what needs attention (service.needs_attention, the ranking the MCP tools use); hosts whose Docker is not answering; what failed in 24h, each with its logs; then the swarm services and the standalone containers as two tables that share the filter bar's search, filters and sort (overview.py). #} {% from "_macros.html" import status_badge, status_dot, sort_th %} {% from "docker/_usage.html" import cpu, mem, cores %} {% macro th(key, label, cls=none, title=none) -%} {{ sort_th(label, sort_url(key), active=f.sort == key, desc=f.dir == 'desc', cls=cls, title=title) }} {%- endmacro %} {% macro up(row) -%} {%- if row.started_at %}{{ row.started_at|ago|striptags|replace(" ago", "") }} {%- else %}—{% endif -%} {%- endmacro %} {# ── Verdict ──────────────────────────────────────────────────────────────── #} {% set problems = attention|length + failing_services|length %}
{% if problems %}{{ problems }} need{{ "s" if problems == 1 }} attention {% else %}Nothing needs attention{% endif %} {%- if services_total %} · {{ services_healthy }}/{{ services_total }} services healthy{% endif %} {%- if containers_total %} · {{ running }} container{{ "s" if running != 1 }} running{% if stopped %}, {{ stopped }} stopped{% endif %}{% if services_total %} outside services{% endif %}{% endif %} {%- if docker_hosts %} · {{ docker_hosts }} Docker host{{ "s" if docker_hosts != 1 }}{% endif %} {%- if stale %} · {{ stale }} stale{% endif %}
{# ── Needs attention ──────────────────────────────────────────────────────── #} {% if attention or failing_services %}| Nodes | {{ th("cpu", "CPU", "num", "Across its running replicas; Docker counts CPU per core") }} {{ th("mem", "Memory", "num", "Across its running replicas") }} {{ th("up", "Up", "num", "Since its newest replica started") }}Failed 24h | ||||||
|---|---|---|---|---|---|---|---|
| {{ r.name }} | {{ status_dot('up' if r.state == 'healthy' else ('warn' if r.state == 'degraded' else 'down')) }} {{ r.running }}/{{ r.desired }} {%- if r.crash_looping %} {{ status_badge('crit', 'Crash-looping') }}{% elif r.unhealthy %} {{ status_badge('crit', 'Unhealthy') }}{% endif %} {%- if r.mode == 'global' %} global{% endif %} | {% if r.stack %}{{ r.stack }}{% else %}—{% endif %} | {{- r.nodes|join(", ") or ("" if r.ghost_nodes else "—") -}} {%- if r.ghost_nodes %}{{ ", " if r.nodes }}{{ r.ghost_nodes|join(", ") }} (no agent){% endif -%} | {% if r.cpu_cores is not none %}{{ cores(r.cpu_cores) }}{% else %}—{% endif %} | {% if r.mem_bytes is not none %}{{ r.mem_bytes|bytes }}{% else %}—{% endif %} | {{ up(r) }} | {%- if r.failures_24h %}{{ r.failures_24h }} {%- else %}—{% endif -%} |
| Host | {{ th("stack", "Stack", title="Its compose project") }}Image | {{ th("cpu", "CPU", "num", "Docker counts CPU per core: 1 core = one core fully busy") }} {{ th("mem", "Memory", "num", "Used, and the limit when one is set") }} {{ th("up", "Up", "num", "Since it started") }}||||||
|---|---|---|---|---|---|---|---|
|
{{ r.name }}
{%- if r.ports %} {% for p in r.ports %}{{ p.host_port }}:{{ p.container_port }}/{{ p.protocol }}{{ " " if not loop.last }}{% endfor %} {% endif %}
|
{{ status_dot('stale' if r.stale else ('up' if r.running else ('pending' if r.status == 'paused' else 'down'))) }} {%- if r.health == 'unhealthy' %} {{ status_badge('crit', 'Unhealthy') }} {%- elif r.health == 'starting' %} {{ status_badge('pending', 'Starting') }} {%- else %} {{ r.status }}{% endif %} {%- if not r.running and r.exit_code is not none and r.exit_code != 0 %} exit {{ r.exit_code }}{% if r.oom_killed %} (OOM){% endif %} {%- endif %} {%- if r.restart_count %} ⟳{{ r.restart_count }}{% endif %} {%- if r.stale %} {{ status_badge('stale', title="Last report " ~ (r.scraped_at.strftime('%Y-%m-%d %H:%M UTC') if r.scraped_at else 'never') ~ "; what is shown may no longer be true") }}{% endif %} | {{ r.host }} | {% if r.stack %}{{ r.stack }}{% else %}—{% endif %} | {{ r.image }} | {% if r.running %}{{ cpu(r.usage) }}{% else %}—{% endif %} | {% if r.running %}{{ mem(r.usage) }}{% else %}—{% endif %} | {{ up(r) }} |
Nothing matches these filters. Show everything
{% else %}No containers reported yet. Containers are collected by the Steward host agent — deploy the agent to a host running Docker (Hosts → the host → agent panel) and its containers will appear here.
{% endif %}