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>
82 lines
4.3 KiB
HTML
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 %}
|