feat: v1.3 Unraid Update Status Sync

Unraid GraphQL API foundation — connectivity, authentication, and
container ID format verified for native Unraid API integration.

Phase 14: Unraid API Access (2 plans, 4 tasks)
- Established Unraid GraphQL API connectivity via myunraid.net cloud relay
- Dual credential storage (.env.unraid-api + n8n env vars)
- Container ID format: {server_hash}:{container_hash} (128-char SHA256 pair)
- Complete API contract documented in ARCHITECTURE.md
- "unraid" test command added to Telegram bot

Phases 15-16 dropped (superseded by v1.4 Unraid API Native).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Lucas Berger
2026-02-09 07:47:31 -05:00
parent ff0773b84b
commit 903e73d616
14 changed files with 1018 additions and 205 deletions
+118
View File
@@ -33,6 +33,124 @@ Docker Engine
**Total:** 287 nodes (166 main + 121 across 7 sub-workflows)
## Unraid GraphQL API
The Unraid GraphQL API is used to sync container update status back to Unraid after bot-initiated updates, resolving the "apply update" badge issue (see Known Limitations).
### API Overview
- **Endpoint:** `{UNRAID_HOST}/graphql` (POST)
- **Authentication:** `x-api-key` header with Unraid API key
- **Available in:** Unraid 7.2+ (native) or 6.9-7.1 (Connect plugin)
- **Purpose:** Sync container update status back to Unraid after bot-initiated updates
### Authentication
- **Header:** `x-api-key: {api_key}`
- **Credential:** n8n Header Auth credential named "Unraid API Key" - Header Name: `x-api-key`
- Header Value: Unraid API key
- **Permission required:** `DOCKER:UPDATE_ANY`
- **Key creation:** `unraid-api apikey --create --name "Docker Manager Bot" --permissions "DOCKER:UPDATE_ANY"`
Alternative: Unraid WebGUI -> Settings -> Management Access -> API Keys -> Create key with DOCKER:UPDATE_ANY permission.
### Network Access
**Critical findings:**
- Direct LAN IP (http://192.168.90.103) does NOT work — nginx redirects HTTP to HTTPS, stripping auth headers on redirect
- Direct HTTPS with standard port (https://192.168.90.103:8443) does NOT have /graphql endpoint
- **Working approach:** Use Unraid's myunraid.net cloud relay URL
**Working configuration:**
- **URL format:** `https://{ip-dashed}.{hash}.myunraid.net:8443/graphql`
- Example: `https://192-168-90-103.abc123def456.myunraid.net:8443/graphql`
- **Environment variable:** Set `UNRAID_HOST` on n8n container (without /graphql suffix)
- **SSL:** Valid certs via myunraid.net — no SSL ignore needed
- **Authentication:** n8n Header Auth credential
**Why this works:**
- myunraid.net cloud relay properly handles GraphQL endpoint routing
- Auth headers preserved through the cloud relay
- No nginx redirect issues
- GraphQL sandbox mode NOT required for API access
**Note:** The `host.docker.internal` and direct IP approaches documented in Phase 14 Plan 01 research did not work in production testing. The myunraid.net relay is the verified working solution for Unraid 7.2.
### Container Query (Phase 14 — read-only)
```graphql
query { docker { containers { id names state } } }
```
**Expected response structure:**
```json
{
"data": {
"docker": {
"containers": [
{
"id": "1639d2f04f44841bc62fec38d18e1869a558d85071fa23e0a8bf64d374b317fa:8a9907a245766012741662a5840cefdec67af6b70e4c6f1629af7ef8f1ee2925",
"names": ["/n8n"],
"state": "RUNNING"
}
]
}
}
}
```
**Important field behaviors:**
- `state` values are **UPPERCASE** (`RUNNING`, not `running`)
- `names` array entries are **prefixed with `/`** (e.g., `/n8n` not `n8n`)
- `isUpdateAvailable` field does **NOT exist** in Unraid 7.2 schema (research was incorrect)
**Schema differences from research:**
- Phase 14 research incorrectly documented `isUpdateAvailable` field
- Actual schema introspection shows this field is not present in DockerContainer type
- Phase 15 will need to determine correct field for update status tracking
### Container ID Format
- **Type:** `PrefixedID` scalar
- **Format:** `{server_hash}:{container_hash}` — two 64-character SHA256 hex strings joined by colon
- **Example:** `1639d2f04f44841bc62fec38d18e1869a558d85071fa23e0a8bf64d374b317fa:8a9907a245766012741662a5840cefdec67af6b70e4c6f1629af7ef8f1ee2925`
- **Components:**
- First part (server hash): Same for all containers on a given Unraid server
- Second part (container hash): Unique per container
- **Note:** Discovered during Phase 14 verification testing. Phase 15 mutations use this format.
### n8n Container Configuration
**Required environment variable:**
- `UNRAID_HOST` — Unraid myunraid.net URL (without /graphql suffix)
- Example: `https://192-168-90-103.abc123def456.myunraid.net:8443`
- Set via Unraid WebGUI -> Docker -> n8n container -> Edit -> Add Variable
**Required n8n credential:**
- **Type:** Header Auth
- **Name:** "Unraid API Key"
- **Header Name:** `x-api-key`
- **Header Value:** Unraid API key (from `unraid-api apikey --create`)
**HTTP Request node configuration:**
- **Authentication:** `genericCredentialType` with `httpHeaderAuth`
- **Credential:** "Unraid API Key"- **URL:** `{{ $env.UNRAID_HOST }}/graphql`
### Update Mutation (Phase 15 — planned, not yet implemented)
```graphql
mutation { docker { updateContainer(id: "<PrefixedID>") { id } } }
```
**Status:** Planned for Phase 15 — not yet implemented per phase boundary.
**Note:** Update tracking field needs discovery via schema introspection (isUpdateAvailable does not exist).
### Error Patterns
- **HTTP errors:** Connection refused (network), 401 (bad API key), 404 (API not available)
- **GraphQL errors:** `response.errors[]` array with message field
- **Error handling:** Same pattern as Docker API errors (structured return, descriptive messages)
## Workflow Files
| File | n8n ID | Purpose | Nodes |