b063382085
Added asyncio monitoring task to main.py to watch Docker container state transitions and send Telegram notifications on failures.
58 lines
2.6 KiB
Python
58 lines
2.6 KiB
Python
from fastapi import FastAPI, Depends
|
|
from fastapi.staticfiles import StaticFiles
|
|
from routers import docker_router, gitea, files, terminal, system, auth
|
|
import auth as auth_module
|
|
|
|
import asyncio
|
|
import httpx
|
|
from config import TELEGRAM_BOT_TOKEN, TELEGRAM_CHAT_ID
|
|
|
|
app = FastAPI(title="NAS Dashboard")
|
|
|
|
async def monitor_containers():
|
|
import docker
|
|
from config import DOCKER_HOST
|
|
client = docker.DockerClient(base_url=DOCKER_HOST)
|
|
|
|
# Store initial states
|
|
previous_states = {}
|
|
|
|
while True:
|
|
try:
|
|
for c in client.containers.list(all=True):
|
|
current_status = c.status
|
|
if c.id in previous_states:
|
|
prev_status = previous_states[c.id]
|
|
# Alert if it transitioned from running to exited or unhealthy
|
|
if prev_status == "running" and current_status in ("exited", "dead"):
|
|
msg = f"⚠️ *Container Alert* ⚠️\nContainer `{c.name}` just stopped unexpectedly (Status: {current_status})."
|
|
# Use httpx directly as system.send_notification expects a FastAPI request object usually
|
|
if TELEGRAM_BOT_TOKEN and TELEGRAM_CHAT_ID:
|
|
async with httpx.AsyncClient() as hc:
|
|
await hc.post(
|
|
f"https://api.telegram.org/bot{TELEGRAM_BOT_TOKEN}/sendMessage",
|
|
data={"chat_id": TELEGRAM_CHAT_ID, "text": msg, "parse_mode": "Markdown"},
|
|
)
|
|
previous_states[c.id] = current_status
|
|
except Exception as e:
|
|
print(f"Error in container monitor: {e}")
|
|
|
|
await asyncio.sleep(60)
|
|
|
|
@app.on_event("startup")
|
|
async def startup_event():
|
|
asyncio.create_task(monitor_containers())
|
|
# Public auth endpoints
|
|
app.include_router(auth.router, prefix="/api/auth", tags=["auth"])
|
|
|
|
# Protected endpoints
|
|
app.include_router(docker_router.router, prefix="/api/docker", dependencies=[Depends(auth_module.get_current_user)])
|
|
app.include_router(gitea.router, prefix="/api/gitea", dependencies=[Depends(auth_module.get_current_user)])
|
|
app.include_router(files.router, prefix="/api/files", dependencies=[Depends(auth_module.get_current_user)])
|
|
app.include_router(system.router, prefix="/api/system", dependencies=[Depends(auth_module.get_current_user)])
|
|
|
|
# WebSocket endpoint (auth handled inside handler via Query param)
|
|
app.add_api_websocket_route("/ws/terminal", terminal.ws_endpoint)
|
|
|
|
app.mount("/", StaticFiles(directory="/app/static", html=True), name="static")
|