# settings

key: features.ldap
value:
  {"loginEnabled":false,"loginLabel":"","connectionUrl":"","allowUnauthorizedCerts":false,"connectionSecurity":"none","connectionPort":389,"baseDn":"","bindingAdminDn":"","bindingAdminPassword":"","firstNameAttribute":"","lastNameAttribute":"","emailAttribute":"","loginIdAttribute":"","ldapIdAttribute":"","userFilter":"","synchronizationEnabled":false,"synchronizationInterval":60,"searchPageSize":0,"searchTimeout":60,"enforceEmailUniqueness":true}


key: license.cert
value:
  [encoded data, 6244 characters]


key: instance.firstProductionFailure
value:
  {"workflowId":"ioR8eFBEVaKOkjc0","projectId":"cZz5fzaW49pCUs3C","userId":"3f77e136-dc7a-4d58-8dc6-817cb2b88866","timestamp":1772773211877}


# execution_data

workflowVersionId: f2a17289-ca75-4511-a9b7-2691b7ce0fa3
workflowData:
  {"id":"ioR8eFBEVaKOkjc0","name":"Create User n8n Server","active":false,"activeVersionId":null,"nodes":[{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"curlImport":"","method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","authentication":"none","provideSslCertificates":false,"sendQuery":false,"sendHeaders":false,"sendBody":true,"contentType":"json","specifyBody":"keypair","bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{},"infoMessage":""},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"}],"connections":{"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","binaryMode":"separate","availableInMCP":false},"pinData":{}}

data:
  [{"version":1,"startData":"1","resultData":"2","executionData":"3"},{"destinationNode":"4","runNodeFilter":"5"},{"runData":"6","pinData":"7","lastNodeExecuted":"8"},{"contextData":"9","nodeExecutionStack":"10","metadata":"11","waitingExecution":"12","waitingExecutionSource":"13","runtimeData":"14"},{"nodeName":"8","mode":"15"},["8"],{"HTTP Request":"16"},{},"HTTP Request",{"node:HTTP Request":"17"},[],{},{},{},{"version":1,"establishedAt":1772773211443,"source":"18","triggerNode":"19"},"inclusive",["20"],{"response":"21"},"manual",{"name":"8","type":"22"},{"startTime":1772773211447,"executionIndex":0,"source":"23","hints":"24","executionTime":494,"executionStatus":"25","data":"26"},{"body":"27"},"n8n-nodes-base.httpRequest",[],[],"success",{"main":"28"},{"message":"29"},["30"],"Workflow was started",["31"],{"json":"27","pairedItem":"32"},{"item":0}]


