feat: add backup-status service (port 9999, push API for borgmatic)

This commit is contained in:
feldjaeger 2026-04-02 11:49:03 +02:00
parent 519eb66bef
commit 6ad9b1a93f
3 changed files with 79 additions and 0 deletions

5
backup-status/Dockerfile Normal file
View file

@ -0,0 +1,5 @@
FROM python:3.12-slim
RUN pip install flask
WORKDIR /app
COPY app.py .
CMD ["python", "app.py"]

64
backup-status/app.py Normal file
View file

@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""
Backup Status API
Hosts push after borgmatic backup, n8n polls this endpoint.
GET / JSON summary of all hosts
POST /push?host=<name>&status=ok|error&msg=<text> update host status
"""
from flask import Flask, request, jsonify
import json, os, time
app = Flask(__name__)
DATA_FILE = "/data/backup_status.json"
def load():
if os.path.exists(DATA_FILE):
with open(DATA_FILE) as f:
return json.load(f)
return {}
def save(data):
os.makedirs(os.path.dirname(DATA_FILE), exist_ok=True)
with open(DATA_FILE, "w") as f:
json.dump(data, f, indent=2)
@app.route("/")
def status():
data = load()
now = time.time()
result = {}
for host, info in data.items():
age_h = (now - info.get("ts", 0)) / 3600
if age_h > 26:
s = "KEIN BACKUP"
elif info.get("status") == "error":
s = "FEHLER"
else:
s = "OK"
result[host] = {
"status": s,
"last_backup": info.get("time", "unbekannt"),
"msg": info.get("msg", ""),
"age_h": round(age_h, 1)
}
return jsonify(result)
@app.route("/push", methods=["POST", "GET"])
def push():
host = request.args.get("host") or request.form.get("host")
status = request.args.get("status", "ok")
msg = request.args.get("msg", "")
if not host:
return jsonify({"error": "host parameter required"}), 400
data = load()
data[host] = {
"status": status,
"msg": msg,
"ts": time.time(),
"time": time.strftime("%Y-%m-%d %H:%M")
}
save(data)
return jsonify({"ok": True, "host": host, "status": status})
if __name__ == "__main__":
app.run(host="0.0.0.0", port=9999)

View file

@ -152,3 +152,13 @@ services:
- '--collector.filesystem.ignored-mount-points=^/(sys|proc|dev|host|etc)($|/)'
restart: unless-stopped
backup-status:
build: ./backup-status
container_name: backup-status
restart: always
ports:
- "9999:9999"
volumes:
- /app-config/backup_status_data:/data
networks:
- monitoring_network