8
n8n 中文网amn8n.com

使用邮件审批和 SSH 自动化基于 Docker 的 n8n 更新

高级

这是一个DevOps领域的自动化工作流,包含 27 个节点。主要使用 If, Set, Ssh, EmailSend, HttpRequest 等节点。 使用邮件审批和 SSH 自动化基于 Docker 的 n8n 更新

前置要求
  • 可能需要目标 API 的认证凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "meta": {
    "instanceId": "0cf1013c00750bfab7ca7f6a76bf0e8c2407d7a4a9a4e66c4888ec456837f043",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "6486fadd-3584-4544-9a02-57ede53e836b",
      "name": "便签 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3456,
        -448
      ],
      "parameters": {
        "color": 4,
        "width": 280,
        "height": 288,
        "content": "## 🚀 工作流开始"
      },
      "typeVersion": 1
    },
    {
      "id": "683461fc-856d-41e8-9d49-9b725fa3a2fa",
      "name": "计划触发器",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3120,
        -368
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "daysInterval": 3,
              "triggerAtHour": 16
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ab507d4a-1a4c-49de-9b32-07f60969b0e7",
      "name": "如果无更改",
      "type": "n8n-nodes-base.if",
      "position": [
        -2000,
        -368
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "47b24202-69ea-481a-8848-67de206ea3c0",
              "operator": {
                "type": "boolean",
                "operation": "false",
                "singleValue": true
              },
              "leftValue": "={{ $json.update_available }}",
              "rightValue": "=Download complete"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "bcdcdc19-e21c-48fb-80bb-014144c6fa6a",
      "name": "检查更新脚本是否存在",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -1328,
        -384
      ],
      "parameters": {
        "cwd": "/root",
        "command": "=sh -c \"if [ -f update_docker.sh ]; then echo true; else echo false; fi\""
      },
      "credentials": {
        "sshPassword": {
          "id": "09btBw3BAMtH8hXO",
          "name": "SSH Password account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "a9cbbad8-5f2f-411f-bc4a-62230e93c0e2",
      "name": "如果文件存在",
      "type": "n8n-nodes-base.if",
      "position": [
        -1104,
        -384
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "1cf2c480-a309-46bc-a0c4-c2cf9827822d",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.stdout }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "ba972070-a78a-4982-975f-7219f26571e3",
      "name": "创建更新脚本",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -880,
        -304
      ],
      "parameters": {
        "cwd": "/root",
        "command": "=sh -c \"printf '%s\\n' 'sleep 30s' 'cd /opt/n8n-docker-caddy' 'docker compose pull' 'docker compose down' 'docker compose up -d' > update_docker.sh; chmod +x update_docker.sh\""
      },
      "credentials": {
        "sshPassword": {
          "id": "09btBw3BAMtH8hXO",
          "name": "SSH Password account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "12f9fcab-8bcb-4bea-8e66-69f5227fb7bf",
      "name": "如果已批准",
      "type": "n8n-nodes-base.if",
      "position": [
        -1552,
        -272
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "32c6b0f0-0747-47de-90e4-56ded46d3d34",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.data.approved }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f3a6c807-0f12-45b6-bed7-ce4cbda4e42b",
      "name": "无更新",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1776,
        -464
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3a90a6d9-b1b1-4f9b-8194-676dccbdb5a5",
      "name": "不执行任何操作",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1328,
        -160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "c1dbc70c-db44-4f5c-9854-64d34d9f114f",
      "name": "请求批准更新",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        -1776,
        -272
      ],
      "webhookId": "c1c2c77a-a3c1-4c4d-83e9-229dfc3b0903",
      "parameters": {
        "message": "=<h2>🔔 n8n Update Available</h2>\n\n<p>A new version of n8n is available on Docker Hub!</p>\n\n<table style=\"border-collapse: collapse; width: 100%; margin: 20px 0;\">\n  <tr style=\"background-color: #f8f9fa;\">\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; font-weight: bold;\">Current Version:</td>\n    <td style=\"padding: 12px; border: 1px solid #dee2e6;\">{{ $json.current_version }}</td>\n  </tr>\n  <tr>\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; font-weight: bold;\">New Version Available:</td>\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; color: #28a745; font-weight: bold;\">Latest from Docker Hub</td>\n  </tr>\n  <tr style=\"background-color: #f8f9fa;\">\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; font-weight: bold;\">Local Digest:</td>\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; font-family: monospace; font-size: 11px;\">{{ $json.local_digest }}</td>\n  </tr>\n  <tr>\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; font-weight: bold;\">Remote Digest:</td>\n    <td style=\"padding: 12px; border: 1px solid #dee2e6; font-family: monospace; font-size: 11px;\">{{ $json.remote_digest }}</td>\n  </tr>\n</table>\n\n<h3>📋 What happens if you approve?</h3>\n<ol>\n  <li>Pull the new n8n Docker image from Docker Hub</li>\n  <li>Restart the n8n container with the new version</li>\n</ol>\n\n<h3>🔧 Manual Update Option</h3>\n<p>If you prefer to update manually later, run these commands on your server:</p>\n<pre style=\"background-color: #f8f8f8; padding: 10px; border-radius: 4px; border: 1px solid #ddd;\">\ncd /opt/n8n-docker-caddy\ndocker compose pull\ndocker compose down\ndocker compose up -d\n</pre>\n\n<p><strong>Do you want to proceed with the automatic update?</strong></p>",
        "options": {
          "limitWaitTime": {
            "values": {
              "resumeAmount": 3
            }
          },
          "appendAttribution": false
        },
        "subject": "Approval Required for Updating n8n!",
        "toEmail": "youremail@yourdomain.com",
        "fromEmail": "info@yourdomain.com",
        "operation": "sendAndWait",
        "approvalOptions": {
          "values": {
            "approvalType": "double"
          }
        }
      },
      "credentials": {
        "smtp": {
          "id": "7qY1U0ZUdM7HKciv",
          "name": "SMTP account"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "0829b238-0c14-4be8-bbf1-edaa63016b51",
      "name": "便签 - 自动更新",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -112
      ],
      "parameters": {
        "color": 6,
        "width": 320,
        "height": 432,
        "content": "## 🔧 自动化更新流程"
      },
      "typeVersion": 1
    },
    {
      "id": "c68450b6-ff97-4be4-932f-42dbabdab811",
      "name": "便签 - 脚本逻辑",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -672
      ],
      "parameters": {
        "color": 7,
        "width": 280,
        "height": 248,
        "content": "## 🎯 脚本逻辑"
      },
      "typeVersion": 1
    },
    {
      "id": "277ab82a-701a-4edc-8def-1dab9165ebe2",
      "name": "便签 - 最终执行",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        -752
      ],
      "parameters": {
        "color": 3,
        "width": 320,
        "height": 328,
        "content": "## 🚀 最终执行"
      },
      "typeVersion": 1
    },
    {
      "id": "5a44fe76-5ca3-4477-9f5d-486c8abec4ab",
      "name": "执行更新脚本",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -656,
        -400
      ],
      "parameters": {
        "cwd": "/root",
        "command": "=sh -c \"exec >/root/update.log 2>&1; nohup /root/update_docker.sh &\""
      },
      "credentials": {
        "sshPassword": {
          "id": "09btBw3BAMtH8hXO",
          "name": "SSH Password account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9a65a79e-eb2e-4ad2-8920-fe6a4a8053c6",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3536,
        -928
      ],
      "parameters": {
        "color": 5,
        "width": 3104,
        "height": 1520,
        "content": "# n8n 自更新器"
      },
      "typeVersion": 1
    },
    {
      "id": "9b195a5d-3057-4690-9a7f-63947349df7b",
      "name": "获取本地镜像摘要",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -2672,
        -368
      ],
      "parameters": {
        "cwd": "/root",
        "command": "sh -c \"docker inspect n8n-docker-caddy-n8n-1 --format='{{index .Image}}' | xargs docker inspect --format='{{index .RepoDigests 0}}'\""
      },
      "credentials": {
        "sshPassword": {
          "id": "09btBw3BAMtH8hXO",
          "name": "SSH Password account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9f46efa6-bfa4-43cc-bc8b-50f4789bfc3f",
      "name": "获取远程镜像摘要",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2448,
        -368
      ],
      "parameters": {
        "url": "https://hub.docker.com/v2/repositories/n8nio/n8n/tags/latest",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "b06e54b7-3760-46b6-b35b-95f74ea19ada",
      "name": "便利贴 9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        -672
      ],
      "parameters": {
        "width": 320,
        "height": 264,
        "content": "## 🔀 更新检查"
      },
      "typeVersion": 1
    },
    {
      "id": "ef630305-91e7-4d78-9a8d-a2729063ddb0",
      "name": "准备更新数据",
      "type": "n8n-nodes-base.set",
      "position": [
        -2224,
        -368
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "832662b6-8fe8-4849-870b-71d32bf88a46",
              "name": "current_version",
              "type": "string",
              "value": "={{ $('Get Current n8n Version').first().json.stdout }}"
            },
            {
              "id": "local-digest-assign",
              "name": "local_digest",
              "type": "string",
              "value": "={{ $('Get Local Image Digest').first().json.stdout.split('@')[1] }}"
            },
            {
              "id": "remote-digest-assign",
              "name": "remote_digest",
              "type": "string",
              "value": "={{ $('Get Remote Image Digest').first().json.digest }}"
            },
            {
              "id": "new-version-assign",
              "name": "update_available",
              "type": "boolean",
              "value": "={{ $('Get Local Image Digest').first().json.stdout.split('@')[1] !== $('Get Remote Image Digest').first().json.digest }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "71409d64-8391-4f08-8359-223728303c20",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        -736
      ],
      "parameters": {
        "color": 4,
        "width": 320,
        "height": 224,
        "content": "## ⛔ 未找到更新"
      },
      "typeVersion": 1
    },
    {
      "id": "1c01f1f9-5c06-41fd-a130-44c43f9a5c11",
      "name": "便签 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2864,
        -656
      ],
      "parameters": {
        "color": 5,
        "width": 280,
        "height": 248,
        "content": "## 🔍 获取当前信息"
      },
      "typeVersion": 1
    },
    {
      "id": "09ef5f83-d20d-489f-9199-aa1ce267427b",
      "name": "便签 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2528,
        -144
      ],
      "parameters": {
        "color": 6,
        "width": 280,
        "height": 236,
        "content": "## 🔎 检查远程摘要"
      },
      "typeVersion": 1
    },
    {
      "id": "0aaada39-31ce-49b8-8526-b22264de5092",
      "name": "获取当前 n8n 版本",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -2896,
        -368
      ],
      "parameters": {
        "cwd": "/root",
        "command": "=sh -c \"docker exec n8n-docker-caddy-n8n-1 n8n --version\""
      },
      "credentials": {
        "sshPassword": {
          "id": "09btBw3BAMtH8hXO",
          "name": "SSH Password account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9982be9b-af55-4364-a29a-d70dca2af86e",
      "name": "便利贴 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1888,
        -64
      ],
      "parameters": {
        "color": 3,
        "width": 320,
        "height": 232,
        "content": "## 📧 批准请求"
      },
      "typeVersion": 1
    },
    {
      "id": "4cf50320-6d4a-4af1-ac91-941f8f2c7851",
      "name": "便签 - 已拒绝1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        0
      ],
      "parameters": {
        "color": 4,
        "width": 280,
        "height": 248,
        "content": "## 🛑 更新已拒绝"
      },
      "typeVersion": 1
    },
    {
      "id": "69673ede-0abc-43ec-86ea-5ae72a6289d2",
      "name": "便利贴 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4080,
        -160
      ],
      "parameters": {
        "color": 2,
        "width": 496,
        "height": 408,
        "content": "## 📊 工作流摘要"
      },
      "typeVersion": 1
    },
    {
      "id": "b1613e0c-a14f-4903-96c3-dedd46423a25",
      "name": "设置要求",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4080,
        -928
      ],
      "parameters": {
        "width": 500,
        "height": 704,
        "content": "## 🧩 设置要求"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "If Approved": {
      "main": [
        [
          {
            "node": "Check Existence of Update Script",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Do Nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If No Changes": {
      "main": [
        [
          {
            "node": "No Updates",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Ask For Approval to Update",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If File Exists": {
      "main": [
        [
          {
            "node": "Execute Update Script",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create Update Script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Get Current n8n Version",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Update Data": {
      "main": [
        [
          {
            "node": "If No Changes",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Update Script": {
      "main": [
        [
          {
            "node": "Execute Update Script",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Local Image Digest": {
      "main": [
        [
          {
            "node": "Get Remote Image Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Current n8n Version": {
      "main": [
        [
          {
            "node": "Get Local Image Digest",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Remote Image Digest": {
      "main": [
        [
          {
            "node": "Prepare Update Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ask For Approval to Update": {
      "main": [
        [
          {
            "node": "If Approved",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Existence of Update Script": {
      "main": [
        [
          {
            "node": "If File Exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级 - 开发运维

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量27
分类1
节点类型8
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

外部链接
在 n8n.io 查看

分享此工作流