workflowVersionId: f2a17289-ca75-4511-a9b7-2691b7ce0fa3
workflowData:
  {"id":"ioR8eFBEVaKOkjc0","name":"Create User n8n Server","active":true,"activeVersionId":"370acd9f-8c23-404f-be77-ec179f6ec858","isArchived":false,"createdAt":"2026-03-06T04:58:21.680Z","updatedAt":"2026-03-06T05:00:01.002Z","nodes":[{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"}],"connections":{"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","binaryMode":"separate","availableInMCP":false},"staticData":{},"pinData":{}}

data:
  [{"version":1,"startData":"1","resultData":"2","executionData":"3"},{},{"error":"4","runData":"5","lastNodeExecuted":"6"},{"contextData":"7","nodeExecutionStack":"8","metadata":"9","waitingExecution":"10","waitingExecutionSource":"11","runtimeData":"12"},{"level":"13","tags":"14","timestamp":1772773211952,"context":"15","functionality":"16","name":"17","node":"18","messages":"19","message":"20","stack":"21"},{"Webhook":"22","Build Docker Command":"23","Run Docker":"24"},"Run Docker",{},["25"],{},{},{},{"version":1,"establishedAt":1772773211877,"source":"26","triggerNode":"27"},"warning",{},{"itemIndex":0},"regular","NodeOperationError",{"parameters":"28","name":"6","type":"29","position":"30","typeVersion":1,"id":"31"},[],"Command failed: docker run -d --name n8n-undefined --memory=1g --cpus=1 -v n8n_undefined:/home/node/.n8n -e N8N_HOST=n8n.undefined.inmetech.cloud -e N8N_PROTOCOL=https -e WEBHOOK_URL=https://n8n.undefined.inmetech.cloud/ -e N8N_TRUST_PROXY=true --label traefik.enable=true --label traefik.http.routers.n8n-undefined.rule=Host(`n8n.undefined.inmetech.cloud`) --label traefik.http.routers.n8n-undefined.entrypoints=websecure --label traefik.http.routers.n8n-undefined.tls.certresolver=letsencrypt --label traefik.http.services.n8n-undefined.loadbalancer.server.port=5678  docker.n8n.io/n8nio/n8n\n/bin/sh: syntax error: unexpected \"(\"\n","NodeOperationError: Command failed: docker run -d --name n8n-undefined --memory=1g --cpus=1 -v n8n_undefined:/home/node/.n8n -e N8N_HOST=n8n.undefined.inmetech.cloud -e N8N_PROTOCOL=https -e WEBHOOK_URL=https://n8n.undefined.inmetech.cloud/ -e N8N_TRUST_PROXY=true --label traefik.enable=true --label traefik.http.routers.n8n-undefined.rule=Host(`n8n.undefined.inmetech.cloud`) --label traefik.http.routers.n8n-undefined.entrypoints=websecure --label traefik.http.routers.n8n-undefined.tls.certresolver=letsencrypt --label traefik.http.services.n8n-undefined.loadbalancer.server.port=5678  docker.n8n.io/n8nio/n8n\n/bin/sh: syntax error: unexpected \"(\"\n\n    at ExecuteContext.execute (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/nodes/ExecuteCommand/ExecuteCommand.node.ts:102:12)\n    at WorkflowExecute.executeNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1043:8)\n    at WorkflowExecute.runNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1222:11)\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1665:27\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:2308:11",["32"],["33"],["34"],{"node":"35","data":"36","source":"37"},"webhook",{"name":"38","type":"39"},{"executeOnce":true,"command":"40"},"n8n-nodes-base.executeCommand",[416,-144],"d049c848-745f-43ce-ad8f-2069344eb356",{"startTime":1772773211879,"executionIndex":0,"source":"41","hints":"42","executionTime":1,"executionStatus":"43","data":"44"},{"startTime":1772773211881,"executionIndex":1,"source":"45","hints":"46","executionTime":36,"executionStatus":"43","data":"47"},{"startTime":1772773211917,"executionIndex":2,"source":"48","hints":"49","executionTime":55,"executionStatus":"50","error":"51"},{"parameters":"52","name":"6","type":"29","position":"53","typeVersion":1,"id":"31"},{"main":"54"},{"main":"48"},"Webhook","n8n-nodes-base.webhook","={{$json.command}}",[],[],"success",{"main":"55"},["56"],[],{"main":"57"},["58"],[],"error",{"level":"13","tags":"14","timestamp":1772773211952,"context":"15","functionality":"16","name":"17","node":"18","messages":"19","message":"20","stack":"21"},{"executeOnce":true,"command":"40"},[416,-144],["59"],["60"],{"previousNode":"38","previousNodeOutput":0,"previousNodeRun":0},["61"],{"previousNode":"62","previousNodeOutput":0,"previousNodeRun":0},["63"],["64"],["65"],"Build Docker Command",{"json":"66","pairedItem":"67"},{"json":"68","pairedItem":"69"},{"json":"66","pairedItem":"70"},{"command":"71","url":"72"},{"item":0},{"headers":"73","params":"74","query":"75","body":"76","webhookUrl":"77","executionMode":"78"},{"item":0},{"item":0},"docker run -d --name n8n-undefined --memory=1g --cpus=1 -v n8n_undefined:/home/node/.n8n -e N8N_HOST=n8n.undefined.inmetech.cloud -e N8N_PROTOCOL=https -e WEBHOOK_URL=https://n8n.undefined.inmetech.cloud/ -e N8N_TRUST_PROXY=true --label traefik.enable=true --label traefik.http.routers.n8n-undefined.rule=Host(`n8n.undefined.inmetech.cloud`) --label traefik.http.routers.n8n-undefined.entrypoints=websecure --label traefik.http.routers.n8n-undefined.tls.certresolver=letsencrypt --label traefik.http.services.n8n-undefined.loadbalancer.server.port=5678  docker.n8n.io/n8nio/n8n","https://n8n.undefined.inmetech.cloud",{"host":"79","user-agent":"80","content-length":"81","accept":"82","accept-encoding":"83","content-type":"84","x-forwarded-for":"85","x-forwarded-host":"79","x-forwarded-port":"86","x-forwarded-proto":"87","x-forwarded-server":"88","x-real-ip":"85"},{},{},{"user_id":"89","ram":"90","cpu":"91"},"https://admin.n8n.inmetech.cloud/webhook/create-n8n","production","admin.n8n.inmetech.cloud","axios/1.13.5","42","application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","gzip, compress, deflate, br","application/json","172.18.0.1","443","https","f431cf187979","user123","1g","1"]


workflowVersionId: fc3bc306-cf91-4f89-aa4b-75ee88a0be50
workflowData:
  {"id":"ioR8eFBEVaKOkjc0","name":"Create User n8n Server","active":false,"activeVersionId":null,"nodes":[{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"curlImport":"","method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","authentication":"none","provideSslCertificates":false,"sendQuery":false,"sendHeaders":false,"sendBody":true,"contentType":"json","specifyBody":"keypair","bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{},"infoMessage":""},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"}],"connections":{"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","binaryMode":"separate","availableInMCP":false},"pinData":{"Webhook":[{"json":{"headers":{"host":"admin.n8n.inmetech.cloud","user-agent":"axios/1.13.5","content-length":"42","accept":"application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","accept-encoding":"gzip, compress, deflate, br","content-type":"application/json","x-forwarded-for":"172.18.0.1","x-forwarded-host":"admin.n8n.inmetech.cloud","x-forwarded-port":"443","x-forwarded-proto":"https","x-forwarded-server":"f431cf187979","x-real-ip":"172.18.0.1"},"params":{},"query":{},"body":{"user_id":"user123","ram":"1g","cpu":"1"},"webhookUrl":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","executionMode":"production"},"pairedItem":{"item":0}}]}}

data:
  [{"version":1,"startData":"1","resultData":"2","executionData":"3"},{"destinationNode":"4","runNodeFilter":"5"},{"error":"6","runData":"7","pinData":"8","lastNodeExecuted":"9"},{"contextData":"10","nodeExecutionStack":"11","metadata":"12","waitingExecution":"13","waitingExecutionSource":"14","runtimeData":"15"},{"nodeName":"9","mode":"16"},["17","9"],{"message":"18","stack":"19"},{"Webhook":"20","Build Docker Command":"21"},{"Webhook":"22"},"Build Docker Command",{},["23"],{},{},{},{"version":1,"establishedAt":1772773295472,"source":"24","triggerNode":"25"},"inclusive","Webhook","user_id missing [Line 4]","Error: user_id missing\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/dist/nodes/Function:4:9\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/dist/nodes/Function:36:2\n    at VM2 Wrapper.apply (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/vm2@3.10.5/node_modules/vm2/lib/bridge.js:672:11)\n    at NodeVM.run (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/vm2@3.10.5/node_modules/vm2/lib/nodevm.js:497:23)\n    at ExecuteContext.execute (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/nodes/Function/Function.node.ts:169:21)\n    at WorkflowExecute.executeNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1043:31)\n    at WorkflowExecute.runNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1222:22)\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1665:38\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:2308:11",["26"],["27"],["28"],{"node":"29","data":"30","source":"31"},"manual",{"name":"9","type":"32"},{"startTime":1772773211879,"executionIndex":0,"source":"33","hints":"34","executionTime":1,"executionStatus":"35","data":"36"},{"startTime":1772773295473,"executionIndex":1,"source":"37","hints":"38","executionTime":22,"executionStatus":"39","error":"40"},{"json":"41","pairedItem":"42"},{"parameters":"43","name":"9","type":"32","position":"44","typeVersion":1,"id":"45"},{"main":"46"},{"main":"37"},"n8n-nodes-base.function",[],[],"success",{"main":"47"},["48"],[],"error",{"message":"18","stack":"19"},{"headers":"49","params":"50","query":"51","body":"52","webhookUrl":"53","executionMode":"54"},{"item":0},{"notice":"55","functionCode":"56"},[112,-144],"7c91468e-80ea-4de5-8553-376dc01f0973",["57"],["58"],{"previousNode":"17","previousNodeOutput":0,"previousNodeRun":0},{"host":"59","user-agent":"60","content-length":"61","accept":"62","accept-encoding":"63","content-type":"64","x-forwarded-for":"65","x-forwarded-host":"59","x-forwarded-port":"66","x-forwarded-proto":"67","x-forwarded-server":"68","x-real-ip":"65"},{},{},{"user_id":"69","ram":"70","cpu":"71"},"https://admin.n8n.inmetech.cloud/webhook/create-n8n","production","","const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];",["72"],["73"],"admin.n8n.inmetech.cloud","axios/1.13.5","42","application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","gzip, compress, deflate, br","application/json","172.18.0.1","443","https","f431cf187979","user123","1g","1",{"json":"41","pairedItem":"74"},{"json":"75","pairedItem":"76"},{"item":0},{"headers":"77","params":"78","query":"79","body":"80","webhookUrl":"53","executionMode":"54"},{"item":0},{"host":"59","user-agent":"60","content-length":"61","accept":"62","accept-encoding":"63","content-type":"64","x-forwarded-for":"65","x-forwarded-host":"59","x-forwarded-port":"66","x-forwarded-proto":"67","x-forwarded-server":"68","x-real-ip":"65"},{},{},{"user_id":"69","ram":"70","cpu":"71"}]


workflowVersionId: bfa0341d-c9ac-4770-8935-19b9c2979780
workflowData:
  {"id":"ioR8eFBEVaKOkjc0","name":"Create n8n Instance","active":false,"activeVersionId":null,"nodes":[{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"curlImport":"","method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","authentication":"none","provideSslCertificates":false,"sendQuery":false,"sendHeaders":false,"sendBody":true,"contentType":"json","specifyBody":"keypair","bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{},"infoMessage":""},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"keepOnlySet":false,"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"notice":"","functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"executeOnce":true,"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"notice":"","functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"executeOnce":true,"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"executeOnce":true,"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"notice":"","functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"executeOnce":true,"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"notice":"","functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n1111","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"notice":"","functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"curlImport":"","method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","authentication":"none","provideSslCertificates":false,"sendQuery":false,"sendHeaders":false,"sendBody":true,"contentType":"json","specifyBody":"keypair","bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{},"infoMessage":""},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}],"connections":{"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]},"Prepare Data":{"main":[[{"node":"List Containers","type":"main","index":0}]]},"List Containers":{"main":[[{"node":"Check Duplicate","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","binaryMode":"separate","availableInMCP":false},"pinData":{"Webhook":[{"json":{"headers":{"host":"admin.n8n.inmetech.cloud","user-agent":"axios/1.13.5","content-length":"42","accept":"application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","accept-encoding":"gzip, compress, deflate, br","content-type":"application/json","x-forwarded-for":"172.18.0.1","x-forwarded-host":"admin.n8n.inmetech.cloud","x-forwarded-port":"443","x-forwarded-proto":"https","x-forwarded-server":"f431cf187979","x-real-ip":"172.18.0.1"},"params":{},"query":{},"body":{"user_id":"user123","ram":"1g","cpu":"1"},"webhookUrl":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","executionMode":"production"},"pairedItem":{"item":0}}]}}

data:
  [{"version":1,"startData":"1","resultData":"2","executionData":"3"},{"destinationNode":"4","runNodeFilter":"5"},{"runData":"6","pinData":"7","lastNodeExecuted":"8"},{"contextData":"9","nodeExecutionStack":"10","metadata":"11","waitingExecution":"12","waitingExecutionSource":"13","runtimeData":"14"},{"nodeName":"8","mode":"15"},["8"],{"HTTP Request1":"16"},{"Webhook":"17"},"HTTP Request1",{"node:HTTP Request1":"18"},[],{},{},{},{"version":1,"establishedAt":1772773624087,"source":"19","triggerNode":"20"},"inclusive",["21"],["22"],{"response":"23"},"manual",{"name":"8","type":"24"},{"startTime":1772773624090,"executionIndex":0,"source":"25","hints":"26","executionTime":287,"executionStatus":"27","data":"28"},{"json":"29","pairedItem":"30"},{"body":"31"},"n8n-nodes-base.httpRequest",[],[],"success",{"main":"32"},{"headers":"33","params":"34","query":"35","body":"36","webhookUrl":"37","executionMode":"38"},{"item":0},{"message":"39"},["40"],{"host":"41","user-agent":"42","content-length":"43","accept":"44","accept-encoding":"45","content-type":"46","x-forwarded-for":"47","x-forwarded-host":"41","x-forwarded-port":"48","x-forwarded-proto":"49","x-forwarded-server":"50","x-real-ip":"47"},{},{},{"user_id":"51","ram":"52","cpu":"53"},"https://admin.n8n.inmetech.cloud/webhook/create-n8n","production","Workflow was started",["54"],"admin.n8n.inmetech.cloud","axios/1.13.5","42","application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","gzip, compress, deflate, br","application/json","172.18.0.1","443","https","f431cf187979","user123","1g","1",{"json":"31","pairedItem":"55"},{"item":0}]


workflowVersionId: bfa0341d-c9ac-4770-8935-19b9c2979780
workflowData:
  {"id":"ioR8eFBEVaKOkjc0","name":"Create n8n Instance","active":true,"activeVersionId":"9d185630-6aca-46e3-b9b4-7ceb8e19d3fb","isArchived":false,"createdAt":"2026-03-06T04:58:21.680Z","updatedAt":"2026-03-06T05:06:49.520Z","nodes":[{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"curlImport":"","method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","authentication":"none","provideSslCertificates":false,"sendQuery":false,"sendHeaders":false,"sendBody":true,"contentType":"json","specifyBody":"keypair","bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{},"infoMessage":""},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"keepOnlySet":false,"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"notice":"","functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"executeOnce":true,"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"notice":"","functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"executeOnce":true,"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"executeOnce":true,"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"notice":"","functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"notice":"","functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"executeOnce":true,"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"notice":"","functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"multipleMethods":false,"httpMethod":"POST","path":"create-n8n1111","authentication":"none","responseMode":"onReceived","responseCode":200,"contentTypeNotice":"","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"notice":"","functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"executeOnce":true,"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"generalNotice":"","respondWith":"firstIncomingItem","options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"curlImport":"","method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","authentication":"none","provideSslCertificates":false,"sendQuery":false,"sendHeaders":false,"sendBody":true,"contentType":"json","specifyBody":"keypair","bodyParameters":{"parameters":[{"name":"user_id","value":"user1"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{},"infoMessage":""},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}],"connections":{"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]},"Prepare Data":{"main":[[{"node":"List Containers","type":"main","index":0}]]},"List Containers":{"main":[[{"node":"Check Duplicate","type":"main","index":0}]]}},"settings":{"executionOrder":"v1","binaryMode":"separate","availableInMCP":false},"staticData":{},"pinData":{"Webhook":[{"json":{"headers":{"host":"admin.n8n.inmetech.cloud","user-agent":"axios/1.13.5","content-length":"42","accept":"application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","accept-encoding":"gzip, compress, deflate, br","content-type":"application/json","x-forwarded-for":"172.18.0.1","x-forwarded-host":"admin.n8n.inmetech.cloud","x-forwarded-port":"443","x-forwarded-proto":"https","x-forwarded-server":"f431cf187979","x-real-ip":"172.18.0.1"},"params":{},"query":{},"body":{"user_id":"user123","ram":"1g","cpu":"1"},"webhookUrl":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","executionMode":"production"},"pairedItem":{"item":0}}]}}

data:
  [{"version":1,"startData":"1","resultData":"2","executionData":"3"},{},{"error":"4","runData":"5","lastNodeExecuted":"6"},{"contextData":"7","nodeExecutionStack":"8","metadata":"9","waitingExecution":"10","waitingExecutionSource":"11","runtimeData":"12"},{"message":"13","stack":"14"},{"Webhook2":"15","Prepare Data":"16"},"Prepare Data",{},["17"],{},{},{},{"version":1,"establishedAt":1772773624314,"source":"18","triggerNode":"19"},"user_id missing [Line 4]","Error: user_id missing\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/dist/nodes/Function:4:9\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/dist/nodes/Function:22:2\n    at VM2 Wrapper.apply (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/vm2@3.10.5/node_modules/vm2/lib/bridge.js:672:11)\n    at NodeVM.run (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/vm2@3.10.5/node_modules/vm2/lib/nodevm.js:497:23)\n    at ExecuteContext.execute (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-nodes-base@file+packages+nodes-base_@aws-sdk+credential-providers@3.808.0_asn1.js@5_8da18263ca0574b0db58d4fefd8173ce/node_modules/n8n-nodes-base/nodes/Function/Function.node.ts:169:21)\n    at WorkflowExecute.executeNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1043:31)\n    at WorkflowExecute.runNode (/usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1222:22)\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:1665:38\n    at /usr/local/lib/node_modules/n8n/node_modules/.pnpm/n8n-core@file+packages+core_@opentelemetry+api@1.9.0_@opentelemetry+exporter-trace-otlp_9f358c3eeaef0d2736f54ac9757ada43/node_modules/n8n-core/src/execution-engine/workflow-execute.ts:2308:11",["20"],["21"],{"node":"22","data":"23","source":"24"},"webhook",{"name":"25","type":"26"},{"startTime":1772773624318,"executionIndex":0,"source":"27","hints":"28","executionTime":1,"executionStatus":"29","data":"30"},{"startTime":1772773624320,"executionIndex":1,"source":"31","hints":"32","executionTime":31,"executionStatus":"33","error":"34"},{"parameters":"35","id":"36","name":"6","type":"37","position":"38","typeVersion":1},{"main":"39"},{"main":"31"},"Webhook2","n8n-nodes-base.webhook",[],[],"success",{"main":"40"},["41"],[],"error",{"message":"13","stack":"14"},{"notice":"42","functionCode":"43"},"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","n8n-nodes-base.function",[-672,1200],["44"],["45"],{"previousNode":"25","previousNodeOutput":0,"previousNodeRun":0},"","const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];",["46"],["47"],{"json":"48","pairedItem":"49"},{"json":"48","pairedItem":"50"},{"headers":"51","params":"52","query":"53","body":"54","webhookUrl":"55","executionMode":"56"},{"item":0},{"item":0},{"host":"57","user-agent":"58","content-length":"59","accept":"60","accept-encoding":"61","content-type":"62","x-forwarded-for":"63","x-forwarded-host":"57","x-forwarded-port":"64","x-forwarded-proto":"65","x-forwarded-server":"66","x-real-ip":"63"},{},{},{"user_id":"67","ram":"68","cpu":"69"},"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","production","admin.n8n.inmetech.cloud","axios/1.13.5","39","application/json,text/html,application/xhtml+xml,application/xml,text/*;q=0.9, image/*;q=0.8, */*;q=0.7","gzip, compress, deflate, br","application/json","172.18.0.1","443","https","f431cf187979","1234","1g","1"]


# user

id: 3f77e136-dc7a-4d58-8dc6-817cb2b88866
email: rizowansiddique@gmail.com
firstName: RIZOWAN
lastName: rizowansiddique@gmail.com
password: $2a$10$a5BxANs3UkqwfXY5dKFbse289gvU7SjgGdFLh48DD86ylcOhi0iwC
createdAt: 2026-03-06 04:57:50.744
updatedAt: 2026-03-06 04:58:06
settings: {"userActivated":false}
lastActiveAt: 2026-03-06
roleSlug: global:owner
personalizationAnswers:
  {"version":"v4","personalization_survey_submitted_at":"2026-03-06T04:58:07.143Z","personalization_survey_n8n_version":"2.10.3"}


# workflow_history

versionId: ca712434-0ad0-4d4f-8652-9eb9306ee2a8
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 04:58:21.686
updatedAt: 2026-03-06 04:58:21.686
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-48,-96],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[256,-96],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[560,-96],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[816,-96],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]}}


versionId: 370acd9f-8c23-404f-be77-ec179f6ec858
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 04:58:28.731
updatedAt: 2026-03-06 04:59:39
name: Version 370acd9f
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]}}


versionId: baa86904-c4ef-4010-bb23-0d0798d02cbc
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 04:59:52.501
updatedAt: 2026-03-06 04:59:52.501
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[512,224],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]}}


