Accueil » 📂N8N » 🇫🇷 Sauvegarder tes Workflows N8N sur GitHub Automatiquement (2026).
Tutoriel vidéo montrant Sauvegarder tes Workflows N8N sur GitHub Automatiquement

Sur une instance N8N self-hosted, les exécutions de workflow ne sont conservées qu’une seule journée. Cette limitation peut rapidement devenir problématique lorsque vous souhaitez retrouver une version antérieure de votre automatisation. Dans cet article, découvrez comment mettre en place un système de sauvegarde automatique de vos workflows sur GitHub, vous permettant de versionner et récupérer n’importe quelle version de vos créations.

Pourquoi sauvegarder vos workflows N8N sur GitHub

La limitation d’historique de N8N self-hosted représente un véritable défi pour les utilisateurs qui travaillent sur des automatisations complexes. Lorsque vous modifiez un workflow et que quelque chose ne fonctionne plus comme prévu, il devient impossible de revenir en arrière après 24 heures. GitHub offre une solution élégante à ce problème en proposant un système de versioning complet et gratuit.

En stockant vos workflows sous forme de fichiers JSON sur GitHub, vous bénéficiez de plusieurs avantages majeurs. Vous pouvez consulter le code de n’importe quel workflow à un instant donné, naviguer dans l’historique des modifications et restaurer une version antérieure en quelques clics. Cette approche transforme GitHub en véritable machine à remonter le temps pour vos automatisations.

Prérequis pour la mise en place

Avant de configurer la sauvegarde automatique, vous devez disposer de quelques éléments essentiels. La connexion entre N8N et GitHub constitue la première étape indispensable. Une fois cette liaison établie, vous pourrez créer un dépôt (repository) dédié au stockage de vos workflows.

Architecture du workflow de sauvegarde

Le système de sauvegarde repose sur deux composants principaux qui fonctionnent en tandem. Le premier élément consiste en deux nœuds que vous intégrez dans chacun de vos workflows. Ces nœuds se déclenchent automatiquement à chaque publication et appellent un sous-workflow dédié à la sauvegarde.

Le déclencheur à la publication

Lorsque vous publiez un workflow, les nœuds de sauvegarde s’activent automatiquement. Ils récupèrent le code JSON complet de votre workflow via l’API N8N et transmettent ces données au sous-workflow de sauvegarde. Vous pouvez même ajouter un message de commit personnalisé pour identifier facilement chaque modification dans l’historique GitHub.

Le sous-workflow de sauvegarde

Ce workflow central gère toute la logique d’envoi vers GitHub. Il reçoit le JSON du workflow parent, interroge l’API N8N pour récupérer les données complètes, puis envoie le fichier vers votre repository. La configuration nécessite de renseigner deux paramètres essentiels : le owner (votre nom d’utilisateur ou organisation GitHub) et le repository de destination.

Gestion intelligente des fichiers

Le workflow de sauvegarde intègre une logique de gestion des erreurs particulièrement astucieuse. GitHub génère une erreur lorsque vous tentez de créer un fichier qui existe déjà. Cette contrainte technique est exploitée pour distinguer automatiquement les nouvelles créations des mises à jour.

Lorsque le nœud de création détecte une erreur, le système comprend que le fichier existe déjà. Il bascule alors vers un processus de modification : récupération du fichier existant, préparation d’une requête HTTP adaptée, puis mise à jour avec le nouveau contenu JSON. Cette approche garantit que chaque sauvegarde s’effectue correctement, qu’il s’agisse d’un nouveau workflow ou d’une modification.

Exploiter l’historique GitHub

Une fois vos workflows sauvegardés sur GitHub, vous disposez d’un historique complet de toutes les modifications. Chaque commit représente une version de votre workflow que vous pouvez consulter, comparer ou restaurer à tout moment.

Pour restaurer une version antérieure, il vous suffit de naviguer dans l’historique du fichier concerné, copier le code JSON de la version souhaitée, puis le coller dans un nouveau workflow N8N. Cette manipulation simple vous permet de récupérer n’importe quelle version de vos automatisations, même plusieurs mois après leur création.

Configuration du repository et owner

