docs(02): create Docker integration phase plans
Phase 02: Docker Integration - 2 plan(s) in 2 wave(s) - Plan 01: Infrastructure setup (Docker socket, curl, env vars) - Plan 02: Container query workflow with fuzzy matching - Sequential execution (02 depends on 01) - Ready for execution Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -32,7 +32,13 @@ Plans:
|
||||
|
||||
**Delivers:** REQ-02 (container status queries)
|
||||
|
||||
**Status:** 🔲 Not started
|
||||
**Plans:** 2 plans
|
||||
|
||||
Plans:
|
||||
- [ ] 02-01-PLAN.md — Configure n8n container for Docker socket access
|
||||
- [ ] 02-02-PLAN.md — Add Docker query workflow with container matching
|
||||
|
||||
**Status:** 🔄 Planning complete
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -0,0 +1,147 @@
|
||||
---
|
||||
phase: 02-docker-integration
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified: []
|
||||
autonomous: false
|
||||
|
||||
user_setup:
|
||||
- service: unraid-docker
|
||||
why: "n8n needs Docker socket access and curl for Docker API queries"
|
||||
dashboard_config:
|
||||
- task: "Mount Docker socket to n8n container"
|
||||
location: "Unraid Docker settings for n8n container -> Add path: /var/run/docker.sock"
|
||||
- task: "Add NODES_EXCLUDE environment variable"
|
||||
location: "Unraid Docker settings for n8n container -> Add variable: NODES_EXCLUDE="
|
||||
- task: "Install curl in n8n container"
|
||||
location: "Unraid terminal: docker exec -u root n8n apk add curl"
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "Docker socket is mounted in n8n container"
|
||||
- "Execute Command node is enabled in n8n"
|
||||
- "curl is available in n8n container"
|
||||
- "n8n can query Docker API and get container list"
|
||||
artifacts:
|
||||
- path: "n8n container configuration"
|
||||
provides: "Docker socket mount at /var/run/docker.sock"
|
||||
- path: "n8n environment"
|
||||
provides: "NODES_EXCLUDE= env var enabling Execute Command"
|
||||
- path: "n8n container"
|
||||
provides: "curl binary available"
|
||||
key_links:
|
||||
- from: "n8n Execute Command node"
|
||||
to: "Docker socket"
|
||||
via: "curl --unix-socket"
|
||||
pattern: "curl.*unix-socket.*/var/run/docker.sock"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Configure n8n container with Docker socket access and required tools for Docker API queries.
|
||||
|
||||
Purpose: Enable n8n to communicate with Docker Engine API to query container information.
|
||||
Output: n8n container configured and verified to query Docker containers.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/luc/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/02-docker-integration/02-RESEARCH.md
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="checkpoint:human-action" gate="blocking">
|
||||
<name>Task 1: Configure n8n Container for Docker Access</name>
|
||||
<action>
|
||||
User must configure n8n container in Unraid with the following:
|
||||
|
||||
1. **Mount Docker socket:**
|
||||
- Unraid Docker UI -> n8n container -> Edit
|
||||
- Add path mapping: Container Path: `/var/run/docker.sock` -> Host Path: `/var/run/docker.sock`
|
||||
- Access Mode: Read/Write
|
||||
|
||||
2. **Enable Execute Command node:**
|
||||
- Add environment variable: `NODES_EXCLUDE=` (empty string)
|
||||
- This re-enables the Execute Command node which is disabled by default in n8n 2.0+
|
||||
|
||||
3. **Install curl in n8n container:**
|
||||
- After container restarts, run: `docker exec -u root n8n apk add curl`
|
||||
- This adds curl to the Alpine-based n8n image
|
||||
|
||||
4. **Restart n8n container** to apply changes
|
||||
</action>
|
||||
<resume-signal>Confirm all three steps completed (socket mounted, env var set, curl installed)</resume-signal>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Verify Docker API Access</name>
|
||||
<files>None (verification only)</files>
|
||||
<action>
|
||||
Create a simple verification to confirm Docker socket access works.
|
||||
|
||||
The user should run this command on the Unraid server:
|
||||
```bash
|
||||
docker exec n8n curl --unix-socket /var/run/docker.sock 'http://localhost/v1.53/containers/json?all=true'
|
||||
```
|
||||
|
||||
If successful, this returns JSON array of containers.
|
||||
|
||||
Common issues:
|
||||
- "Permission denied": Socket permissions issue - may need to run n8n as root or adjust socket permissions
|
||||
- "curl: not found": curl not installed - run `docker exec -u root n8n apk add curl`
|
||||
- Empty response `[]`: Docker has no containers (unlikely on Unraid)
|
||||
|
||||
Document the verification command for user to run.
|
||||
</action>
|
||||
<verify>
|
||||
User runs: `docker exec n8n curl --unix-socket /var/run/docker.sock 'http://localhost/v1.53/containers/json?all=true'`
|
||||
Expected: JSON array containing container objects with Id, Names, State, Status fields
|
||||
</verify>
|
||||
<done>Docker API returns container list via curl in n8n container</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<name>Task 3: Confirm Docker Access Working</name>
|
||||
<what-built>Docker socket access from n8n container via curl</what-built>
|
||||
<how-to-verify>
|
||||
Run this command on Unraid:
|
||||
```bash
|
||||
docker exec n8n curl --unix-socket /var/run/docker.sock 'http://localhost/v1.53/containers/json?all=true'
|
||||
```
|
||||
|
||||
Expected result:
|
||||
- JSON array with your containers
|
||||
- Each container has: Id, Names (with leading slash), State, Status
|
||||
- Example: `[{"Id":"abc123","Names":["/plex-server"],"State":"running","Status":"Up 2 days"...}]`
|
||||
|
||||
If you see the JSON output, Docker integration is ready.
|
||||
</how-to-verify>
|
||||
<resume-signal>Confirm JSON container list returned, or describe error</resume-signal>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- Docker socket mounted at /var/run/docker.sock in n8n container
|
||||
- NODES_EXCLUDE environment variable set (empty string)
|
||||
- curl available in n8n container
|
||||
- Docker API responds with container list via curl
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- `docker exec n8n curl --unix-socket /var/run/docker.sock 'http://localhost/v1.53/containers/json?all=true'` returns JSON container array
|
||||
- n8n container has Execute Command node available in node palette
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/02-docker-integration/02-01-SUMMARY.md`
|
||||
</output>
|
||||
@@ -0,0 +1,192 @@
|
||||
---
|
||||
phase: 02-docker-integration
|
||||
plan: 02
|
||||
type: execute
|
||||
wave: 2
|
||||
depends_on: ["02-01"]
|
||||
files_modified: [n8n-workflow.json]
|
||||
autonomous: false
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "User can send 'status' and see running container summary"
|
||||
- "User can ask about specific container by name and see details"
|
||||
- "Fuzzy matching works (plex finds plex-server)"
|
||||
- "Multiple matches prompt for clarification"
|
||||
- "Docker connection failure shows clear error message"
|
||||
artifacts:
|
||||
- path: "n8n-workflow.json"
|
||||
provides: "Docker query workflow branch"
|
||||
contains: "Execute Command"
|
||||
key_links:
|
||||
- from: "n8n-workflow.json"
|
||||
to: "Docker API"
|
||||
via: "Execute Command node with curl"
|
||||
pattern: "curl.*unix-socket"
|
||||
- from: "Code node (parse)"
|
||||
to: "Container JSON"
|
||||
via: "JSON.parse"
|
||||
pattern: "JSON.parse"
|
||||
- from: "Code node (match)"
|
||||
to: "Container names"
|
||||
via: "fuzzy match function"
|
||||
pattern: "includes.*toLowerCase"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Add Docker query capability to n8n workflow - list containers, match by name, format responses.
|
||||
|
||||
Purpose: Enable users to query container status through Telegram conversation.
|
||||
Output: Updated n8n-workflow.json with Docker query branch that handles "status" and container-specific queries.
|
||||
</objective>
|
||||
|
||||
<execution_context>
|
||||
@/home/luc/.claude/get-shit-done/workflows/execute-plan.md
|
||||
@/home/luc/.claude/get-shit-done/templates/summary.md
|
||||
</execution_context>
|
||||
|
||||
<context>
|
||||
@.planning/PROJECT.md
|
||||
@.planning/ROADMAP.md
|
||||
@.planning/STATE.md
|
||||
@.planning/phases/02-docker-integration/02-RESEARCH.md
|
||||
@.planning/phases/02-docker-integration/02-CONTEXT.md
|
||||
@.planning/phases/02-docker-integration/02-01-SUMMARY.md
|
||||
@n8n-workflow.json
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Add Docker Query Branch to Workflow</name>
|
||||
<files>n8n-workflow.json</files>
|
||||
<action>
|
||||
Extend the existing n8n workflow with Docker query capability.
|
||||
|
||||
**New nodes to add:**
|
||||
|
||||
1. **Switch Node** (after IF User Authenticated, replaces direct connection to Format Echo):
|
||||
- Route based on message content
|
||||
- Case 1: Message contains "status" OR starts with container-related keywords -> Docker Query branch
|
||||
- Case 2: Default -> existing Echo branch (for now, will be replaced by Claude NLU in Phase 4)
|
||||
|
||||
2. **Execute Command Node** (Docker List):
|
||||
- Command: `curl --unix-socket /var/run/docker.sock 'http://localhost/v1.53/containers/json?all=true'`
|
||||
- This fetches all containers (running and stopped)
|
||||
|
||||
3. **Code Node** (Parse and Match):
|
||||
- Parse JSON response from curl
|
||||
- Extract container name from user message (simple: look for words that aren't "status", "show", "check", etc.)
|
||||
- Implement fuzzy matching per CONTEXT.md:
|
||||
- Case-insensitive
|
||||
- Strip common prefixes (linuxserver-, binhex-)
|
||||
- Substring match
|
||||
- Handle cases:
|
||||
- No container name -> return summary (count by state)
|
||||
- Single match -> return that container's details
|
||||
- Multiple matches -> return list and ask for clarification
|
||||
- No matches -> return "not found" message
|
||||
|
||||
4. **Code Node** (Format Response):
|
||||
- Format per CONTEXT.md:
|
||||
- Emoji + text: "checkmark plex-server: Running (2 days)"
|
||||
- State emoji mapping: running=checkmark, exited=X, paused=pause, restarting=arrows, dead=skull
|
||||
- Summary shows counts: "25 running, 3 stopped"
|
||||
- Single container shows: name, state, uptime, image
|
||||
- Strip leading slash from container names
|
||||
- Calculate uptime from Status field (already human-readable like "Up 2 days")
|
||||
|
||||
5. **Telegram Send** (reuse existing Send Echo node or create new for Docker responses)
|
||||
|
||||
**Connection changes:**
|
||||
- IF User Authenticated -> Switch Node
|
||||
- Switch Node case "docker" -> Execute Command -> Parse and Match -> Format Response -> Telegram Send
|
||||
- Switch Node default -> Format Echo -> Send Echo (existing)
|
||||
|
||||
**Error handling:**
|
||||
- If curl fails (non-zero exit), format error message: "Can't reach Docker - check if n8n has socket access"
|
||||
- If JSON parse fails, format error message: "Unexpected Docker response"
|
||||
|
||||
**Important implementation notes from RESEARCH.md:**
|
||||
- Container names have leading slash: use `.replace(/^\//, '')`
|
||||
- Health status may not exist: use optional chaining `?.`
|
||||
- Use simple substring matching first (no external library needed)
|
||||
</action>
|
||||
<verify>
|
||||
- n8n-workflow.json contains Execute Command node with curl command
|
||||
- n8n-workflow.json contains Code nodes for parsing and formatting
|
||||
- Switch node routes "status" messages to Docker branch
|
||||
- JSON structure is valid (can be imported into n8n)
|
||||
</verify>
|
||||
<done>Workflow JSON updated with complete Docker query branch</done>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-action" gate="blocking">
|
||||
<name>Task 2: Import Updated Workflow</name>
|
||||
<action>
|
||||
User imports the updated n8n-workflow.json into n8n:
|
||||
|
||||
1. Open n8n in browser
|
||||
2. Go to the Docker Manager Bot workflow
|
||||
3. Delete existing workflow (or create new one)
|
||||
4. Import updated n8n-workflow.json
|
||||
5. Select Telegram API credential for both Telegram nodes
|
||||
6. Activate workflow
|
||||
</action>
|
||||
<resume-signal>Confirm workflow imported and activated</resume-signal>
|
||||
</task>
|
||||
|
||||
<task type="checkpoint:human-verify" gate="blocking">
|
||||
<name>Task 3: Verify Docker Query Flow</name>
|
||||
<what-built>Docker query capability via Telegram conversation</what-built>
|
||||
<how-to-verify>
|
||||
Test these scenarios in Telegram:
|
||||
|
||||
1. **Summary query:**
|
||||
- Send: "status"
|
||||
- Expected: Summary like "Container summary: 15 running, 2 stopped"
|
||||
|
||||
2. **Specific container (exact match):**
|
||||
- Send: "status plex" (or name of a container you have)
|
||||
- Expected: Detailed status with emoji, state, uptime
|
||||
|
||||
3. **Fuzzy match:**
|
||||
- Send: "check plex" (partial name)
|
||||
- Expected: Same as above - finds plex-server or similar
|
||||
|
||||
4. **Multiple matches (if applicable):**
|
||||
- Send a name that matches multiple containers
|
||||
- Expected: List of matches asking for clarification
|
||||
|
||||
5. **Not found:**
|
||||
- Send: "status nonexistent123"
|
||||
- Expected: "No container found matching..." message
|
||||
|
||||
6. **Fallback to echo (non-docker message):**
|
||||
- Send: "hello"
|
||||
- Expected: Echo response (existing behavior)
|
||||
</how-to-verify>
|
||||
<resume-signal>Confirm all test scenarios pass, or describe failures</resume-signal>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- "status" returns container summary with counts
|
||||
- Container name query returns detailed status with emoji
|
||||
- Fuzzy matching works (partial names, case-insensitive)
|
||||
- Multiple matches prompt for clarification
|
||||
- Non-docker messages fall through to echo
|
||||
- Docker errors show clear message
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- User sends "status" -> sees running container count/summary
|
||||
- User sends "status plex" -> sees plex container details with emoji status
|
||||
- User sends "hello" -> gets echo response (existing flow works)
|
||||
- Invalid container name -> clear "not found" message
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/02-docker-integration/02-02-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user