Files
FabledSteward/plugins/docker/templates/docker/widget.html
T
bvandeusenandClaude Opus 5.5 5c7a4cf9a0
CI / lint (push) Successful in 3s
CI / integration (push) Successful in 1m23s
CI / unit (push) Successful in 1m33s
CI / publish (push) Successful in 1m7s
feat(widgets): a troubled container on the Docker widget says since when (#5810)
Its problems and since come from the same container_problems and
problem_since the Docker page uses, read from the day's deaths and
health changes; troubled containers sort worst problem first, then name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:09:25 -04:00

82 lines
4.3 KiB
HTML

{# docker/widget.html — the dashboard Docker widget (#5252), in the widget-shape
order: a verdict line; the services and containers in trouble; what failed
in the last 24h, by name; then everything healthy, one line each, packed
into as many columns as the widget is wide. Resource use is the Busiest
Containers widget's, so it isn't repeated here. #}
{% from "_macros.html" import status_dot %}
{% if total_count == 0 %}
<div class="w-verdict" style="color:var(--text-muted);">No containers reported yet.</div>
{% else %}
{% set wrong = bad_services|length + bad_containers|length %}
<div class="w-verdict {{ 'tone-crit' if wrong else ('tone-warn' if failures else 'tone-ok') }}">
{%- if services_total %}{{ services_healthy }}/{{ services_total }} services healthy · {% endif -%}
{{ running_count }} other container{{ 's' if running_count != 1 }} running ·
{% if failures %}<a href="/plugins/docker/#failures" style="color:inherit;">{{ failures|length }} failed in 24h</a>{% else %}nothing failed in 24h{% endif -%}
</div>
{% if wrong %}
<div class="w-section">Needs a look</div>
{% for s in bad_services %}
<div class="w-item">
{{ status_dot('degraded' if s.state == 'degraded' else 'down') }}
<span class="w-label" title="{{ s.name }}">{{ s.name }}
<span class="w-sub {{ 'tone-crit' if s.state != 'degraded' else 'tone-warn' }}">
{%- if s.crash_looping %}crash-looping: {{ s.failures_1h }} failed in the last hour{% else %}{{ s.running }} of {{ s.desired }} running{% endif %}
{%- if s.trouble_since %}, since {{ s.trouble_since|ago }}{% endif %}
{%- if s.last_error and (s.last_error.error or s.last_error.message) %} · {{ s.last_error.error or s.last_error.message }}{% endif -%}
</span>
</span>
<span class="w-meta" title="replicas running / wanted">{{ s.running }}/{{ s.desired }}</span>
</div>
{% endfor %}
{% for c in bad_containers %}
<div class="w-item">
{{ status_dot('warn' if c.status == 'restarting' else 'down') }}
<span class="w-label" title="{{ c.name }}">
{%- if session.user_id %}<a href="/plugins/docker/container/{{ c.host_id }}/{{ c.name }}">{{ c.name }}</a>{% else %}{{ c.name }}{% endif %}
<span class="w-sub tone-crit">
{%- if c.health == 'unhealthy' %}unhealthy{% elif c.status == 'restarting' %}restarting{% else %}exited {{ c.exit_code }}{% if c.oom_killed %}, out of memory{% endif %}{% endif %}
{%- set since = (bad_since or {}).get((c.host_id, c.name)) %}{% if since %} since {{ since|ago }}{% endif %} · {{ host_name.get(c.host_id, c.host_id) }}
</span>
</span>
</div>
{% endfor %}
{% endif %}
{% if failures %}
<div class="w-section">Failed in the last 24h</div>
{% for f in failures[:5] %}
<div class="w-item">
{{ status_dot('failed') }}
<span class="w-label" title="{{ f.name }}">{{ f.name }}
<span class="w-sub">{% if f.count > 1 %}{{ f.count }} times, last {% endif %}{{ f.at|ago }}{% if f.detail %} · {{ f.detail }}{% endif %} · {{ f.host }}</span>
</span>
</div>
{% endfor %}
{% if failures|length > 5 %}<div class="w-more">+{{ failures|length - 5 }} more · <a href="/plugins/docker/#failures">the full list</a></div>{% endif %}
{% endif %}
{% if healthy %}
<div class="w-section">Healthy</div>
<div class="w-grid">
{% for h in healthy %}
<div class="w-item">
{% if h.kind == 'service' %}{% set s = h.s %}
{{ status_dot('up') }}
<span class="w-label" title="{{ s.name }} — on {{ s.replicas|map(attribute='host')|unique|join(', ') }}">{{ s.name }}
<span style="color:var(--text-dim);"> · {{ s.replicas|map(attribute='host')|unique|join(', ') }}</span></span>
<span class="w-meta" title="replicas running / wanted">{{ s.running }}/{{ s.desired }}</span>
{% else %}{% set c = h.c %}
{{ status_dot('up' if h.kind == 'container' else 'unknown') }}
<span class="w-label" title="{{ c.name }}">
{%- if session.user_id %}<a href="/plugins/docker/container/{{ c.host_id }}/{{ c.name }}">{{ c.name }}</a>{% else %}{{ c.name }}{% endif %}
<span style="color:var(--text-dim);"> · {{ host_name.get(c.host_id, c.host_id) }}</span></span>
{% if h.kind == 'stopped' %}<span class="w-meta">stopped</span>{% endif %}
{% endif %}
</div>
{% endfor %}
</div>
{% if healthy_more %}<div class="w-more">+{{ healthy_more }} more healthy · <a href="/plugins/docker/">all of Docker</a></div>{% endif %}
{% endif %}
{% endif %}