La configuration du sous-workflow nécessite de renseigner correctement deux paramètres dans le nœud GitHub. Le champ owner correspond à votre identifiant GitHub personnel ou au nom de votre organisation si vous utilisez cette fonctionnalité. Le repository désigne le dépôt spécifique où seront stockés vos fichiers JSON.

Une fois ces paramètres configurés, le système fonctionne de manière totalement autonome. Chaque publication de workflow déclenche automatiquement la sauvegarde, sans intervention manuelle de votre part. Vous pouvez ainsi vous concentrer sur la création de vos automatisations en sachant que chaque version est précieusement conservée.

Quotien Intellectuel pour illustrer l'apprentissage du noeud N8N

Comment le workflow de sauvegarde distingue-t-il une création d'une mise à jour de fichier sur GitHub ?

Conclusion

La sauvegarde automatique de vos workflows N8N sur GitHub représente une solution gratuite et efficace pour contourner la limitation d’historique des instances self-hosted. Ce système vous permet de versionner toutes vos automatisations et de restaurer n’importe quelle version en quelques clics.

N’oubliez pas de configurer correctement les paramètres owner et repository dans votre sous-workflow, et d’intégrer les nœuds de déclenchement dans chaque workflow que vous souhaitez sauvegarder.

Pour aller plus loin, explorez nos autres ressources N8N ou contactez notre équipe pour mettre en place des stratégies de backup avancées pour vos automatisations.

