Files
unraid-docker-manager/.planning/PROJECT.md
T
2026-02-08 19:35:46 -05:00

7.1 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.

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