Automatisierung des Docker-basierten n8n-Updates mit E-Mail-Genehmigung und SSH
Experte
Dies ist ein DevOps-Bereich Automatisierungsworkflow mit 27 Nodes. Hauptsächlich werden If, Set, Ssh, EmailSend, HttpRequest und andere Nodes verwendet. Automatisierung von Docker-basierten n8n-Updates mit E-Mail-Genehmigung und SSH
Voraussetzungen
- •Möglicherweise sind Ziel-API-Anmeldedaten erforderlich
Verwendete Nodes (27)
Kategorie
Workflow-Vorschau
Visualisierung der Node-Verbindungen, mit Zoom und Pan
Workflow exportieren
Kopieren Sie die folgende JSON-Konfiguration und importieren Sie sie in n8n
{
"meta": {
"instanceId": "0cf1013c00750bfab7ca7f6a76bf0e8c2407d7a4a9a4e66c4888ec456837f043",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "6486fadd-3584-4544-9a02-57ede53e836b",
"name": "Notizzettel 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": "Zeitplan-Trigger",
"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": "Wenn keine Änderungen",
"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": "Existenz des Update-Skripts prüfen",
"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": "Wenn Datei existiert",
"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": "Update-Skript erstellen",
"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": "Wenn genehmigt",
"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": "Keine Updates",
"type": "n8n-nodes-base.noOp",
"position": [
-1776,
-464
],
"parameters": {},
"typeVersion": 1
},
{
"id": "3a90a6d9-b1b1-4f9b-8194-676dccbdb5a5",
"name": "Nichts tun",
"type": "n8n-nodes-base.noOp",
"position": [
-1328,
-160
],
"parameters": {},
"typeVersion": 1
},
{
"id": "c1dbc70c-db44-4f5c-9854-64d34d9f114f",
"name": "Genehmigung für Update anfragen",
"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": "Notizzettel - Auto-Update",
"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": "Notizzettel - Skriptlogik",
"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": "Notizzettel - Finale Ausführung",
"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": "Update-Skript ausführen",
"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": "Notizzettel",
"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": "Lokalen Image-Digest abrufen",
"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": "Remote-Image-Digest abrufen",
"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": "Notizzettel 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": "Update-Daten vorbereiten",
"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": "Notizzettel",
"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": "Notizzettel 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": "Notizzettel 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": "Aktuelle n8n-Version abrufen",
"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": "Notizzettel 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": "Notizzettel - Abgelehnt1",
"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": "Notizzettel 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": "Anforderungen einrichten",
"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
}
]
]
}
}
}Häufig gestellte Fragen
Wie verwende ich diesen Workflow?
Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.
Für welche Szenarien ist dieser Workflow geeignet?
Experte - DevOps
Ist es kostenpflichtig?
Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.
Verwandte Workflows
n8n-Update
Automatisierung von Docker-Container-Updates mit einem Genehmigungssystem per Telegram
If
Set
Ssh
+
If
Set
Ssh
27 NodesJaber Zare
DevOps
Automatisierte n8n-Workflow-Sicherung bei GitHub und Nachverfolgung von Löschvorgängen
Automatisches Backup von n8n-Workflows bei GitHub mit Tracking von Löschvorgängen
If
N8n
Set
+
If
N8n
Set
31 NodesMarcial Ambriz
DevOps
Automatische Updates für selbstgehostete Anwendungen (Coolify-Deployment)
Automatische Updates für selbstgehostete Anwendungen mit Coolify
If
Set
Merge
+
If
Set
Merge
18 NodesEdoardo Guzzi
DevOps
Bidirektionale Synchronisation von Typebot-Workflows mit GitHub unter Verwendung der Typebot-API
Bidirektionale Synchronisation von Typebot-Workflows mit GitHub unter Verwendung des Typebot-APIs
If
Set
Code
+
If
Set
Code
31 NodesMarcial Ambriz
DevOps
GitHub Synchronisations-Dashboard - V2
GitHub-Workflow-Versionskontroll-Dashboard mit Commit-Verlauf und Rollback-Funktion
If
N8n
Set
+
If
N8n
Set
94 NodesEduard
DevOps
Mit Gemini AI auf Basis von US-Repräsentantenhaus-Gesetzen wöchentlichen Tierrechts-Aktionsbrief erstellen
Wöchentliche Tierschutz-Aktions-Briefings mit Gemini AI basierend auf US-Repräsentantenhaus-Gesetzen generieren
If
Set
Html
+
If
Set
Html
26 NodesOpen Paws
Soziale Medien
Workflow-Informationen
Schwierigkeitsgrad
Experte
Anzahl der Nodes27
Kategorie1
Node-Typen8
Autor
Muhammad Anas Farooq
@anasn-farooqExterne Links
Auf n8n.io ansehen →
Diesen Workflow teilen