versionId: 81920a61-a843-4304-825d-75d8b5a9f3b3
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 04:59:56.071
updatedAt: 2026-03-06 04:59:56.071
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"}]

connections:
[cell repeats an earlier one in this file: 231 characters]


versionId: f2a17289-ca75-4511-a9b7-2691b7ce0fa3
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:00:01.003
updatedAt: 2026-03-06 05:00:01.003
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nconst cmd = `docker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label traefik.http.routers.n8n-${user}.rule=Host(\\`${domain}\\`) \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${domain}` } }];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"}]

connections:
[cell repeats an earlier one in this file: 231 characters]


versionId: fc3bc306-cf91-4f89-aa4b-75ee88a0be50
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:01:34.809
updatedAt: 2026-03-06 05:01:34.809
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"}]

connections:
[cell repeats an earlier one in this file: 231 characters]


versionId: 285f3e29-532e-4e7c-b4b2-d193af9c54e5
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:02:48.475
updatedAt: 2026-03-06 05:02:48.475
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]}}


versionId: ee251927-8041-419f-97d4-a97f32049f96
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:05:11.200
updatedAt: 2026-03-06 05:05:11.200
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]}}


versionId: 4fbe9afd-8972-4eb3-b6e1-bb70468b1e25
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:05:16.126
updatedAt: 2026-03-06 05:05:16.126
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]},"Prepare Data":{"main":[[{"node":"List Containers","type":"main","index":0}]]},"List Containers":{"main":[[{"node":"Check Duplicate","type":"main","index":0}]]}}


