Telegram bot for monitoring Unraid servers with AI diagnostics and container control
6.9K
A Telegram bot for monitoring Docker containers and Unraid servers. Get real-time alerts, check container status, view logs, and control containers - all from Telegram.
scratch-it.co.uk/unraidmonitorbot has the illustrated tour. This README is the reference.
/ups for battery and runtime/manage hub for status, resources, server, disks, ignores, mutes, and a Features panel to toggle optional monitors/help with navigable category buttons instead of a text wall![]() | ![]() |
Setup wizard. Scans your containers on first run and sorts them into priority, protected, watched and killable. Re-run any time with /setup. | Log error alert. Errors in a watched container, with the latest line and one tap to ignore, mute, read the logs or diagnose. |
![]() | ![]() |
AI diagnosis. /diagnose reads the logs and tells you what happened and why, instead of handing you a wall of text. | Resource alert. CPU and memory against your thresholds, and you can change the threshold from the alert itself. |
![]() | ![]() |
| Image updates. An opt-in daily digest of containers running behind their registry, each with a Pull button. | Natural language. Ask in plain English. It reads real server state, and it will humour you. |
![]() | ![]() |
The /manage hub. Server vitals at the top, then every panel one tap away, feature toggles included. | Commands, if you want them. The menu is built from what your install actually has enabled, so it never offers something the bot cannot do. |
/model used to freeze the bot on whatever was newest that day. sonnet and opus now always mean the latest, and existing choices upgrade themselves. A full model ID you pick on purpose stays pinneddocker stats on Unraid 7 instead of counting the disk cache/ups during a network blip no longer hides a real outage/mute, /ignore and /diagnose read the container name off the alert you replied to. Replying to a restart-loop alert used to mute a container called "4" (the crash count) and tell you it had worked. Reply-to-alert /diagnose had never worked on anything but resource alerts/restart has always wanted a ✅. Alerts stay in your chat for days, so a stale one was a mis-tap away from bouncing a container/model choice survives a crash mid-save/server, the Memory Critical alert body and the figures handed to the AI were all wrong together. Alert thresholds read the percentage, so no false alerts were firing/server detailed now shows the total and the reclaimable disk cache - "55% used" next to "0.5 GB free" was baffling without them/ups command - Model, status, battery percentage, runtime left, load and input voltage. /ups detailed dumps every variable/manage -> ⚙️ Featuresupsd knows nothing, and reporting that as an OK would be worse than uselessSetup gotcha:
upsdbinds to127.0.0.1only by default. If the bot runs in a container you needLISTEN 0.0.0.0 3493inupsd.confbefore it can connect. See Configure NUT.
/manage → ⚙️ Features/ in Telegram to see every command, built from the features your install actually has enabled/manage panels have Back and Refresh - Status, Resources, Server and Disks are no longer dead ends/pull keeps your GPU - nvidia device access, custom runtimes and supplementary groups now survive a container updateNote on UPS support: UPS monitoring reads from a NUT server, not from Unraid's API. Unraid exposes
upsDevices, but that data comes fromapcupsdover a local USB link, which is no use to a bot in a container and no use at all without the cable. NUT works over TCP, so it covers both cases. See the changelog.
See the changelog for full details.
The easiest way to install on Unraid.
Install from Community Apps
Configure the template
TELEGRAM_BOT_TOKEN - Your bot token (how to get one)TELEGRAM_ALLOWED_USERS - Your Telegram user ID (how to find it)ANTHROPIC_API_KEY (optional) - Enables AI features via ClaudeOPENAI_API_KEY (optional) - Enables AI features via OpenAIOLLAMA_HOST (optional) - Enables AI features via local Ollama (e.g., http://192.168.1.100:11434)DEFAULT_MODEL (optional) - Override the default AI model (e.g., qwen2.5:7b, gpt-4o)UNRAID_API_KEY (optional) - Enables server monitoringStart the container
Message your bot on Telegram - send /start to begin the setup wizard
Re-configure anytime (optional)
/setup to re-run the wizard (merges non-destructively with existing config)/mnt/user/appdata/unraid-monitor/config/config.yaml directly and restartIf not using Community Apps, you can set it up manually.
mkdir -p /mnt/user/appdata/unraid-monitor/{config,data}
Create /mnt/user/appdata/unraid-monitor/config/.env:
# Required
TELEGRAM_BOT_TOKEN=your_bot_token_here
TELEGRAM_ALLOWED_USERS=123456789
# Optional - AI features (configure at least one for /diagnose, NL chat, smart ignore)
ANTHROPIC_API_KEY=your_anthropic_api_key_here
OPENAI_API_KEY=your_openai_api_key_here
OLLAMA_HOST=http://localhost:11434
# Optional - override the default AI model (e.g. qwen2.5:7b, gpt-4o)
DEFAULT_MODEL=
# Optional - enables Unraid server monitoring
UNRAID_API_KEY=your_unraid_api_key_here
# Optional - only if your NUT server requires a login for reads
NUT_USERNAME=
NUT_PASSWORD=
Go to Docker → Add Container and configure:
| Field | Value |
|---|---|
| Name | unraid-monitor-bot |
| Repository | dervish/unraidmonitorbot:latest |
| Network Type | bridge or your preferred network |
Add these paths:
| Container Path | Host Path | Access |
|---|---|---|
/app/config | /mnt/user/appdata/unraid-monitor/config | Read/Write |
/app/data | /mnt/user/appdata/unraid-monitor/data | Read/Write |
/var/run/docker.sock | /var/run/docker.sock | Read Only |
Add these variables:
| Name | Value |
|---|---|
TELEGRAM_BOT_TOKEN | Your bot token |
TELEGRAM_ALLOWED_USERS | Your user ID |
ANTHROPIC_API_KEY | (optional) Claude AI features |
OPENAI_API_KEY | (optional) OpenAI AI features |
OLLAMA_HOST | (optional) Ollama URL, e.g., http://192.168.1.100:11434 |
DEFAULT_MODEL | (optional) Override default model, e.g., qwen2.5:7b |
UNRAID_API_KEY | (optional) Unraid server monitoring |
NUT_USERNAME | (optional) Only if your NUT server gates reads |
NUT_PASSWORD | (optional) Only if your NUT server gates reads |
PUID | (optional) Runtime user ID for file ownership (default: 99 — Unraid's nobody) |
PGID | (optional) Runtime group ID for file ownership (default: 100 — Unraid's users) |
TZ | Your timezone (e.g., Europe/London) |
Start the container and check the logs for any errors. Message your bot on Telegram with /start to begin the interactive setup wizard.
For non-Unraid Docker hosts (Ubuntu, Debian, Synology, etc.), use docker-compose:
Clone the repository and create your environment file:
git clone https://github.com/dervish666/UnraidMonitor.git
cd UnraidMonitor
cp config/.env.example config/.env
# Edit config/.env with your TELEGRAM_BOT_TOKEN, TELEGRAM_ALLOWED_USERS, etc.
Adjust docker-compose.yml volume paths to suit your system (the defaults point to Unraid appdata paths). For example:
volumes:
- /var/run/docker.sock:/var/run/docker.sock:ro
- ./config:/app/config
- ./data:/app/data
Check your Docker socket GID and set it if it differs from the default (281):
ls -ln /var/run/docker.sock # look at the 4th column
echo "DOCKER_GID=999" >> .env # adjust to match
Build and start:
docker-compose up -d
Message your bot on Telegram with /start to begin the setup wizard.
/newbot123456789:ABCdefGHIjklMNOpqrsTUVwxyz)123456789)This ID is used to restrict who can control your bot. You can add multiple IDs separated by commas: 123456789,987654321
At least one provider is needed for AI-powered features (/diagnose, smart ignore patterns, natural language chat). You can configure multiple providers and switch between them at runtime with /model.
Option A: Anthropic Claude (recommended)
ANTHROPIC_API_KEYOption B: OpenAI
OPENAI_API_KEYOption C: Ollama (free, runs locally)
ollama pull llama3.1:8bOLLAMA_HOST to your Ollama URL (e.g., http://192.168.1.100:11434)Models are auto-discovered from Ollama at startup. Note: some local models don't support tool calling, so NL chat actions (restart, etc.) may be limited.
Required for Unraid server monitoring (CPU, memory, temps, array status).
UNRAID_API_KEYNeeded only if you have a UPS. NUT talks over the network, so the UPS can hang off any machine on the LAN, not necessarily the one running the bot.
Install a NUT server. On Unraid, install the NUT plugin from Community
Apps and point it at your UPS. On another Linux box, install nut and
configure ups.conf for your model. Check it works locally first:
upsc myups
Let the bot reach it. This is the step people miss. upsd binds to
127.0.0.1 only by default, which a container cannot reach. Add this to
upsd.conf and restart upsd:
LISTEN 0.0.0.0 3493
Then confirm from another machine: upsc myups@<your-nut-host>.
Point the bot at it (optional). If your NUT server runs on the same box
as Unraid, the bot uses your unraid.host automatically. Otherwise set
nut.host in config.yaml.
Credentials (optional). Most upsd setups allow anonymous reads, since
upsd.users normally gates only SET and instant commands. If yours does
not, set NUT_USERNAME and NUT_PASSWORD in config/.env.
Configuration is stored in config/config.yaml. On first run, the interactive setup wizard creates this file. You can also run /setup anytime to reconfigure.
Location:
/mnt/user/appdata/unraid-monitor/config/config.yaml./config/config.yaml (relative to project root)# Containers to watch for log errors
log_watching:
containers:
- plex
- radarr
- sonarr
- lidarr
error_patterns:
- "error"
- "exception"
- "fatal"
- "failed"
- "critical"
ignore_patterns:
- "DeprecationWarning"
- "DEBUG"
cooldown_seconds: 900 # 15 min between alerts for same container
# Containers to hide from status reports
ignored_containers:
- some-temp-container
# Containers that cannot be controlled via Telegram (safety)
protected_containers:
- unraid-monitor-bot
- mariadb
- postgresql14
CPU is reported per-core on Linux, so multi-threaded apps can exceed 100% (e.g., 200% = 2 cores fully used). Set thresholds accordingly.
resource_monitoring:
enabled: true
poll_interval_seconds: 60
sustained_threshold_seconds: 120 # Alert after 2 min exceeded
defaults:
cpu_percent: 80
memory_percent: 85
# Per-container overrides (also adjustable via Telegram)
containers:
plex:
cpu_percent: 200 # Plex transcoding uses multiple cores
memory_percent: 90
handbrake:
cpu_percent: 400 # Expected to max out all cores
Per-container thresholds can also be adjusted directly from Telegram: when a resource alert fires, tap ⚙️ Raise Limit to pick a new threshold. The change applies immediately and persists across restarts.
Automatically kills low-priority containers when system memory is critical.
memory_management:
enabled: false # Disabled by default - enable with caution
warning_threshold: 90 # Notify at this %
critical_threshold: 95 # Start killing at this %
safe_threshold: 80 # Offer restart when below this
kill_delay_seconds: 60 # Warning before killing
stabilization_wait: 180 # Wait between kills
# Never kill these (highest priority)
priority_containers:
- plex
- mariadb
# Kill these in order during memory pressure (lowest priority first)
killable_containers:
- handbrake
- tdarr
# Offer a one-tap Restart button for these on pressure alerts — for
# services that hog memory but recover after a bounce (classic Plex).
# Pick them from Telegram via /manage → Features → Configure memory restarts.
restart_containers:
- plex
Memory warnings list the top 5 memory users and offer Restart/Stop buttons sorted largest-first, so the biggest win is always the top button.
unraid:
enabled: true
host: "192.168.1.100" # Your Unraid IP
port: 443
use_ssl: true
verify_ssl: false # Set true if using valid SSL cert
polling:
system: 30 # CPU/memory poll interval
array: 300 # Array status poll interval
notifications: 300 # Unraid notification feed poll interval
# ups: 60 # IGNORED - UPS polling lives under the `nut:` section below
thresholds:
cpu_temp: 80 # Alert above this temp (C)
cpu_usage: 95 # Alert above this %
memory_usage: 90 # Alert above this %
disk_temp: 50 # Alert above this temp (C)
array_usage: 85 # Alert above this %
# ups_battery: 30 # IGNORED - see `nut.thresholds.battery_charge` below
notifications:
enabled: false # Relay Unraid's own notifications into Telegram
min_importance: WARNING # WARNING (default), ALERT, or INFO for everything
Unraid's notification feed is what sits behind the bell icon in the web UI: SMART
warnings, disk errors, share-full warnings, parity results, plugin updates.
Relaying it means one place to look instead of two. It is off by default and
floored at WARNING, because the feed also carries routine INFO chatter
(backup finished, parity-check tuning pausing and resuming).
Toggle it from Telegram with /manage → ⚙️ Features. Enabling or disabling
restarts the bot; changing the importance floor applies immediately.
Reads your UPS from a NUT server over TCP 3493. Enabled by default, but it does nothing until a host resolves, and it never alerts about a NUT server it has never reached.
nut:
enabled: true # Master switch (also toggled from /manage -> Features)
host: "" # Blank falls back to unraid.host
port: 3493
ups_name: "" # Blank auto-picks when upsd serves exactly one UPS
poll_seconds: 60
thresholds:
battery_charge: 50 # Warn below this %, but only while on battery
load: 80 # Warn above this % of rated capacity
You get an alert when the mains drops (OB), when the battery gets low (LB),
when the battery needs replacing (RB, nagged once a day rather than every
poll), and on OVER, BYPASS, OFF, FSD and ALARM. Coming back to mains
sends a recovery message with how long you ran on battery.
A runtime calibration (CAL) is not alerted on. It puts the UPS on battery
deliberately, the same reason a parity sync is not reported as a failed disk.
If the bot cannot reach upsd, /ups and /health say unavailable and
name the error. They never render a UPS it cannot read as healthy. Losing a
server that was previously working sends an alert after three consecutive
failed polls, so one dropped poll does not wake you up.
Checks once per day (configurable) whether a newer image is available for watched containers. Sends a single batched digest message with Pull buttons. Disabled by de
Content type
Image
Digest
sha256:4f43dc357…
Size
65.6 MB
Last updated
about 11 hours ago
docker pull dervish/unraidmonitorbot