# Unraid Docker Manager ## What This Is A Telegram bot that lets you manage Docker containers on your Unraid server via inline keyboard buttons and text commands. Built on a modular n8n sub-workflow architecture with 7 domain-specific sub-workflows. Control containers from your phone — check status, view logs, start/stop/restart/update containers, batch operations, and update all :latest containers at once. ## Core Value When you get a container update notification or notice a service is down, you can immediately investigate and act from your phone. ## Requirements ### Validated **v1.0:** - ✓ Send a message to the bot and receive a response — v1.0 - ✓ Check container status ("status") — v1.0 - ✓ Start a container by name — v1.0 - ✓ Stop a container by name — v1.0 - ✓ Restart a container by name — v1.0 - ✓ Update a container (pull new image, recreate) — v1.0 - ✓ View container logs with configurable line count — v1.0 - ✓ Bot only responds to your Telegram user ID — v1.0 **v1.1:** - ✓ n8n API access for Claude Code (programmatic workflow read/update/test/logs) — v1.1 - ✓ Docker socket security (remove direct socket from internet-exposed n8n) — v1.1 - ✓ Telegram inline keyboard buttons (container list with pagination and action buttons) — v1.1 - ✓ Batch container operations (update/start/stop/restart multiple at once) — v1.1 - ✓ Confirmation dialogs for dangerous actions (stop, update) — v1.1 - ✓ Progress feedback during operations (message edits) — v1.1 **v1.2:** - ✓ Workflow modularization into 7 domain sub-workflows — v1.2 - ✓ Sub-workflows callable from main without code duplication — v1.2 - ✓ Update all :latest containers via text command ("update all") — v1.2 - ✓ Update all :latest containers via inline keyboard button — v1.2 - ✓ Bitmap-encoded batch selection (supports 50+ containers, eliminates 64-byte limit) — v1.2 - ✓ Batch selection supports containers with long names — v1.2 - ✓ Unraid update badge documented as known limitation — v1.2 - ✓ Environment variable documentation (TELEGRAM_USERID, BOT_TOKEN) — v1.2 - ✓ README documents proxy architecture and all v1.2 features — v1.2 - ✓ Duplicate --max-time flags fixed — v1.2 - ✓ Update flow consolidated (no duplicate logic) — v1.2 - ✓ Correlation ID tracking across sub-workflow boundaries — v1.2 ### Active **v1.3: Unraid Update Status Sync** - [ ] After bot updates a container, Unraid recognizes it as current (no stale badges) - [ ] No false-positive Unraid Telegram notifications for containers already updated via bot - [ ] No manual Unraid login required to clear update status after bot updates ### Out of Scope - Taking over Unraid notifications — keep existing notification system, this bot is for control - Deploying new containers — manage existing only, not create new ones - Natural language understanding — simple keyword matching sufficient, Claude API adds complexity - Proactive monitoring/notifications — bot is reactive (you ask, it answers) - Offline mode — real-time Docker API access is core to functionality - Ring buffer / persistent debug logging — n8n static data is execution-scoped, not workflow-scoped ## Current State **Shipped:** v1.2 (2026-02-08) **Tech stack:** n8n workflow + Telegram Bot API + Docker socket proxy **Architecture:** 1 main workflow (166 nodes) + 7 sub-workflows (121 nodes) = 287 total nodes **Files:** 8 workflow JSON files (10,987 LOC), README.md (264 lines), ARCHITECTURE.md (725 lines) **Sub-workflows:** Update, Actions, Logs, Batch UI, Status, Confirmation, Matching ## Context **Environment:** - Unraid server with Intel N100 CPU, 32GB RAM - n8n container with Docker socket proxy access (no direct socket mount) - Multiple Docker containers (Plex, Sonarr, lldap, etc.) - docker-socket-proxy on dockernet network **Constraints:** - Platform: Unraid (Docker-based) - Orchestration: n8n (already running) - Matching: Keyword/substring with exact-match priority - Auth: Single user via Telegram ID - Logs: Configurable line count, default 50, max 1000 - Callback data: Bitmap encoding overcomes 64-byte Telegram limit - n8n static data: Execution-scoped only (no persistent cross-execution state) **Known tech debt:** - 3 orphan nodes in main workflow (legacy dead code, unreachable) - Legacy batch parsers retained alongside bitmap parsers (graceful migration) - Phase 10.2 logging features descoped (n8n platform limitation) ## Key Decisions | Decision | Rationale | Outcome | |----------|-----------|---------| | Use keyword matching over NLU | Simple substring matching works well, Claude API adds complexity | ✓ Good | | Use n8n for orchestration | Already running, handles Telegram webhooks | ✓ Good | | Manage existing containers only | Keeps scope focused, deployment rarely needed from mobile | ✓ Good | | Single user auth via Telegram ID | Simple security, only one person needs access | ✓ Good | | Static curl binary mount | Hardened n8n image lacks package manager | ✓ Good | | Exact match priority | Prevents substring collisions (plex vs jellyplex) | ✓ Good | | Default to :latest tag | Prevents Docker API from pulling all tags | ✓ Good | | HTML escape logs | Log content may contain text | ✓ Good | | docker-socket-proxy for security | Filters dangerous APIs (exec, build, commit) at network level | ✓ Good | | Container create API allowed | Update command needs container recreation | ✓ Good | | Colon callback format | Compact format fits 64-byte limit | ✓ Good | | editMessageText transitions | Clean UX with no message clutter | ✓ Good | | 30-second confirmation timeout | Prevents stale confirmations | ✓ Good | | Batch stop requires confirmation | Fuzzy matching risk for destructive operations | ✓ Good | | Two-phase batch execution | Callbacks have names but no IDs - need lookup | ✓ Good | | Update all filters to :latest | Performance optimization - full check would be slow | ✓ Good | | 7 domain sub-workflows | Clean boundaries: Update, Actions, Logs, Batch UI, Status, Confirmation, Matching | ✓ Good | | Bitmap-encoded batch callbacks | Base36 BigInt supports 50+ containers in 64-byte limit | ✓ Good | | Action-based sub-workflow routing | Sub-workflow returns action field, main routes to Telegram handlers | ✓ Good | | Correlation IDs without persistent logging | Timestamp+random string traces requests; ring buffer non-viable on n8n | ✓ Good | | Infrastructure container exclusion | Exclude n8n and socket-proxy from "update all" to prevent self-destruction | ✓ Good | | Document Unraid badge as limitation | Unraid API integration adds complexity for cosmetic issue | ⚠️ Revisit | ## Current Milestone: v1.3 Unraid Update Status Sync **Goal:** After the bot updates a container, Unraid recognizes it's current — no stale badges, no false-positive notifications. **Target features:** - Sync update status back to Unraid after bot-initiated container updates - Eliminate false-positive Unraid Telegram notifications for already-updated containers - (Nice-to-have) Use Unraid's update detection data in the bot's update flow --- *Last updated: 2026-02-08 after v1.3 milestone started*