{
  "name": "Self update Docker-based n8n with email approval and SSH",
  "nodes": [
    {
      "id": "6486fadd-3584-4544-9a02-57ede53e836b",
      "name": "Sticky Note 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3456,
        -448
      ],
      "parameters": {
        "width": 280,
        "height": 288,
        "content": "## 🚀 WORKFLOW START\n\n**Triggers:**\n- Manual execution (test runs)\n- Automated every 3 days at 4 PM UTC\n\nThis workflow checks for n8n updates and sends an approval email, to automatically update the n8"
      }
    },
    {
      "id": "683461fc-856d-41e8-9d49-9b725fa3a2fa",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -3120,
        -368
      ]
    },
    {
      "id": "ab507d4a-1a4c-49de-9b32-07f60969b0e7",
      "name": "If No Changes",
      "type": "n8n-nodes-base.if",
      "position": [
        -2000,
        -368
      ]
    },
    {
      "id": "bcdcdc19-e21c-48fb-80bb-014144c6fa6a",
      "name": "Check Existence of Update Script",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -1328,
        -384
      ]
    },
    {
      "id": "a9cbbad8-5f2f-411f-bc4a-62230e93c0e2",
      "name": "If File Exists",
      "type": "n8n-nodes-base.if",
      "position": [
        -1104,
        -384
      ]
    },
    {
      "id": "ba972070-a78a-4982-975f-7219f26571e3",
      "name": "Create Update Script",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -880,
        -304
      ]
    },
    {
      "id": "12f9fcab-8bcb-4bea-8e66-69f5227fb7bf",
      "name": "If Approved",
      "type": "n8n-nodes-base.if",
      "position": [
        -1552,
        -272
      ]
    },
    {
      "id": "f3a6c807-0f12-45b6-bed7-ce4cbda4e42b",
      "name": "No Updates",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1776,
        -464
      ]
    },
    {
      "id": "3a90a6d9-b1b1-4f9b-8194-676dccbdb5a5",
      "name": "Do Nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1328,
        -160
      ]
    },
    {
      "id": "c1dbc70c-db44-4f5c-9854-64d34d9f114f",
      "name": "Ask For Approval to Update",
      "type": "n8n-nodes-base.emailSend",
      "position": [
        -1776,
        -272
      ]
    },
    {
      "id": "0829b238-0c14-4be8-bbf1-edaa63016b51",
      "name": "Sticky Note - Auto Update",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -112
      ],
      "parameters": {
        "width": 320,
        "height": 432,
        "content": "## 🔧 AUTOMATED UPDATE PROCESS\n\n**Three-step update execution:**\n\n1. **Check Script**: Verify if update script exists\n2. **Create Script** (if needed): Generate update script with:\n   - 30-second delay"
      }
    },
    {
      "id": "c68450b6-ff97-4be4-932f-42dbabdab811",
      "name": "Sticky Note - Script Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -672
      ],
      "parameters": {
        "width": 280,
        "height": 248,
        "content": "## 🎯 SCRIPT LOGIC\n\n**Optimizes script creation:**\n\n- If script exists → Use it directly\n- If script missing → Create new one\n\nPrevents unnecessary file operations and ensures idempotency."
      }
    },
    {
      "id": "277ab82a-701a-4edc-8def-1dab9165ebe2",
      "name": "Sticky Note - Final Execution",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        -752
      ],
      "parameters": {
        "width": 320,
        "height": 328,
        "content": "## 🚀 FINAL EXECUTION\n\n**Runs in background:**\n\nExecutes `update_docker.sh` with:\n- `nohup`: Runs independently of this session\n- `> update.log`: Logs output for debugging\n- `2>&1`: Captures both stdou"
      }
    },
    {
      "id": "5a44fe76-5ca3-4477-9f5d-486c8abec4ab",
      "name": "Execute Update Script",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -656,
        -400
      ]
    },
    {
      "id": "9a65a79e-eb2e-4ad2-8920-fe6a4a8053c6",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3536,
        -928
      ],
      "parameters": {
        "width": 3104,
        "height": 1520,
        "content": "# n8n-Self-Updater"
      }
    },
    {
      "id": "9b195a5d-3057-4690-9a7f-63947349df7b",
      "name": "Get Local Image Digest",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -2672,
        -368
      ]
    },
    {
      "id": "9f46efa6-bfa4-43cc-bc8b-50f4789bfc3f",
      "name": "Get Remote Image Digest",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -2448,
        -368
      ]
    },
    {
      "id": "b06e54b7-3760-46b6-b35b-95f74ea19ada",
      "name": "Sticky Note 9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2224,
        -672
      ],
      "parameters": {
        "width": 320,
        "height": 264,
        "content": "## 🔀 UPDATE CHECK\n\n**Checks if update exists:**\n\nCompares local vs remote digest:\n- If digests match → No update (top path)\n- If digests differ → Update available (bottom path)\n\n**Prevents unnecessary"
      }
    },
    {
      "id": "ef630305-91e7-4d78-9a8d-a2729063ddb0",
      "name": "Prepare Update Data",
      "type": "n8n-nodes-base.set",
      "position": [
        -2224,
        -368
      ]
    },
    {
      "id": "71409d64-8391-4f08-8359-223728303c20",
      "name": "Sticky Note ",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        -736
      ],
      "parameters": {
        "width": 320,
        "height": 224,
        "content": "## ⛔ NO UPDATES FOUND\n\nWorkflow ends when:\n- Local and remote digests match\n- Already running latest version\n\n**No unnecessary emails!**\n\nWorkflow completes silently."
      }
    },
    {
      "id": "1c01f1f9-5c06-41fd-a130-44c43f9a5c11",
      "name": "Sticky Note 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2864,
        -656
      ],
      "parameters": {
        "width": 280,
        "height": 248,
        "content": "## 🔍 GET CURRENT INFO\n\nRetrieves:\n1. Current n8n version\n2. Local image digest (RepoDigest)\n\nThis tells us what we're currently running."
      }
    },
    {
      "id": "09ef5f83-d20d-489f-9199-aa1ce267427b",
      "name": "Sticky Note 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2528,
        -144
      ],
      "parameters": {
        "width": 280,
        "height": 236,
        "content": "## 🔎 CHECK REMOTE DIGEST\n\nQueries Docker Hub registry to get:\n- Remote image digest for :latest tag\n- WITHOUT pulling the image!\n\nUses Docker Registry HTTP API v2."
      }
    },
    {
      "id": "0aaada39-31ce-49b8-8526-b22264de5092",
      "name": "Get Current n8n Version",
      "type": "n8n-nodes-base.ssh",
      "position": [
        -2896,
        -368
      ]
    },
    {
      "id": "9982be9b-af55-4364-a29a-d70dca2af86e",
      "name": "Sticky Note 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1888,
        -64
      ],
      "parameters": {
        "width": 320,
        "height": 232,
        "content": "## 📧 APPROVAL REQUEST\n\nSends email with:\n- Current version\n- Digest comparison\n- **Approve/Disapprove buttons**\n\nn8n stays exactly as-is until you click APPROVE!"
      }
    },
    {
      "id": "4cf50320-6d4a-4af1-ac91-941f8f2c7851",
      "name": "Sticky Note - Declined1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        0
      ],
      "parameters": {
        "width": 280,
        "height": 248,
        "content": "## 🛑 UPDATE DECLINED\n\nWorkflow ends when:\n- User clicks **Decline**\n- Update will wait for next check or manual execution\n\n**Manual option always available!**"
      }
    },
    {
      "id": "69673ede-0abc-43ec-86ea-5ae72a6289d2",
      "name": "Sticky Note 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4080,
        -160
      ],
      "parameters": {
        "width": 496,
        "height": 408,
        "content": "## 📊 WORKFLOW SUMMARY\n\n**Flow:**\n1. Get current version + local digest\n2. Get remote digest from Docker Hub\n3. Compare digests\n4. If different → Request approval with version info\n5. If approved → Pul"
      }
    },
    {
      "id": "b1613e0c-a14f-4903-96c3-dedd46423a25",
      "name": "Setup Requirements",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4080,
        -928
      ],
      "parameters": {
        "width": 500,
        "height": 704,
        "content": "## 🧩 SETUP REQUIREMENTS\n\n**1️⃣ SSH Credentials**\n- Go to *Credentials → New → SSH Password*\n- Enter:\n  - Host: your VPS IP (e.g., 165.22.xx.xx)\n  - Port: 22\n  - Username: root / ubuntu\n  - Password or"
      }
    }
  ],
  "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
          }
        ]
      ]
    }
  }
}