versionId: 36d1509a-6676-4676-b4eb-fe32fb63cc67
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:05:20.470
updatedAt: 2026-03-06 05:05:20.470
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"009b5a49-b88a-4314-a3f1-89ed6eeffe93","name":"Webhook3","type":"n8n-nodes-base.webhook","position":[-976,1856],"typeVersion":1,"webhookId":"459de9ca-eec6-4e95-a7d0-772d0f1a514b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"6447f14c-cc00-4a41-8984-9cf0b0cfa3bb","name":"Prepare Data1","type":"n8n-nodes-base.function","position":[-736,1856],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"419de9af-19c1-4320-9542-ee2115dbb85e","name":"List Containers1","type":"n8n-nodes-base.executeCommand","position":[-480,1744],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"3ffadfe2-a97f-4184-94c4-b781fea47500","name":"Check Duplicate1","type":"n8n-nodes-base.function","position":[-224,1744],"typeVersion":1},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"fea1e447-d596-4039-9e60-cc9de087c024","name":"Build Docker Command2","type":"n8n-nodes-base.function","position":[32,1856],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"63857df6-328c-4324-84d8-87cf6168a149","name":"Run Docker2","type":"n8n-nodes-base.executeCommand","position":[272,1856],"typeVersion":1},{"parameters":{"options":{}},"id":"2a3d9c0d-7f65-4730-9f75-2ffe7f4543dc","name":"Respond3","type":"n8n-nodes-base.respondToWebhook","position":[528,1856],"typeVersion":1}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]},"Prepare Data":{"main":[[{"node":"List Containers","type":"main","index":0}]]},"List Containers":{"main":[[{"node":"Check Duplicate","type":"main","index":0}]]},"Webhook3":{"main":[[{"node":"Prepare Data1","type":"main","index":0}]]},"Check Duplicate1":{"main":[[{"node":"Build Docker Command2","type":"main","index":0}]]},"Build Docker Command2":{"main":[[{"node":"Run Docker2","type":"main","index":0}]]},"Run Docker2":{"main":[[{"node":"Respond3","type":"main","index":0}]]}}


