8.3 KiB
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. Includes Unraid GraphQL API connectivity for native Unraid integration.
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
v1.3:
- ✓ n8n container can reach Unraid GraphQL API endpoint — v1.3
- ✓ Unraid API key with Docker update permission, stored securely — v1.3
- ✓ Container ID format verified and documented — v1.3
Active
Current Milestone: v1.4 Unraid API Native
Goal: Replace Docker socket proxy with Unraid's GraphQL API for all container operations, remove all proxy artifacts, and update documentation.
Target features:
- All container operations via Unraid GraphQL API (status, start, stop, restart, update)
- Remove container logs feature (not valuable enough to justify hybrid architecture)
- Remove docker-socket-proxy container entirely (no hybrid architecture)
- Remove all proxy-related artifacts from workflows, credentials, n8n container config
- Documentation fully updated for Unraid API-native architecture (README, ARCHITECTURE.md, CLAUDE.md)
- Cleanup instructions for removing the proxy container
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
- Container logs via Telegram bot — removed in v1.4 to eliminate hybrid architecture (Docker proxy + Unraid API); not valuable enough to justify complexity
- Real-time container stats — requires WebSocket infrastructure, defer to future
Current State
Shipped: v1.3 (2026-02-09) Building: v1.4 Unraid API Native Tech stack: n8n workflow + Telegram Bot API + Docker socket proxy + Unraid GraphQL API Architecture: 1 main workflow (169 nodes) + 7 sub-workflows (121 nodes) = 290 total nodes Files: 8 workflow JSON files (~11K LOC), README.md, ARCHITECTURE.md 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
- Unraid GraphQL API accessible via myunraid.net cloud relay
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)
- Unraid API: myunraid.net cloud relay required (direct LAN IP fails due to nginx redirect)
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 | ⚠️ Revisit (replacing with Unraid API in v1.4) |
| 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 |
| myunraid.net cloud relay for Unraid API | Direct LAN IP fails (nginx strips auth headers on redirect) | ✓ Good |
| Environment variables for Unraid API auth | More reliable than n8n Header Auth credential system for GraphQL | ✓ Good |
| Descope v1.3 to Phase 14 only | Phases 15-16 superseded by v1.4 Unraid API Native approach | ✓ Good |
| Remove container logs feature in v1.4 | Not valuable enough to justify hybrid architecture (Docker proxy for logs + Unraid API for everything else) | — Pending |
| Remove docker-socket-proxy entirely | Clean single-API architecture, no hybrid routing complexity | — Pending |
Last updated: 2026-02-09 after v1.4 milestone started