Automatisation de la mise à jour de n8n basé sur Docker avec l'approbation par e-mail et SSH

Avancé

Ceci est unDevOpsworkflow d'automatisation du domainecontenant 27 nœuds.Utilise principalement des nœuds comme If, Set, Ssh, EmailSend, HttpRequest. Automatisation des mises à jour de n8n basé sur Docker via l'approbation par e-mail et SSH

Prérequis
  • Peut nécessiter les informations d'identification d'authentification de l'API cible

Catégorie

Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "meta": {
    "instanceId": "0cf1013c00750bfab7ca7f6a76bf0e8c2407d7a4a9a4e66c4888ec456837f043",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "6486fadd-3584-4544-9a02-57ede53e836b",
      "name": "Note adhésive 1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3456,
        -448
      ],
      "parameters": {
        "color": 4,
        "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 n8n instance."
      },
      "typeVersion": 1
    },
    {
      "id": "683461fc-856d-41e8-9d49-9b725fa3a2fa",
      "name": "Déclencheur programmé",
      "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": "Si aucune modification",
      "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": "Vérifier l'existence du script de mise à jour",
      "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": "Si fichier existe",
      "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": "Créer le script de mise à jour",
      "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": "Si approuvé",
      "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": "Pas de mises à jour",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1776,
        -464
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "3a90a6d9-b1b1-4f9b-8194-676dccbdb5a5",
      "name": "Ne rien faire",
      "type": "n8n-nodes-base.noOp",
      "position": [
        -1328,
        -160
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "c1dbc70c-db44-4f5c-9854-64d34d9f114f",
      "name": "Demander approbation pour mise à jour",
      "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": "Note adhésive - Mise à jour auto",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        -112
      ],
      "parameters": {
        "color": 6,
        "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\n   - Navigate to docker directory\n   - Execute update commands\n3. **Execute**: Run script in background via `nohup`\n\n**The 60-second delay ensures this workflow completes before container restarts!**"
      },
      "typeVersion": 1
    },
    {
      "id": "c68450b6-ff97-4be4-932f-42dbabdab811",
      "name": "Note adhésive - Logique du script",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1392,
        -672
      ],
      "parameters": {
        "color": 7,
        "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."
      },
      "typeVersion": 1
    },
    {
      "id": "277ab82a-701a-4edc-8def-1dab9165ebe2",
      "name": "Note adhésive - Exécution finale",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -976,
        -752
      ],
      "parameters": {
        "color": 3,
        "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 stdout and stderr\n- `&`: Background execution\n\n**Workflow completes immediately, update happens 30 seconds later!**"
      },
      "typeVersion": 1
    },
    {
      "id": "5a44fe76-5ca3-4477-9f5d-486c8abec4ab",
      "name": "Exécuter le script de mise à jour",
      "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": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3536,
        -928
      ],
      "parameters": {
        "color": 5,
        "width": 3104,
        "height": 1520,
        "content": "# n8n-Self-Updater"
      },
      "typeVersion": 1
    },
    {
      "id": "9b195a5d-3057-4690-9a7f-63947349df7b",
      "name": "Obtenir l'empreinte d'image locale",
      "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": "Obtenir l'empreinte d'image distante",
      "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": "Note adhésive 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 email notifications!**"
      },
      "typeVersion": 1
    },
    {
      "id": "ef630305-91e7-4d78-9a8d-a2729063ddb0",
      "name": "Préparer les données de mise à jour",
      "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": "Note adhésive",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1840,
        -736
      ],
      "parameters": {
        "color": 4,
        "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."
      },
      "typeVersion": 1
    },
    {
      "id": "1c01f1f9-5c06-41fd-a130-44c43f9a5c11",
      "name": "Note adhésive 2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2864,
        -656
      ],
      "parameters": {
        "color": 5,
        "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."
      },
      "typeVersion": 1
    },
    {
      "id": "09ef5f83-d20d-489f-9199-aa1ce267427b",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2528,
        -144
      ],
      "parameters": {
        "color": 6,
        "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."
      },
      "typeVersion": 1
    },
    {
      "id": "0aaada39-31ce-49b8-8526-b22264de5092",
      "name": "Obtenir la version actuelle de 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": "Note adhésive 5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1888,
        -64
      ],
      "parameters": {
        "color": 3,
        "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!"
      },
      "typeVersion": 1
    },
    {
      "id": "4cf50320-6d4a-4af1-ac91-941f8f2c7851",
      "name": "Note adhésive - Refusé1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1408,
        0
      ],
      "parameters": {
        "color": 4,
        "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!**"
      },
      "typeVersion": 1
    },
    {
      "id": "69673ede-0abc-43ec-86ea-5ae72a6289d2",
      "name": "Note adhésive 6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -4080,
        -160
      ],
      "parameters": {
        "color": 2,
        "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 → Pull and restart\n6. If same → Silent skip\n\n**Benefits:**\n- Bandwidth efficient\n- Clear version comparison\n- Manual approval control\n- No spam when no updates"
      },
      "typeVersion": 1
    },
    {
      "id": "b1613e0c-a14f-4903-96c3-dedd46423a25",
      "name": "Configurer les prérequis",
      "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 Private Key\n\n\n**2️⃣ SMTP Credentials (Email)**\n- Go to *Credentials → New → SMTP*\n- Fill in:\n  - Host: smtp.yourprovider.com\n  - Port: 465 (SSL) / 587 (TLS)\n  - User: your email\n  - Password: email password or app password\n\n\n**3️⃣ Docker Server Setup**\n- Ensure Docker + docker-compose are installed\n- n8n is deployed via docker-compose (e.g., /opt/n8n-docker-caddy)\n\n\n**4️⃣ Workflow Setup**\n- Import the JSON workflow\n- Edit Email Node → update `fromEmail` & `toEmail`\n- Connect correct SSH + SMTP credentials\n- Enable Schedule Trigger (optional)\n\n✅ Once complete, test manually before activating auto checks."
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "12f9fcab-8bcb-4bea-8e66-69f5227fb7bf": {
      "main": [
        [
          {
            "node": "bcdcdc19-e21c-48fb-80bb-014144c6fa6a",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "3a90a6d9-b1b1-4f9b-8194-676dccbdb5a5",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ab507d4a-1a4c-49de-9b32-07f60969b0e7": {
      "main": [
        [
          {
            "node": "f3a6c807-0f12-45b6-bed7-ce4cbda4e42b",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "c1dbc70c-db44-4f5c-9854-64d34d9f114f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a9cbbad8-5f2f-411f-bc4a-62230e93c0e2": {
      "main": [
        [
          {
            "node": "5a44fe76-5ca3-4477-9f5d-486c8abec4ab",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ba972070-a78a-4982-975f-7219f26571e3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "683461fc-856d-41e8-9d49-9b725fa3a2fa": {
      "main": [
        [
          {
            "node": "0aaada39-31ce-49b8-8526-b22264de5092",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ef630305-91e7-4d78-9a8d-a2729063ddb0": {
      "main": [
        [
          {
            "node": "ab507d4a-1a4c-49de-9b32-07f60969b0e7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ba972070-a78a-4982-975f-7219f26571e3": {
      "main": [
        [
          {
            "node": "5a44fe76-5ca3-4477-9f5d-486c8abec4ab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9b195a5d-3057-4690-9a7f-63947349df7b": {
      "main": [
        [
          {
            "node": "9f46efa6-bfa4-43cc-bc8b-50f4789bfc3f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "0aaada39-31ce-49b8-8526-b22264de5092": {
      "main": [
        [
          {
            "node": "9b195a5d-3057-4690-9a7f-63947349df7b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "9f46efa6-bfa4-43cc-bc8b-50f4789bfc3f": {
      "main": [
        [
          {
            "node": "ef630305-91e7-4d78-9a8d-a2729063ddb0",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c1dbc70c-db44-4f5c-9854-64d34d9f114f": {
      "main": [
        [
          {
            "node": "12f9fcab-8bcb-4bea-8e66-69f5227fb7bf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bcdcdc19-e21c-48fb-80bb-014144c6fa6a": {
      "main": [
        [
          {
            "node": "a9cbbad8-5f2f-411f-bc4a-62230e93c0e2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - DevOps

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds27
Catégorie1
Types de nœuds8
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34