versionId: 4bf2016d-9c08-4a74-afca-1926ffdabfc7
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:05:40.654
updatedAt: 2026-03-06 05:05:40.654
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"path":"ec0fa388-5055-4524-9adb-21dfd976f806","options":{}},"type":"n8n-nodes-base.webhook","typeVersion":2.1,"position":[-592,1664],"id":"84346f4e-5a9e-468d-b564-74fe7c1e8c99","name":"Webhook3","webhookId":"ec0fa388-5055-4524-9adb-21dfd976f806"}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]},"Prepare Data":{"main":[[{"node":"List Containers","type":"main","index":0}]]},"List Containers":{"main":[[{"node":"Check Duplicate","type":"main","index":0}]]}}


versionId: fc47ad8e-caf4-428e-a45a-8e8a7bd70196
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:05:50.825
updatedAt: 2026-03-06 05:05:50.825
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 31cf9688-316a-4cc4-a8df-ba01116bebf5
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:05:54.460
updatedAt: 2026-03-06 05:05:54.460
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user1"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 7be55d5f-51fe-48da-b0cb-d3842ba563fe
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:06:06.652
updatedAt: 2026-03-06 05:06:06.652
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[112,-144],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973"},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user1"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: ba231745-44b2-4e08-86f0-0dc5ea19589d
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:06:17.639
updatedAt: 2026-03-06 05:06:17.639
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b"},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user1"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 9d185630-6aca-46e3-b9b4-7ceb8e19d3fb
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:06:27.147
updatedAt: 2026-03-06 05:06:29
name: Version 9d185630
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user1"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 12245b43-f693-48fc-9f02-fb1e6f96050f
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:06:40.633
updatedAt: 2026-03-06 05:06:40.633
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user1"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 4feebac7-ff3b-4bf3-839a-9d6a02c3a16e
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:06:44.417
updatedAt: 2026-03-06 05:06:44.417
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: bfa0341d-c9ac-4770-8935-19b9c2979780
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:06:49.522
updatedAt: 2026-03-06 05:06:49.522
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: c4d8b9a6-f94e-472b-96a8-34466617b949
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:10:23.032
updatedAt: 2026-03-06 05:10:23.032
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = ;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: b0319ad9-feaa-4e2d-a01f-87c1bdedcec8
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:11:17.086
updatedAt: 2026-03-06 05:11:17.086
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":"const user = ;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"},{"parameters":{"jsCode":"// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all();"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[-464,1200],"id":"48594458-80cf-442a-be1d-c146a406d631","name":"Code in JavaScript"}]

