master
May B. 2020-03-14 15:48:59 +01:00
parent a7ab5e426d
commit a0323e7122
3 changed files with 28 additions and 4 deletions

View File

@ -7,11 +7,13 @@ Simple status page using Docker sdk and healthcheck.
Environment variable | Description | Default
--- | --- | ---
DOCKER_* | Docker client options | [Doc](https://docker-py.readthedocs.io/en/stable/client.html#docker.client.from_env)
DST_PATH | Json file output | `/data/status.json`
DST_PATH | Files output | `/data`
DST_INTERVAL | Update interval is seconds | `30`
DST_FILTER_LABEL | Filter visible containers with label | `False`
DST_NAME_LABEL | Override container name with label | `False`
DST_URL_LABEL | Provide url with label | `False`
DST_TITLE | Page title | `Docker Status`
DST_CAPTION | Page caption
## TODO

28
dst.py
View File

@ -3,7 +3,9 @@ import json
import time
import os
path = os.environ.get("DST_PATH", "/data/status.json")
title = os.environ.get("DST_TITLE", "Docker Status")
caption = os.environ.get("DST_CAPTION", 'Status page using <a href="https://git.wadza.fr/me/dst">dst</a>')
path = os.environ.get("DST_PATH", "/data")
interval = int(os.environ.get("DST_INTERVAL", "30"))
filter_label = os.environ.get("DST_FILTER_LABEL", False)
filters = {}
@ -12,6 +14,11 @@ if filter_label:
name_label = os.environ.get("DST_NAME_LABEL", False)
url_label = os.environ.get("DST_URL_LABEL", False)
css = 'body{padding:0;max-width:50em;margin:auto;background:#f2f2f2;box-shadow:0 0.5rem 1rem rgba(0, 0, 0, 0.2);font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"}.content{background:#fcfcfc;padding:1rem;text-align:center}footer,header{text-align:center}section{margin:1rem;border:1px #eee solid;border-radius:4px;background:white;display:flex;padding:0.5rem 1rem}section *{margin:0}h2{flex-grow:1;text-align:left}h2 a{text-decoration:none}section p{align-self:center}.health,.status{text-transform:capitalize;min-width:5em}.health::after,.status::after{font-size:1.5rem;vertical-align:middle}.health-none,.status-created,.status-paused{color:cornflowerblue}.health-healthy,.status-running{color:#7ED321}.health-healthy::after,.status-running::after{content:"\\2714"}.health-starting,.status-removing,.status-restarting{color:#ffbf00}.health-starting::after,.status-restarting::after{content:"\\21bb"}.status-removing::after{content:"\\21af"}.health-unhealthy,.status-dead,.status-exited{color:orangered}.health-unhealthy::after,.status-dead::after,.status-exited::after{content:"\\2718"}a{color:black}'
header = '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>{0}</title><link rel="stylesheet" href="style.css"></head><body><div class="content"><header><h1>{0}</h1><h5>{1}</h5></header>'
section = '<section><h2><a href="{1}">{0}</a></h2><p class="status status-{2}" title="{3}">{2}</p><p class="health health-{4}" title="{5}">{4}</p></section>'
footer = '<footer><a href="https://git.wadza.fr/me/dst">Docker Status</a></footer></div></body></html>'
client = docker.from_env()
def formatContainer(container):
@ -19,7 +26,7 @@ def formatContainer(container):
health = state.get("Health", {})
return {
"name": container.labels.get(name_label, container.name),
"url": container.labels.get(url_label),
"url": container.labels.get(url_label, ""),
"status": container.status,
"start": state.get("StartedAt"),
"stop": state.get("FinishedAt"),
@ -35,8 +42,23 @@ def loop():
report = list(
map(formatContainer,
client.containers.list(all=True, filters=filters)))
with open(path, 'w') as outfile:
with open(path + "/style.css", 'w') as outfile:
outfile.write(css)
with open(path + "/status.json", 'w') as outfile:
json.dump(report, outfile)
with open(path + "/index.html", 'w') as outfile:
outfile.write(header.format(title, caption))
for l in report:
outfile.write(
section.format(
l.get("name"), l.get("url"), l.get("status"),
l.get("stop") if l.get("status") in ["exited", "dead"] else l.get("start"),
l.get("health").get("status"), l.get("health").get("fails")))
outfile.write(footer)
except docker.errors.NotFound:
print('Container bad move. Restarting.')
time.sleep(interval)