Files
unraid-docker-manager/n8n-container-actions.json
T
Lucas Berger 6ef2736cff fix(10-03): fix success detection for container actions
Docker API returns 204 No Content on success (empty response body).
Changed from checking statusCode (not available in n8n httpRequest)
to checking for absence of error/message in response body.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 13:37:03 -05:00

304 lines
10 KiB
JSON

{
"name": "Container Actions",
"nodes": [
{
"parameters": {
"inputSource": "passthrough",
"schema": {
"schemaType": "fromFields",
"inputFieldName": "",
"fields": [
{
"fieldName": "containerId",
"fieldType": "string"
},
{
"fieldName": "containerName",
"fieldType": "string"
},
{
"fieldName": "action",
"fieldType": "string"
},
{
"fieldName": "chatId",
"fieldType": "number"
},
{
"fieldName": "messageId",
"fieldType": "number"
},
{
"fieldName": "responseMode",
"fieldType": "string"
}
]
}
},
"id": "trigger-sub-workflow",
"name": "When executed by another workflow",
"type": "n8n-nodes-base.executeWorkflowTrigger",
"typeVersion": 1.1,
"position": [
240,
300
]
},
{
"parameters": {
"rules": {
"values": [
{
"id": "route-start",
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "loose"
},
"conditions": [
{
"id": "is-start",
"leftValue": "={{ $json.action }}",
"rightValue": "start",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "start"
},
{
"id": "route-stop",
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "loose"
},
"conditions": [
{
"id": "is-stop",
"leftValue": "={{ $json.action }}",
"rightValue": "stop",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "stop"
},
{
"id": "route-restart",
"conditions": {
"options": {
"caseSensitive": true,
"typeValidation": "loose"
},
"conditions": [
{
"id": "is-restart",
"leftValue": "={{ $json.action }}",
"rightValue": "restart",
"operator": {
"type": "string",
"operation": "equals"
}
}
],
"combinator": "and"
},
"renameOutput": true,
"outputKey": "restart"
}
]
},
"options": {
"fallbackOutput": "none"
}
},
"id": "switch-action-type",
"name": "Route Action",
"type": "n8n-nodes-base.switch",
"typeVersion": 3.2,
"position": [
460,
300
]
},
{
"parameters": {
"method": "POST",
"url": "=http://docker-socket-proxy:2375/v1.47/containers/{{ $json.containerId }}/start",
"options": {
"timeout": 15000
}
},
"id": "http-start-container",
"name": "Start Container",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
680,
200
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "POST",
"url": "=http://docker-socket-proxy:2375/v1.47/containers/{{ $json.containerId }}/stop?t=10",
"options": {
"timeout": 15000
}
},
"id": "http-stop-container",
"name": "Stop Container",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
680,
300
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"method": "POST",
"url": "=http://docker-socket-proxy:2375/v1.47/containers/{{ $json.containerId }}/restart?t=10",
"options": {
"timeout": 15000
}
},
"id": "http-restart-container",
"name": "Restart Container",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
680,
400
],
"onError": "continueRegularOutput"
},
{
"parameters": {
"jsCode": "// Format start action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u25B6\\uFE0F <b>${containerName}</b> started successfully`;\n} else {\n message = `\\u274C Failed to start <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-start-result",
"name": "Format Start Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
200
]
},
{
"parameters": {
"jsCode": "// Format stop action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u23F9\\uFE0F <b>${containerName}</b> stopped`;\n} else {\n message = `\\u274C Failed to stop <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-stop-result",
"name": "Format Stop Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
300
]
},
{
"parameters": {
"jsCode": "// Format restart action result\nconst triggerData = $('When executed by another workflow').item.json;\nconst containerId = triggerData.containerId;\nconst containerName = triggerData.containerName;\nconst action = triggerData.action;\nconst chatId = triggerData.chatId;\nconst messageId = triggerData.messageId;\nconst responseMode = triggerData.responseMode;\n\n// Docker API returns 204 No Content on success (empty response body)\n// Error responses contain 'message' field\nconst response = $input.item.json || {};\nconst hasError = response.message || response.error || false;\n\n// Success = no error message in response (empty {} means 204 success)\nconst success = !hasError;\n\nlet message;\nif (success) {\n message = `\\u{1F504} <b>${containerName}</b> restarted`;\n} else {\n message = `\\u274C Failed to restart <b>${containerName}</b>`;\n}\n\nreturn {\n json: {\n success,\n message,\n action,\n containerName,\n containerId,\n chatId,\n messageId,\n responseMode\n }\n};"
},
"id": "code-format-restart-result",
"name": "Format Restart Result",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
400
]
}
],
"connections": {
"When executed by another workflow": {
"main": [
[
{
"node": "Route Action",
"type": "main",
"index": 0
}
]
]
},
"Route Action": {
"main": [
[
{
"node": "Start Container",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop Container",
"type": "main",
"index": 0
}
],
[
{
"node": "Restart Container",
"type": "main",
"index": 0
}
]
]
},
"Start Container": {
"main": [
[
{
"node": "Format Start Result",
"type": "main",
"index": 0
}
]
]
},
"Stop Container": {
"main": [
[
{
"node": "Format Stop Result",
"type": "main",
"index": 0
}
]
]
},
"Restart Container": {
"main": [
[
{
"node": "Format Restart Result",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1",
"callerPolicy": "any"
}
}