connections:
  {"Webhook":{"main":[[{"node":"Build Docker Command","type":"main","index":0}]]},"Build Docker Command":{"main":[[{"node":"Run Docker","type":"main","index":0}]]},"Run Docker":{"main":[[{"node":"Respond","type":"main","index":0}]]},"Set Input":{"main":[[{"node":"Build Commands","type":"main","index":0}]]},"Build Commands":{"main":[[{"node":"Check Existing","type":"main","index":0},{"node":"Create Volume","type":"main","index":0}]]},"Check Existing":{"main":[[{"node":"Fail If Exists","type":"main","index":0}]]},"Fail If Exists":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Create Volume":{"main":[[{"node":"Run Container","type":"main","index":0}]]},"Run Container":{"main":[[{"node":"Prepare Response","type":"main","index":0}]]},"Prepare Response":{"main":[[{"node":"Respond1","type":"main","index":0}]]},"Webhook1":{"main":[[{"node":"Set Input","type":"main","index":0}]]},"Check Duplicate":{"main":[[{"node":"Build Docker Command1","type":"main","index":0}]]},"Webhook2":{"main":[[{"node":"Prepare Data","type":"main","index":0}]]},"Build Docker Command1":{"main":[[{"node":"Run Docker1","type":"main","index":0}]]},"Run Docker1":{"main":[[{"node":"Respond2","type":"main","index":0}]]},"Prepare Data":{"main":[[{"node":"List Containers","type":"main","index":0},{"node":"Code in JavaScript","type":"main","index":0}]]},"List Containers":{"main":[[{"node":"Check Duplicate","type":"main","index":0}]]}}


versionId: af3173d0-d5a2-4e82-8080-9dc9eb1a5638
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:11:24.773
updatedAt: 2026-03-06 05:11:24.773
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":""},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"},{"parameters":{"jsCode":"// Loop over input items and add a new field called 'myNewField' to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all();"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[-464,1200],"id":"48594458-80cf-442a-be1d-c146a406d631","name":"Code in JavaScript"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 44117e37-f6ac-4327-93f8-eb439bd1a09c
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:11:31.532
updatedAt: 2026-03-06 05:11:31.532
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":""},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"},{"parameters":{"jsCode":"const user = ;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[-464,1200],"id":"48594458-80cf-442a-be1d-c146a406d631","name":"Code in JavaScript"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


versionId: 91ac832d-df1a-46ee-87ad-0aa740ed9f86
workflowId: ioR8eFBEVaKOkjc0
authors: RIZOWAN rizowansiddique@gmail.com
createdAt: 2026-03-06 05:11:38.177
updatedAt: 2026-03-06 05:11:38.177
nodes:
  [{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook","type":"n8n-nodes-base.webhook","position":[-192,-144],"typeVersion":1,"id":"026a9c89-93a9-4dc5-9af4-701d31b89ae6","webhookId":"a4d792e3-b5b9-425f-b612-c938e71de65d"},{"parameters":{"functionCode":"const user = $json.user_id;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = \"n8n.\" + user + \".inmetech.cloud\";\n\nconst cmd = `\ndocker run -d \\\n--name n8n-${user} \\\n--memory=${ram} \\\n--cpus=${cpu} \\\n-v n8n_${user}:/home/node/.n8n \\\n-e N8N_HOST=${domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \"traefik.http.routers.n8n-${user}.rule=Host('${domain}')\" \\\n--label traefik.http.routers.n8n-${user}.entrypoints=websecure \\\n--label traefik.http.routers.n8n-${user}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.n8n-${user}.loadbalancer.server.port=5678 \\\ndocker.n8n.io/n8nio/n8n\n`;\n\nreturn [{\n  json: {\n    command: cmd,\n    url: \"https://\" + domain\n  }\n}];"},"name":"Build Docker Command","type":"n8n-nodes-base.function","position":[176,-192],"typeVersion":1,"id":"7c91468e-80ea-4de5-8553-376dc01f0973","disabled":true},{"parameters":{"command":"={{$json.command}}"},"name":"Run Docker","type":"n8n-nodes-base.executeCommand","position":[416,-144],"typeVersion":1,"id":"d049c848-745f-43ce-ad8f-2069344eb356"},{"parameters":{"options":{}},"name":"Respond","type":"n8n-nodes-base.respondToWebhook","position":[672,-144],"typeVersion":1,"id":"c17c8373-bb00-4562-ae8f-c18a13839f0d"},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"user123"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[336,-400],"id":"9654e007-c6e7-4a2b-b48a-7ee7df40a1c0","name":"HTTP Request"},{"parameters":{"values":{"string":[{"name":"apiKey","value":"{{$json[\"apiKey\"] || $env.API_KEY || \"\"}}"},{"name":"username","value":"={{$json[\"username\"] || $json[\"email\"] || $json[\"user\"] || \"user\"}}"},{"name":"plan","value":"={{$json[\"plan\"] || \"basic\"}}"},{"name":"domain","value":"={{$json[\"domain\"] || $env.DEFAULT_DOMAIN || \"inmetech.cloud\"}}"}]},"options":{}},"name":"Set Input","type":"n8n-nodes-base.set","typeVersion":1,"position":[-400,256],"id":"503fad3f-a1b5-4820-a049-48dd916574f5"},{"parameters":{"functionCode":"const payload = items[0].json;\n\n// simple API key check (secure your webhook in production)\nconst providedKey = payload.apiKey || '';\nconst expected = process.env.API_KEY || '';\nif (!expected || providedKey !== expected) {\n  throw new Error('Invalid API key');\n}\n\n// sanitize username\nlet raw = (payload.username || 'user').toString();\nlet username = raw.toLowerCase().replace(/[^a-z0-9\\-]/g, '').slice(0, 20) || 'user';\n\n// plan -> resources mapping (restrict to allowed values)\nconst plans = {\n  basic: { ram: '1g', cpus: '0.5' },\n  pro: { ram: '2g', cpus: '1' },\n  agency: { ram: '4g', cpus: '2' }\n};\nconst plan = (payload.plan || 'basic').toLowerCase();\nconst res = plans[plan] || plans['basic'];\n\nconst domain = (payload.domain || process.env.DEFAULT_DOMAIN || 'inmetech.cloud').replace(/[^a-z0-9.\\-]/gi,'');\nconst subdomain = `n8n-${username}`;\nconst host = `${subdomain}.${domain}`;\nconst containerName = `n8n-${username}`;\nconst volume = `${containerName}_data`;\n\n// environment variables for each user container (disable dangerous nodes for clients)\nconst envs = [\n  `-e N8N_HOST=${host}`,\n  `-e N8N_PROTOCOL=https`,\n  `-e WEBHOOK_URL=https://${host}/` ,\n  `-e N8N_TRUST_PROXY=true`,\n  `-e N8N_SECURE_COOKIE=true`,\n  `-e NODES_EXCLUDE=[\"n8n-nodes-base.executeCommand\",\"n8n-nodes-base.localFileTrigger\"]`\n];\n\n// labels for Traefik routing\nconst labels = [\n  `--label traefik.enable=true`,\n  `--label traefik.http.routers.${containerName}.entrypoints=websecure`,\n  `--label traefik.http.routers.${containerName}.rule=Host(\\`${host}\\`)`,\n  `--label traefik.http.routers.${containerName}.tls.certresolver=letsencrypt`,\n  `--label traefik.http.services.${containerName}.loadbalancer.server.port=5678`\n];\n\n// prepare docker commands\nconst cmdCreateVolume = `docker volume create ${volume}`;\nconst cmdRun = `docker run -d --name ${containerName} --restart unless-stopped --memory=${res.ram} --cpus=${res.cpus} -v ${volume}:/home/node/.n8n ${envs.join(' ')} ${labels.join(' ')} docker.n8n.io/n8nio/n8n`;\n\n// check existing container cmd\nconst cmdCheck = `docker ps -a --filter \\\"name=^/${containerName}$\\\" --format \\\"{{.Names}}\\\"`;\n\nreturn [ { json: { username, plan, domain, host, containerName, cmdCreateVolume, cmdRun, cmdCheck } } ];"},"name":"Build Commands","type":"n8n-nodes-base.function","typeVersion":1,"position":[-160,256],"id":"6b4138b5-495d-46a4-8a37-1ef01adb601a"},{"parameters":{"command":"={{$json.commandCheck}}"},"name":"Check Existing","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,192],"id":"33050773-1166-410e-af9a-2629b205483c"},{"parameters":{"functionCode":"const out = items[0].json;\nif (out && out.data && out.data.length) {\n  const names = out.data.trim();\n  if (names) throw new Error(`Container already exists: ${names}`);\n}\nreturn items;"},"name":"Fail If Exists","type":"n8n-nodes-base.function","typeVersion":1,"position":[336,192],"id":"8b770345-6008-45df-b449-648dc9181903"},{"parameters":{"command":"={{$json.cmdCreateVolume}}"},"name":"Create Volume","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[96,320],"id":"c3ef5fcd-65be-44ef-a8fa-dc1db8dc1621"},{"parameters":{"command":"={{$json.cmdRun}}"},"name":"Run Container","type":"n8n-nodes-base.executeCommand","typeVersion":1,"position":[336,320],"id":"749ef316-deab-4898-805c-891900d0fed0"},{"parameters":{"functionCode":"const j = items[0].json;\nreturn [{ json: { success: true, host: j.host, container: j.containerName, message: 'Container creation triggered. Allow 10-30s to boot and acquire TLS.' } }];"},"name":"Prepare Response","type":"n8n-nodes-base.function","typeVersion":1,"position":[608,256],"id":"352f91c6-e900-433c-8d9b-b653cbf5e275"},{"parameters":{"httpMethod":"POST","path":"create-n8n","options":{}},"name":"Webhook1","type":"n8n-nodes-base.webhook","typeVersion":1,"position":[-640,256],"id":"8e72c500-0d98-4892-b3bf-16633ffdb18f","webhookId":"91e8d5c0-cb20-4d3a-978a-db8e22e4073b","disabled":true},{"parameters":{"options":{}},"name":"Respond1","type":"n8n-nodes-base.respondToWebhook","typeVersion":1,"position":[864,256],"id":"8d30d07b-7c63-43dd-89cc-fed8ec9d226b"},{"parameters":{"functionCode":""},"id":"9ddf7ecd-9b82-40df-82c7-63fc748fb79c","name":"Prepare Data","type":"n8n-nodes-base.function","position":[-672,1200],"typeVersion":1},{"parameters":{"command":"docker ps -a --format '{{.Names}}'"},"id":"0f259cf3-ccd1-481d-b237-bbb048f9ce3c","name":"List Containers","type":"n8n-nodes-base.executeCommand","position":[-416,1088],"typeVersion":1},{"parameters":{"functionCode":"const existing = $json.stdout || \"\";\nconst user = $items(\"Prepare Data\")[0].json.user;\n\nif (existing.includes(`n8n-${user}`)) {\n  throw new Error(\"Container already exists\");\n}\n\nreturn $items(\"Prepare Data\");"},"id":"12aa3069-ada6-4845-ad2f-87af3d31bb85","name":"Check Duplicate","type":"n8n-nodes-base.function","position":[-160,1088],"typeVersion":1},{"parameters":{"httpMethod":"POST","path":"create-n8n1111","options":{}},"id":"fb6697e6-8815-4beb-936d-f16f1814cfdc","name":"Webhook2","type":"n8n-nodes-base.webhook","position":[-912,1200],"typeVersion":1,"webhookId":"c08aedad-597e-4ea4-b647-bccecb2c90f3"},{"parameters":{"functionCode":"const data = $json;\n\nconst cmd = `docker run -d \\\n--name ${data.container} \\\n--memory=${data.ram} \\\n--cpus=${data.cpu} \\\n-v ${data.volume}:/home/node/.n8n \\\n-e N8N_HOST=${data.domain} \\\n-e N8N_PROTOCOL=https \\\n-e WEBHOOK_URL=https://${data.domain}/ \\\n-e N8N_TRUST_PROXY=true \\\n--label traefik.enable=true \\\n--label \\\"traefik.http.routers.${data.container}.rule=Host('${data.domain}')\\\" \\\n--label traefik.http.routers.${data.container}.entrypoints=websecure \\\n--label traefik.http.routers.${data.container}.tls.certresolver=letsencrypt \\\n--label traefik.http.services.${data.container}.loadbalancer.server.port=5678 \\\n docker.n8n.io/n8nio/n8n`;\n\nreturn [{ json: { command: cmd, url: `https://${data.domain}` } }];"},"id":"36f16652-730e-4ff9-8978-16747fa1d8e3","name":"Build Docker Command1","type":"n8n-nodes-base.function","position":[96,1200],"typeVersion":1},{"parameters":{"command":"={{$json.command}}"},"id":"652ddbd1-09f1-4ac6-84c2-169a34d5016c","name":"Run Docker1","type":"n8n-nodes-base.executeCommand","position":[336,1200],"typeVersion":1},{"parameters":{"options":{}},"id":"2672e437-0f80-43fa-91ad-80805b69d424","name":"Respond2","type":"n8n-nodes-base.respondToWebhook","position":[592,1200],"typeVersion":1},{"parameters":{"method":"POST","url":"https://admin.n8n.inmetech.cloud/webhook/create-n8n1111","sendBody":true,"bodyParameters":{"parameters":[{"name":"user_id","value":"1234"},{"name":"ram","value":"1g"},{"name":"cpu","value":"1"}]},"options":{}},"type":"n8n-nodes-base.httpRequest","typeVersion":4.4,"position":[-592,1664],"id":"6699443d-0372-4cbf-958a-e890a12c5381","name":"HTTP Request1"},{"parameters":{"jsCode":"const user = ;\n\nif (!user) {\n  throw new Error(\"user_id missing\");\n}\n\nconst ram = $json.ram || \"1g\";\nconst cpu = $json.cpu || \"1\";\n\nconst domain = `n8n.${user}.inmetech.cloud`;\n\nreturn [{\n  json: {\n    user,\n    ram,\n    cpu,\n    domain,\n    container: `n8n-${user}`,\n    volume: `n8n_${user}`\n  }\n}];"},"type":"n8n-nodes-base.code","typeVersion":2,"position":[-480,1312],"id":"48594458-80cf-442a-be1d-c146a406d631","name":"Code in JavaScript"}]

connections:
[cell repeats an earlier one in this file: 1374 characters]