{
  "nodes": [
    {
      "parameters": {
        "content": "## 🚀 Déclencheurs\n\nTrigger n8n : Se déclenche automatiquement lorsqu'un workflow est modifié ou activé.\n\nPublier (Execute Workflow Trigger) : Permet une exécution manuelle ou un appel depuis un autre workflow.\n\nLes deux points d'entrée alimentent le même flux de sauvegarde.",
        "height": 800,
        "width": 320,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        288
      ],
      "typeVersion": 1,
      "id": "c068b9ec-060f-471d-86f9-06e36b5dd2fc",
      "name": "Sticky Note3"
    },
    {
      "parameters": {
        "content": "## 🔑 Configuration requise\n\n1. Remplacez l'URL par celle de votre instance n8n :\n   `https://VOTRE-INSTANCE.com/api/v1/workflows/`\n\n2. Créez une clé API n8n :\n   Paramètres → API → Créer une clé API\n\n3. Ajoutez les identifiants : API n8n (type Clé API)",
        "height": 800,
        "width": 310,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        608,
        288
      ],
      "typeVersion": 1,
      "id": "bc5045fd-4e3f-4eae-813f-a68547803f88",
      "name": "Sticky Note4"
    },
    {
      "parameters": {
        "content": "## 📁 GitHub Backup\n\n**Create File**: First attempt — creates the JSON file if it doesn't exist.\n\n**Edit File**: Fallback — if file exists, updates it instead.\n\n➡️ Update these fields:\n- Owner: your GitHub username or org\n- Repository: your backup repo name\n\nCommit message uses your workflow version description automatically. ",
        "height": 800,
        "width": 1030,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        928,
        288
      ],
      "typeVersion": 1,
      "id": "4b4b1e46-f5e4-42e1-8b2b-ae5abe99fe52",
      "name": "Sticky Note5"
    },
    {
      "parameters": {
        "events": [
          "update",
          "activate"
        ]
      },
      "type": "n8n-nodes-base.n8nTrigger",
      "typeVersion": 1,
      "position": [
        384,
        624
      ],
      "id": "16a9bebc-597b-4ddc-9300-83e813c9da3e",
      "name": "N8N TRIGGER"
    },
    {
      "parameters": {
        "inputSource": "passthrough"
      },
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "typeVersion": 1.1,
      "position": [
        384,
        864
      ],
      "id": "5ccc62cd-0b4c-4cfa-af98-b09c679a8246",
      "name": "PUBLISH"
    },
    {
      "parameters": {
        "operation": "get",
        "workflowId": {
          "__rl": true,
          "value": "={{$json.workflow_id}}",
          "mode": "id"
        },
        "requestOptions": {}
      },
      "type": "n8n-nodes-base.n8n",
      "typeVersion": 1,
      "position": [
        800,
        752
      ],
      "id": "2f746366-2de8-4386-a153-52510fa1f056",
      "name": "GET A WORKFLOW",
      "notesInFlow": true,
      "credentials": {
        "n8nApi": {
          "id": "4Muq5STAvFEAfES9",
          "name": "N8N Ocade Fusion"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "owner": {
          "__rl": true,
          "value": "={{ $('VARS').item.json.OWNER_GITHUB }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('VARS').item.json['REPOSITORY GITHUB'] }}",
          "mode": "name"
        },
        "filePath": "={{ $json.id }}.json",
        "fileContent": "={{ JSON.stringify($json, null, 2) }}",
        "commitMessage": "={{ $json.activeVersion.description }} \n=============================\n{{ $json.activeVersion.name }} | {{ $json.activeVersion.authors }}\n\n"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        992,
        752
      ],
      "id": "c81dfec5-e0fb-4236-9540-9eaec0d9e305",
      "name": "CREATE FILE",
      "webhookId": "82a62f5d-61d6-46e7-b655-44f5d9121e79",
      "notesInFlow": true,
      "credentials": {
        "githubOAuth2Api": {
          "id": "YJEsHavOHt0iR1QN",
          "name": "GitHub valentin.charrier&hotmail.fr"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "get",
        "owner": {
          "__rl": true,
          "value": "={{ $('VARS').item.json.OWNER_GITHUB }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('VARS').item.json['REPOSITORY GITHUB'] }}",
          "mode": "name"
        },
        "filePath": "={{ $json.id }}.json",
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        1216,
        768
      ],
      "id": "2611e24f-9f33-4af5-8391-f6146f08f20b",
      "name": "Get a file",
      "webhookId": "8fb9c30d-84f9-4fd4-ad1e-3c960f721d39",
      "notesInFlow": true,
      "credentials": {
        "githubOAuth2Api": {
          "id": "YJEsHavOHt0iR1QN",
          "name": "GitHub valentin.charrier&hotmail.fr"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const workflow = $('GET A WORKFLOW').item.json;\nconst sha = $('Get a file').item.json.sha;\n\nreturn [{\n  json: {\n    workflow_id: workflow.id,\n    content: btoa(unescape(encodeURIComponent(JSON.stringify(workflow, null, 2)))),\n    sha: sha,\n    message: (workflow.activeVersion?.description || 'Update') + '\\n=============================\\n' + (workflow.activeVersion?.name || '') + ' | ' + (workflow.activeVersion?.authors || '')\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        1424,
        768
      ],
      "id": "c7c0afdf-1b91-4de5-91db-bec58a844641",
      "name": "Preprare HTTP Request"
    },
    {
      "parameters": {
        "method": "PUT",
        "url": "=https://api.github.com/repos/{{ $('VARS').item.json.OWNER_GITHUB }}/{{ $('VARS').item.json['REPOSITORY GITHUB'] }}/contents/{{ $json.workflow_id }}.json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubOAuth2Api",
        "sendBody": true,
        "bodyParameters": {
          "parameters": [
            {
              "name": "message",
              "value": "={{ $json.message }}"
            },
            {
              "name": "content",
              "value": "={{ $json.content }}"
            },
            {
              "name": "sha",
              "value": "={{ $json.sha }}"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.3,
      "position": [
        1648,
        768
      ],
      "id": "33f1bb84-a210-48ac-ad92-26ab81e744c6",
      "name": "Execute HTTP Request",
      "notesInFlow": true,
      "credentials": {
        "githubOAuth2Api": {
          "id": "YJEsHavOHt0iR1QN",
          "name": "GitHub valentin.charrier&hotmail.fr"
        }
      }
    },
    {
      "parameters": {
        "workflowId": {
          "__rl": true,
          "value": "g8S7y933beqthWWz",
          "mode": "list",
          "cachedResultUrl": "/workflow/g8S7y933beqthWWz",
          "cachedResultName": "VERSIONNING"
        },
        "workflowInputs": {
          "mappingMode": "defineBelow",
          "value": {},
          "matchingColumns": [],
          "schema": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        },
        "options": {}
      },
      "type": "n8n-nodes-base.executeWorkflow",
      "typeVersion": 1.3,
      "position": [
        592,
        -96
      ],
      "id": "ef2e6c68-b950-4a98-abc9-918014f665ac",
      "name": "VERSIONNING",
      "notesInFlow": true,
      "disabled": true
    },
    {
      "parameters": {
        "events": [
          "update",
          "activate"
        ]
      },
      "type": "n8n-nodes-base.n8nTrigger",
      "typeVersion": 1,
      "position": [
        368,
        -96
      ],
      "id": "4b6fb1c0-f991-40a8-a6b2-03be4b9605b0",
      "name": "N8N TRIGGER1",
      "disabled": true
    },
    {
      "parameters": {
        "content": "##  NOEUDS A METTRE DANS D'AUTRES WORKFLOW A VERSIONNER.",
        "height": 400,
        "width": 544
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        272,
        -272
      ],
      "typeVersion": 1,
      "id": "ca84f28d-efcb-4495-873e-c20e7e1b1ab9",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "8b3bb531-18c6-4f8d-a5e4-503cd00d7836",
              "name": "OWNER_GITHUB",
              "value": "VOTRE OWNER GITHUB ICI",
              "type": "string"
            },
            {
              "id": "fb9730e9-e63e-41aa-b615-5a2896d321c9",
              "name": "REPOSITORY GITHUB",
              "value": "VOTRE REPOSITORY GITHUB ICI",
              "type": "string"
            }
          ]
        },
        "includeOtherFields": true,
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        640,
        752
      ],
      "id": "99f9f061-479d-448c-96c6-45b4c6902246",
      "name": "VARS",
      "notesInFlow": true
    }
  ],
  "connections": {
    "N8N TRIGGER": {
      "main": [
        [
          {
            "node": "VARS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "PUBLISH": {
      "main": [
        [
          {
            "node": "VARS",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET A WORKFLOW": {
      "main": [
        [
          {
            "node": "CREATE FILE",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "CREATE FILE": {
      "main": [
        [],
        [
          {
            "node": "Get a file",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get a file": {
      "main": [
        [
          {
            "node": "Preprare HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Preprare HTTP Request": {
      "main": [
        [
          {
            "node": "Execute HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "N8N TRIGGER1": {
      "main": [
        [
          {
            "node": "VERSIONNING",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "VARS": {
      "main": [
        [
          {
            "node": "GET A WORKFLOW",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "meta": {
    "instanceId": "9ed09ab91fbf542fcf50302dd736797c3f1ce41ba182bf3640612d82acc05052"
  }
}
Pourquoi N8N self-hosted ne conserve-t-il les exécutions qu’une journée ?

Cette limitation est liée à la gestion des ressources serveur. Conserver un historique complet des exécutions consommerait énormément d’espace de stockage. La sauvegarde sur GitHub contourne cette limitation en stockant le code JSON des workflows de manière externe.

Dois-je payer pour utiliser GitHub comme solution de backup ?

Non, GitHub propose des comptes gratuits avec des repositories publics ou privés illimités. Cette solution de sauvegarde est donc entièrement gratuite pour un usage personnel ou professionnel.

Comment restaurer un workflow depuis une version sauvegardée sur GitHub ?

Naviguez vers le fichier JSON dans votre repository GitHub, consultez l’historique pour trouver la version souhaitée, copiez le code JSON complet, puis collez-le dans un nouveau workflow N8N. Le workflow sera immédiatement reconstitué avec tous ses nœuds.

Que se passe-t-il si la sauvegarde échoue lors de la publication ?

Le workflow de sauvegarde utilise un système de gestion des erreurs. Si une erreur survient lors de la création du fichier (fichier existant), le système bascule automatiquement vers le mode modification. En cas d’erreur réseau ou d’authentification, vérifiez vos credentials GitHub dans N8N.

Puis-je utiliser cette méthode avec N8N Cloud ?

Oui, cette méthode fonctionne également avec N8N Cloud. Cependant, N8N Cloud propose déjà un historique des versions plus étendu. La sauvegarde GitHub reste utile pour disposer d’une copie externe de vos workflows.

Quelle est la différence entre owner personnel et organisation sur GitHub ?

Le owner personnel correspond à votre nom d’utilisateur GitHub individuel. Une organisation est un espace partagé permettant à plusieurs utilisateurs de collaborer sur des repositories communs. Choisissez l’organisation si vous travaillez en équipe sur vos automatisations N8N.