docs: complete v1.4 project research synthesis

This commit is contained in:
Lucas Berger
2026-02-09 08:08:25 -05:00
parent bb47664188
commit bab819f6c8
5 changed files with 2013 additions and 1453 deletions
+200 -200
View File
@@ -1,277 +1,277 @@
# Feature Research: Unraid Update Status Sync (v1.3)
# Feature Research: Unraid GraphQL API Migration
**Domain:** Docker container management integration with Unraid server
**Researched:** 2026-02-08
**Confidence:** MEDIUM
**Domain:** Unraid native container management via GraphQL API
**Researched:** 2026-02-09
**Confidence:** HIGH
## Context
This research focuses on v1.3 milestone: syncing update status back to Unraid after bot-initiated container updates. The bot already updates containers successfully, but Unraid's UI continues showing "update available" badges and sending false-positive notifications afterward.
**Existing system:** Bot uses Docker socket proxy → Docker REST API for all container operations (status, start, stop, restart, update, logs). Unraid doesn't know about bot-initiated operations, causing "apply update" badge persistence.
**Existing capabilities (v1.0-v1.2):**
- Container update via bot (pull image, recreate container)
- "Update All :latest" batch operation
- Container status display with inline keyboards
- Confirmation dialogs for dangerous actions
- Progress feedback during operations
**Migration target:** Replace Docker socket proxy with Unraid's native GraphQL API for all operations. Unraid 7.2+ provides a GraphQL endpoint at `/graphql` with native Docker container management.
**New scope:** Two directions for Unraid integration:
1. **Sync-back:** Clear Unraid's "update available" badge after bot updates container
2. **Read-forward:** Use Unraid's update detection data as source of truth for which containers need updates
**Key question:** Which existing features are drop-in replacements (same capability, different API) vs. which gain new capabilities vs. which need workarounds?
---
## Feature Landscape
### Table Stakes (Users Expect These)
### Direct Replacements (Same Behavior, Different API)
Features users assume exist when managing containers outside Unraid's UI.
Features that work identically via Unraid API — no user-visible changes.
| Feature | Why Expected | Complexity | Notes |
|---------|--------------|------------|-------|
| Clear "update available" badge after bot update | Users expect Unraid UI to reflect reality after external updates | MEDIUM | Requires writing to `/var/lib/docker/unraid-update-status.json` - known workaround for Watchtower/Portainer users |
| Prevent duplicate update notifications | After bot updates a container, Unraid shouldn't send false-positive Telegram notifications | MEDIUM | Same mechanism as clearing badge - update status file tracks whether updates are pending |
| Avoid breaking Unraid's update tracking | External tools shouldn't corrupt Unraid's internal state | LOW | Docker API operations are safe - Unraid tracks via separate metadata files |
| No manual "Apply Update" clicks | Point of remote management is to eliminate manual steps | HIGH | Core pain point - users want "update from bot = done" not "update from bot = still need to click in Unraid" |
| Feature | Current Implementation | Unraid API Equivalent | Complexity | Notes |
|---------|------------------------|----------------------|------------|-------|
| Container status display | `GET /containers/json` → parse JSON → display | `query { docker { containers { id names state } } }` | LOW | GraphQL returns structured data, cleaner parsing. State values uppercase (`RUNNING` not `running`) |
| Container start | `POST /containers/{id}/start` → 204 No Content | `mutation { docker { start(id: PrefixedID) { id names state } } }` | LOW | Returns container object instead of empty body. PrefixedID format: `{server_hash}:{container_hash}` |
| Container stop | `POST /containers/{id}/stop?t=10` → 204 No Content | `mutation { docker { stop(id: PrefixedID) { id names state } } }` | LOW | Same as start — returns container data |
| Container restart | `POST /containers/{id}/restart?t=10` → 204 No Content | Unraid has NO native restart mutation — must call stop then start | MEDIUM | Need to implement restart as two-step operation with error handling between steps |
| Container list pagination | Parse `/containers/json`, slice in memory | Same — query returns all containers, client-side pagination | LOW | No server-side pagination in GraphQL schema |
| Batch operations | Iterate containers, call Docker API N times | `mutation { docker { updateContainers(ids: [PrefixedID!]!) } }` for updates, iterate for start/stop | MEDIUM | Batch update is native, batch start/stop still requires iteration |
### Differentiators (Competitive Advantage)
### Enhanced Features (Gain New Capabilities)
Features that set the bot apart from other Docker management tools.
Features that work better with Unraid API.
| Feature | Value Proposition | Complexity | Notes |
|---------|-------------------|------------|-------|
| Automatic sync after every update | Bot updates container AND clears Unraid badge in single operation - zero user intervention | MEDIUM | Requires detecting update success and writing status file atomically |
| Use Unraid's update detection data | If Unraid already knows which containers need updates, bot could use that source of truth instead of its own Docker image comparison | HIGH | Requires parsing Unraid's update status JSON and integrating with existing container selection/matching logic |
| Bidirectional status awareness | Bot shows which containers Unraid thinks need updates, not just Docker image digest comparison | MEDIUM-HIGH | Depends on reading update status file - enhances accuracy for edge cases (registry issues, multi-arch images) |
| Manual sync command | Users can manually trigger "sync status to Unraid" if they updated containers through another tool | LOW | Simple command that iterates running containers and updates status file |
| Feature | New Capability | Value | Complexity | Notes |
|---------|----------------|-------|------------|-------|
| Container update | **Automatic update status sync** — Unraid knows bot updated container, no "apply update" badge | Solves core v1.3 pain point — zero manual cleanup | LOW | Unraid API's `updateContainer` mutation handles internal state sync automatically |
| "Update All :latest" | **Batch update mutation** — single GraphQL call updates multiple containers | Faster, more atomic than N sequential Docker API calls | LOW | `updateAllContainers` mutation exists but may not respect :latest filter. May need `updateContainers(ids: [...])` with filtering |
| Container status badges | **Native update detection**`isUpdateAvailable` field in container query | Bot shows what Unraid sees, eliminates digest comparison discrepancies | LOW | Docker API required manual image digest comparison, Unraid tracks this internally |
| Update progress feedback | **Real-time stats via subscription**`dockerContainerStats` subscription provides CPU/mem/IO during operations | Could show pull progress, container startup metrics | HIGH | Subscriptions require WebSocket setup, adds complexity. DEFER to future phase |
### Anti-Features (Commonly Requested, Often Problematic)
### Features Requiring Workarounds
Features that seem good but create problems.
Features where Unraid API is less capable than Docker API.
| Feature | Why Requested | Why Problematic | Alternative |
|---------|---------------|-----------------|-------------|
| Full Unraid API integration (authentication, template parsing) | "Properly" integrate with Unraid's web interface instead of file manipulation | Adds authentication complexity, XML parsing, API version compatibility, web session management - all for a cosmetic badge | Direct file writes are the established community workaround - simpler and more reliable |
| Automatic template XML regeneration | Update container templates so Unraid thinks it initiated the update | Template XML is generated by Community Applications and Docker Manager - modifying it risks breaking container configuration | Clearing update status file is sufficient - templates are source of truth for config, not update state |
| Sync status for ALL containers on every operation | Keep Unraid 100% in sync with Docker state at all times | Performance impact (Docker API queries for all containers on every update), unnecessary for user's pain point | Sync only the container(s) just updated by the bot - targeted and efficient |
| Persistent monitoring daemon | Background process that watches Docker events and updates Unraid status in real-time | Requires separate container/service, adds operational complexity, duplicates n8n's event model | On-demand sync triggered by bot operations - aligns with n8n's workflow execution model |
| Feature | Docker API Approach | Unraid API Limitation | Workaround | Complexity | Impact |
|---------|---------------------|----------------------|------------|------------|--------|
| Container logs | `GET /containers/{id}/logs?stdout=1&stderr=1&tail=N&timestamps=1` | `query { docker { logs(id: PrefixedID, tail: Int, since: DateTime) { ... } } }` | Unraid API has logs query — need to verify field structure and timestamp support | LOW-MEDIUM | Schema shows `logs` query exists, need to test response format |
| Container restart | Single `POST /restart` call | No native restart mutation | Call `stop` mutation, wait for state change, call `start` mutation. Need error handling if stop succeeds but start fails | MEDIUM | Adds latency, two points of failure instead of one |
| Container pause/unpause | `POST /containers/{id}/pause` | Unraid has `pause`/`unpause` mutations | No workaround needed — not currently used by bot | N/A | Bot doesn't use pause feature, no impact |
### New Capabilities NOT in Current Bot
Features Unraid API enables that Docker socket proxy doesn't support.
| Feature | Unraid API Capability | User Value | Complexity | Priority |
|---------|----------------------|------------|------------|----------|
| Container autostart configuration | `updateAutostartConfiguration` mutation | Users could control container boot order via bot | MEDIUM | P3 — nice to have, not requested |
| Docker network management | `query { docker { networks { ... } } }` | List/inspect networks, detect conflicts | LOW | P3 — troubleshooting aid, not core workflow |
| Port conflict detection | `query { docker { portConflicts { ... } } }` | Identify why container won't start due to port conflicts | MEDIUM | P3 — helpful for debugging, not primary use case |
| Real-time container stats | `subscription { dockerContainerStats { cpuPercent memoryUsage ... } }` | Live resource monitoring during updates | HIGH | P3 — requires WebSocket infrastructure |
---
## Feature Dependencies
```
Clear Update Badge (sync-back)
└──requires──> Update operation success detection (existing)
└──requires──> File write to /var/lib/docker/unraid-update-status.json
Container Operations (start/stop/update)
└──requires──> PrefixedID format mapping
└──requires──> Container ID resolution (existing matching logic)
Read Unraid Update Status (read-forward)
└──requires──> Parse update status JSON file
└──requires──> Container ID to name mapping (existing)
└──enhances──> Container selection UI (show Unraid's view)
Batch Update
└──requires──> Container selection UI (existing)
└──enhances──> "Update All :latest" (atomic operation)
Manual Sync Command
└──requires──> Clear Update Badge mechanism
└──requires──> Container list enumeration (existing)
Update Status Sync
└──automatically provided by──> Unraid API mutations (no explicit action needed)
└──eliminates need for──> File writes to /var/lib/docker/unraid-update-status.json
Bidirectional Status Awareness
└──requires──> Read Unraid Update Status
└──requires──> Clear Update Badge
└──conflicts──> Current Docker-only update detection (source of truth ambiguity)
Container Restart
└──requires──> Stop mutation
└──requires──> Start mutation
└──requires──> State polling between operations
Container Logs
└──requires──> GraphQL logs query testing
└──may require──> Response format adaptation (if different from Docker API)
```
### Dependency Notes
- **Clear Update Badge requires Update success detection:** Already have this - n8n-update.json returns `success: true, updated: true` with digest comparison
- **Read Unraid Status enhances Container selection:** Could show "(Unraid: update available)" badge in status keyboard - helps users see what Unraid sees
- **Bidirectional Status conflicts with Docker-only detection:** Need to decide: is Unraid's update status file the source of truth, or is Docker image digest comparison? Mixing both creates confusion about "which containers need updates"
- **PrefixedID format is critical:** Unraid uses `{server_hash}:{container_hash}` (128-char total) instead of Docker's short container ID. Existing matching logic must resolve names to Unraid IDs, not Docker IDs
- **Restart requires two mutations:** No atomic restart in Unraid API. Must implement stop → verify → start pattern
- **Update status sync is automatic:** Biggest win — no manual file manipulation needed, Unraid knows about updates immediately
- **Logs query needs verification:** Schema shows `logs` exists but field structure unknown until tested
---
## MVP Definition
## Migration Complexity Assessment
### Launch With (v1.3)
### Drop-in Replacements (LOW complexity)
Minimum viable - eliminates the core pain point.
Change API endpoint and request format, behavior unchanged.
- [ ] Clear update badge after bot-initiated updates - Write to `/var/lib/docker/unraid-update-status.json` after successful update operation
- [ ] Prevent false-positive notifications - Ensure status file write happens before user sees "update complete" message
- [ ] Integration with existing n8n-update.json sub-workflow - Add status sync as final step in update flow (text, inline, batch modes)
- [x] Container list/status display
- [x] Container start
- [x] Container stop
- [x] Batch container selection UI (no API changes)
- [x] Confirmation dialogs (no API changes)
**Rationale:** This solves the stated pain: "after updating containers through the bot, Unraid still shows update available badges and sends false-positive Telegram notifications."
**Effort:** 1-2 nodes per operation. Replace HTTP Request URL and body, adapt response parsing. Error handling pattern stays same.
### Add After Validation (v1.4+)
### Adapted Replacements (MEDIUM complexity)
Features to add once core sync-back is working.
Requires implementation changes but same user experience.
- [ ] Manual sync command (`/sync` or `/sync <container>`) - Trigger when user updates via other tools (Portainer, CLI, Watchtower)
- [ ] Read Unraid update status for better detection - Parse `/var/lib/docker/unraid-update-status.json` to see which containers Unraid thinks need updates
- [ ] Show Unraid's view in status keyboard - Display "(Unraid: update ready)" badge alongside container state
- [ ] Container restart — Implement as stop + start sequence with state verification
- [ ] Container logs — Adapt to GraphQL logs query response format
- [ ] Batch update — Use `updateContainers(ids: [...])` mutation instead of N individual calls
- [ ] Container ID resolution — Map container names to PrefixedID format
**Trigger:** User requests ability to see "what Unraid sees" or needs to sync status after non-bot updates.
**Effort:** 3-5 nodes per operation. Need state machine for restart, response format testing for logs, ID format mapping for all operations.
### Future Consideration (v2+)
### Enhanced Features (LOW-MEDIUM complexity)
Features to defer until core functionality is proven.
Gain new capabilities with minimal work.
- [ ] Bidirectional status awareness - Use Unraid's update detection as source of truth instead of Docker digest comparison
- [ ] Sync on container list view - Automatically update status file when user views container list (proactive sync)
- [ ] Batch status sync - `/sync all` command to reconcile all containers
- [x] Update status sync — Automatic via Unraid API, remove Phase 14 manual sync
- [x] Update detection — Use `isUpdateAvailable` field instead of Docker digest comparison
- [x] Batch mutations — Native support for multi-container updates
**Why defer:** Unraid's update detection has known bugs (doesn't detect external updates, false positives persist). Using it as source of truth may import those bugs. Better to prove sync-back works first, then evaluate whether read-forward adds value.
**Effort:** Remove old workarounds, use new API fields. Net simplification.
---
## Feature Prioritization Matrix
## Migration Phases
| Feature | User Value | Implementation Cost | Priority |
|---------|------------|---------------------|----------|
| Clear update badge after bot update | HIGH | MEDIUM | P1 |
| Prevent false-positive notifications | HIGH | LOW | P1 |
| Manual sync command | MEDIUM | LOW | P2 |
| Read Unraid update status | MEDIUM | MEDIUM | P2 |
| Show Unraid's view in UI | LOW | MEDIUM | P3 |
| Bidirectional status (Unraid as source of truth) | MEDIUM | HIGH | P3 |
### Phase 1: Infrastructure (Phase 14 — COMPLETE)
**Priority key:**
- P1: Must have for v1.3 launch - solves core pain point
- P2: Should have for v1.4 - adds convenience, not critical
- P3: Nice to have for v2+ - explore after validating core
- [x] Unraid GraphQL API connectivity
- [x] Authentication setup (API key, Header Auth credential)
- [x] Test query validation
- [x] Container ID format documentation
**Status:** Complete per Phase 14 verification. Ready for mutation implementation.
### Phase 2: Core Operations (Next Phase)
Replace Docker socket proxy for fundamental operations.
- [ ] Container start mutation
- [ ] Container stop mutation
- [ ] Container restart (two-step: stop + start)
- [ ] Container status query (replace `/containers/json`)
- [ ] Update PrefixedID resolution in matching sub-workflow
**Impact:** All single-container operations switch to Unraid API. Docker socket proxy only used for updates and logs temporarily.
### Phase 3: Update Operations
Replace update workflow with Unraid API.
- [ ] Single container update via `updateContainer` mutation
- [ ] Batch update via `updateContainers` mutation
- [ ] "Update All" via `updateAllContainers` mutation (or filtered `updateContainers`)
- [ ] Verify automatic update status sync (no badge persistence)
**Impact:** Solves v1.3 milestone pain point. Unraid UI reflects bot updates immediately.
### Phase 4: Logs and Polish
Replace remaining Docker API calls.
- [ ] Container logs via GraphQL `logs` query
- [ ] Verify log timestamp format and display
- [ ] Remove docker-socket-proxy dependency entirely
- [ ] Update ARCHITECTURE.md (remove Docker API contract, document Unraid API)
**Impact:** Complete migration. Docker socket proxy container can be removed.
---
## Implementation Notes
## Complexity Matrix
### File Format: /var/lib/docker/unraid-update-status.json
| Operation | Docker API | Unraid API | Complexity | Blocker |
|-----------|------------|------------|------------|---------|
| Start | POST /start | mutation start(id) | LOW | None |
| Stop | POST /stop | mutation stop(id) | LOW | None |
| Restart | POST /restart | stop + start (2 calls) | MEDIUM | State verification between mutations |
| Status | GET /json | query containers | LOW | PrefixedID format mapping |
| Update | POST /images/create + stop + rename + start | mutation updateContainer(id) | LOW | None — simpler than Docker API |
| Batch Update | N × update | mutation updateContainers(ids) | LOW | None — native support |
| Logs | GET /logs | query logs(id, tail, since) | MEDIUM | Response format unknown |
Based on community forum discussions, this file tracks update status per container. When Unraid checks for updates, it compares registry manifests and writes results here. To clear the badge, remove the container's entry from this JSON.
**Example structure (inferred from community discussions):**
```json
{
"containerId1": { "status": "update_available", "checked": "timestamp" },
"containerId2": { "status": "up_to_date", "checked": "timestamp" }
}
```
**Operation:** After bot updates a container successfully:
1. Read existing JSON file
2. Remove entry for updated container (or set status to "up_to_date")
3. Write JSON back atomically
**Confidence: LOW** - exact format not documented officially, needs verification by reading actual file.
### Integration Points
**Existing bot architecture:**
- n8n-update.json sub-workflow already returns `success: true, updated: true, oldDigest, newDigest` on successful update
- Three callers: Execute Text Update, Execute Callback Update, Execute Batch Update
- All three modes need status sync (text, inline keyboard, batch operations)
**New node requirements:**
- Read Update Status File (HTTP Request or Execute Command node - read JSON file)
- Parse Update Status (Code node - JSON manipulation)
- Write Update Status File (HTTP Request or Execute Command node - write JSON file)
- Update n8n-update.json to call status sync before returning success
**File access:** n8n runs in Docker container, needs volume mount or HTTP access to Unraid filesystem. Docker socket proxy already provides access - may need to add file system access or use Unraid API.
### Update Status Sync Mechanism
**Current state:** Unraid checks for updates by comparing local image digest with registry manifest digest. Results stored in `/var/lib/docker/unraid-update-status.json`. When container is updated externally (bot, Watchtower, CLI), Unraid doesn't re-check - status file shows stale "update available" until manually cleared.
**Community workaround:** Delete `/var/lib/docker/unraid-update-status.json` to force complete reset, OR edit JSON to remove specific container entry.
**Bot approach:** After successful update (pull + recreate), programmatically edit JSON file to mark container as up-to-date. This is what Unraid would do if it had performed the update itself.
**Alternatives considered:**
1. Call Unraid's "Check for Updates" API endpoint - requires authentication, web session, not documented
2. Trigger Unraid's update check via CLI - no known CLI command for this
3. Reboot server - clears status (per forum posts) but obviously unacceptable
4. Edit XML templates - risky, templates are config source of truth
**Selected approach:** Direct JSON file edit (community-proven workaround, lowest risk).
**Key insight:** Most operations are simpler with Unraid API. Only restart and logs require adaptation work.
---
## Competitor Analysis
## Anti-Features
### Watchtower
- Automatically updates containers on schedule
- Does NOT sync status back to Unraid
- Community complaint: "Watchtower running on unraid but containers still say update after it runs"
- Workaround: Manual deletion of update status file
Features that seem useful but complicate migration without user value.
### Portainer
- UI-based container management
- Shows its own "update available" indicator (independent of Unraid)
- Does NOT sync with Unraid's update tracking
- Users run both Portainer and Unraid UI, see conflicting status
### Unraid Docker Compose Manager
- Manages docker-compose stacks
- Known issue: "Docker tab reports updates available after even after updating stack"
- No automatic sync with Unraid Docker Manager
### Our Approach
- Automatic sync after every bot-initiated update
- Transparent to user - no manual steps after update completes
- Solves pain point that all other tools ignore
- Differentiator: tight integration with Unraid's native tracking system
| Feature | Why Tempting | Why Problematic | Alternative |
|---------|--------------|-----------------|-------------|
| Parallel use of Docker API + Unraid API | "Keep both during migration" | Two sources of truth, complex ID mapping, defeats purpose of migration | Full cutover per operation — start/stop on Unraid API, then update, then logs |
| GraphQL subscriptions for real-time stats | "Monitor container resource usage live" | Requires WebSocket setup, n8n HTTP Request node doesn't support subscriptions, adds infrastructure complexity | Poll if needed, defer to future phase with dedicated subscription node |
| Expose full GraphQL schema to user | "Let users run arbitrary queries via bot" | Security risk (unrestricted API access), complex query parsing, unclear user benefit | Expose only operations via commands (`start`, `update`, `logs`), not raw GraphQL |
| Port conflict detection on every status check | "Proactively warn about port conflicts" | Performance impact (extra query), rare occurrence, clutters UI | Only query port conflicts when start/restart fails with port binding error |
---
## Edge Cases & Considerations
## Success Criteria
### Race Conditions
- Unraid's update checker runs on schedule (user configurable)
- If checker runs between bot update and status file write, may re-detect update
- Mitigation: Write status file immediately after image pull, before container recreate
Migration is successful when:
### Multi-Arch Images
- Unraid uses manifest digests for update detection
- Bot uses `docker inspect` image ID comparison
- May disagree on whether update is needed (manifest vs image layer digest)
- Research needed: Does Unraid use manifest digest or image digest in status file?
### Failed Updates
- Bot update may fail after pulling image (recreate fails, container won't start)
- Should NOT clear update badge if container is broken
- Status sync must be conditional on full update success (container running)
### Infrastructure Containers
- Bot already excludes n8n and docker-socket-proxy from batch operations
- Status sync should respect same exclusions (don't clear badge for bot's own container)
### File Permissions
- `/var/lib/docker/` typically requires root access
- n8n container may not have write permissions
- Need to verify access method: direct mount, docker exec, or Unraid API
- [x] **Zero Docker socket proxy calls** — All operations use Unraid GraphQL API
- [x] **Update badge sync works** — Unraid UI shows correct status after bot updates
- [x] **Restart works reliably** — Two-step restart handles edge cases (stop succeeds, start fails)
- [x] **Logs display correctly** — GraphQL logs query returns usable data for Telegram display
- [x] **No performance regression** — Operations complete in same or better time than Docker API
- [x] **Error messages stay clear** — GraphQL errors map to actionable user feedback
---
## Sources
**Community Forums & Issue Discussions:**
- [Regression: Incorrect docker update notification - Unraid Forums](https://forums.unraid.net/bug-reports/stable-releases/regression-incorrect-docker-update-notification-r2807/)
- [Docker Update Check not reliable for external container - Unraid Forums](https://forums.unraid.net/bug-reports/stable-releases/691-docker-update-check-not-reliable-for-external-container-r940/)
- [Watchtower running on unraid but containers still say update after it runs - GitHub Discussion](https://github.com/containrrr/watchtower/discussions/1389)
- [Docker update via Watchtower - Status not reflected in Unraid - Unraid Forums](https://forums.unraid.net/topic/149953-docker-update-via-watchtower-status-not-reflected-in-unraid/)
- [Docker compose: Docker tab reports updates available after updating stack - Unraid Forums](https://forums.unraid.net/topic/149264-docker-compose-docker-tab-reports-updates-available-after-even-after-updating-stack/)
### Primary (HIGH confidence)
**Workarounds & Solutions:**
- [Containers show update available even when up-to-date - Unraid Forums](https://forums.unraid.net/topic/142238-containers-show-update-available-even-when-it-is-up-to-date/)
- [binhex Documentation - Docker FAQ for Unraid](https://github.com/binhex/documentation/blob/master/docker/faq/unraid.md)
- [Unraid GraphQL Schema](https://raw.githubusercontent.com/unraid/api/main/api/generated-schema.graphql) — Docker mutations (start, stop, pause, unpause, updateContainer, updateContainers, updateAllContainers), queries (containers, logs, portConflicts), subscriptions (dockerContainerStats)
- [Using the Unraid API](https://docs.unraid.net/API/how-to-use-the-api/) — Endpoint URL, authentication, rate limiting
- [Docker and VM Integration | Unraid API](https://deepwiki.com/unraid/api/2.4.2-notification-system) — DockerService architecture, retry logic, timeout handling
- Phase 14 Research (`14-RESEARCH.md`) — Container ID format (PrefixedID), authentication patterns, network access
- Phase 14 Verification (`14-VERIFICATION.md`) — Confirmed working query, credential setup, myunraid.net URL requirement
**Unraid API & Architecture:**
- [Docker and VM Integration - Unraid API DeepWiki](https://deepwiki.com/unraid/api/2.4.2-notification-system)
- [Using the Unraid API - Official Docs](https://docs.unraid.net/API/how-to-use-the-api/)
- [Dynamix Docker Manager - GitHub Source](https://github.com/limetech/dynamix/blob/master/plugins/dynamix.docker.manager/include/DockerClient.php)
### Secondary (MEDIUM confidence)
**Docker Digest Comparison:**
- [Image digests - Docker Docs](https://docs.docker.com/dhi/core-concepts/digests/)
- [Digests in Docker - Mike Newswanger](https://www.mikenewswanger.com/posts/2020/docker-image-digests/)
- [Core Services | Unraid API](https://deepwiki.com/unraid/api/2.4-docker-integration) — DockerService mutation implementation details
- Existing bot architecture (`ARCHITECTURE.md`) — Current Docker API usage patterns, sub-workflow contracts
- Project codebase (`n8n-*.json`) — Docker API calls (grep results), error handling patterns
### Implementation Details (HIGH confidence)
- **Restart requires two mutations:** Confirmed by schema — no `restart` mutation exists, only `start` and `stop`
- **Batch updates native:** Schema defines `updateContainers(ids: [PrefixedID!]!)` and `updateAllContainers` mutations
- **Logs query exists:** Schema shows `logs(id: PrefixedID!, since: DateTime, tail: Int)``DockerContainerLogs!` type
- **Real-time stats via subscription:** `dockerContainerStats` subscription exists but requires WebSocket transport
---
*Feature research for: Unraid Update Status Sync (v1.3)*
*Researched: 2026-02-08*
## Open Questions
1. **DockerContainerLogs response structure**
- What we know: Schema defines type, accepts `since` and `tail` params
- What's unclear: Field names, timestamp format, stdout/stderr separation
- Resolution: Test logs query in Phase 2/3, adapt parsing logic as needed
2. **updateAllContainers behavior**
- What we know: Mutation exists, returns `[DockerContainer!]!`
- What's unclear: Does it filter by `:latest` tag, or update everything with available updates?
- Resolution: Test mutation or use `updateContainers(ids)` with manual filtering
3. **Restart failure scenarios**
- What we know: Must implement as stop + start
- What's unclear: Best retry/backoff pattern if start fails after stop succeeds
- Resolution: Design state machine with error recovery (Phase 2 planning)
4. **Rate limiting for batch operations**
- What we know: Unraid API has rate limiting (docs confirm)
- What's unclear: Does `updateContainers` count as 1 request or N requests?
- Resolution: Test batch update with 20+ containers, monitor for 429 errors
---
*Feature research for: Unraid GraphQL API migration*
*Researched: 2026-02-09*
*Milestone: Replace Docker socket proxy with Unraid native API*