{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "aa223d2f-8f6d-44de-9737-4a6f05a4e21c",
      "name": "Sticky \u2022 Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -288,
        1184
      ],
      "parameters": {
        "width": 580,
        "height": 740,
        "content": "## n8n Auto-Updater via Coolify \ud83d\udd04\n\n### How it works\nThis workflow automatically checks whether your self-hosted n8n instance is outdated and triggers a redeployment via Coolify \u2014 no manual intervention needed.\n\n1. A weekly **Schedule** triggers the workflow.\n2. The **n8n Audit** node runs a security audit on your instance and checks for outdated versions.\n3. An **IF** node evaluates whether the audit flagged the instance as outdated.\n4. If outdated: the latest stable version is fetched from **GitHub**, then **Coolify** is called to restart the service with the new image.\n5. A **Mattermost** notification confirms the update.\n6. If up to date: the workflow stops silently.\n\n### Setup\n1. **n8n API Key** \u2014 Go to *Settings \u2192 API \u2192 Generate Key* and create an `n8n API` credential. Assign it to the **GET audit** node.\n2. **Coolify** \u2014 Generate an API token in Coolify (*Settings \u2192 API Tokens*). Create an `HTTP Bearer Auth` credential and assign it to the **CALL Coolify** node. Update the URL with your domain and service UUID.\n3. **Mattermost (optional)** \u2014 Replace the URL, Bearer token, and channel ID in the **post to channel** node. Or delete this node if not needed.\n4. **Schedule** \u2014 Default is weekly on Monday at 01:00. Adjust as needed."
      },
      "typeVersion": 1
    },
    {
      "id": "81c3e0a7-5c89-44df-8c97-99914b902df9",
      "name": "Sticky \u2022 Audit",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        592,
        1264
      ],
      "parameters": {
        "color": 7,
        "width": 468,
        "height": 476,
        "content": "## 1 \u00b7 Check instance version\nRuns a security audit on your n8n instance. Requires an `n8n API` credential (*Settings \u2192 API \u2192 Generate Key*)."
      },
      "typeVersion": 1
    },
    {
      "id": "9c301c57-78d0-423d-ae6b-8bcd16838b0d",
      "name": "Sticky \u2022 IF",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1104,
        1264
      ],
      "parameters": {
        "color": 7,
        "width": 352,
        "height": 476,
        "content": "## 2 \u00b7 Is it outdated?\nChecks if the audit result contains a section with `title === \"Outdated instance\"`.\n- **True** \u2192 proceed with update\n- **False** \u2192 stop"
      },
      "typeVersion": 1
    },
    {
      "id": "18b668df-fbe5-49d2-bbe2-b98cc6395836",
      "name": "Sticky \u2022 GitHub",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1488,
        1264
      ],
      "parameters": {
        "color": 7,
        "width": 404,
        "height": 476,
        "content": "## 3 \u00b7 Get latest version\nFetches the latest stable n8n release from the GitHub API. No authentication needed."
      },
      "typeVersion": 1
    },
    {
      "id": "b6631f38-5591-466e-90d3-eda8dfafb66e",
      "name": "Sticky \u2022 Deploy",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        1264
      ],
      "parameters": {
        "color": 7,
        "width": 508,
        "height": 476,
        "content": "## 4 \u00b7 Deploy via Coolify\nRestarts the n8n service with the latest image. Requires an `HTTP Bearer Auth` credential with your Coolify API token.\n\nReplace `<your-coolify-domain>` and `<APP_UUID>` in the node URL. Find the UUID in the Coolify service URL."
      },
      "typeVersion": 1
    },
    {
      "id": "91068e2a-de4c-4862-989d-63ae3a7b4a98",
      "name": "Sticky \u2022 Notify",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2512,
        1264
      ],
      "parameters": {
        "color": 7,
        "width": 316,
        "height": 476,
        "content": "## 5 \u00b7 Notify via Mattermost\nPosts a confirmation message to a channel. Replace the URL, Bearer token and channel ID \u2014 or delete this node if you use a different notification tool."
      },
      "typeVersion": 1
    },
    {
      "id": "e2db26e0-cfcd-4933-8ebd-60604598ff2f",
      "name": "Run weekly update check",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        352,
        1568
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "weeks",
              "triggerAtHour": 1
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "b9027840-c6ca-4d1f-a5ba-305b7baad24a",
      "name": "Already up to date",
      "type": "n8n-nodes-base.noOp",
      "position": [
        1632,
        1760
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "038bf3a1-7479-4057-99f6-468b93eb2c05",
      "name": "GET audit",
      "type": "n8n-nodes-base.n8n",
      "position": [
        752,
        1568
      ],
      "parameters": {
        "resource": "audit",
        "operation": "generate",
        "requestOptions": {},
        "additionalOptions": {
          "categories": [
            "instance"
          ]
        }
      },
      "credentials": {
        "n8nApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "581932b7-8a3a-490e-864e-775dca28a9dc",
      "name": "GET latest n8n release",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1632,
        1552
      ],
      "parameters": {
        "url": "https://api.github.com/repos/n8n-io/n8n/releases/latest",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "2def0d0c-357c-4b1c-bd8e-869d7ea4593f",
      "name": "CALL Coolify to update image",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2160,
        1552
      ],
      "parameters": {
        "url": "https://<your-coolify-domain>/api/v1/services/<APP_UUID>/restart?latest=true",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "152c586c-d025-460a-81ab-71566f8e2bc1",
      "name": "post to channel",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2624,
        1552
      ],
      "parameters": {
        "url": "https://<your-mattermost-domain>/api/v4/posts",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"channel_id\": \"<CHANNEL_ID>\",\n  \"message\": \"n8n update \u2705 Successfully deployed latest version.\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Accept",
              "value": "application/json"
            },
            {
              "name": "Authorization",
              "value": "Bearer <MATTERMOST_TOKEN>"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "53f18e19-83be-4a5e-a61a-1639f3552bad",
      "name": "Is instance up to date?",
      "type": "n8n-nodes-base.if",
      "position": [
        1232,
        1568
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "36e8757d-8f3e-49b9-86f2-cd04ed499ee1",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json[\"Instance Risk Report\"].sections.find(s => s.title === \"Outdated instance\") ? \"yes\" : \"no\" }}",
              "rightValue": "=yes"
            }
          ]
        },
        "looseTypeValidation": true
      },
      "typeVersion": 2.3
    }
  ],
  "connections": {
    "GET audit": {
      "main": [
        [
          {
            "node": "Is instance up to date?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET latest n8n release": {
      "main": [
        [
          {
            "node": "CALL Coolify to update image",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is instance up to date?": {
      "main": [
        [
          {
            "node": "GET latest n8n release",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Already up to date",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Run weekly update check": {
      "main": [
        [
          {
            "node": "GET audit",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CALL Coolify to update image": {
      "main": [
        [
          {
            "node": "post to channel",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}