Migrer n8n de SQLite vers PostgreSQL sur DigitalOcean
Migrez une instance n8n auto-hébergée de SQLite vers PostgreSQL géré par DigitalOcean avec une bascule planifiée, des accès limités et un test de reprise.
Décider si cette migration est nécessaire
SQLite convient à une installation n8n peu sollicitée. Passez à PostgreSQL quand plusieurs personnes administrent les workflows, que l’historique d’exécution compte ou qu’une panne a un coût réel. Il place les données n8n hors du Droplet. Il ne rend pas un workflow risqué plus sûr et ne remplace pas un plan de reprise.
Une base PostgreSQL vide peut laisser n8n démarrer sans vos workflows, identifiants ni historiques. Prévoyez une fenêtre de maintenance, gardez la clé de chiffrement n8n et ne touchez pas aux données SQLite avant l’acceptation de la bascule.
Vous avez besoin d’un accès administrateur DigitalOcean, d’un accès SSH au Droplet Linux qui exécute n8n et d’un endroit séparé pour tester une restauration. Un Droplet est le serveur virtuel. Une source approuvée est une règle réseau qui autorise un serveur ou une adresse d’administration à se connecter à la base.
- Une archive de récupération testée et la clé de chiffrement n8n correspondante.
- Une fenêtre de maintenance qui suspend les webhooks entrants et les tâches planifiées de production.
- Une personne désignée pour vérifier les identifiants et approuver la bascule finale.
Créer un point de récupération avant de modifier la base
Commencez avec une sauvegarde que vous savez restaurer. Notez la version n8n, l’étiquette d’image Compose, l’URL publique, l’emplacement de la clé de chiffrement, le nom du volume et l’horodatage de la dernière sauvegarde. Lisez une archive chiffrée dans l’environnement de récupération isolé du guide n8n privé. Gardez la même version n8n pour la migration. Ne combinez pas ce changement avec une mise à niveau n8n.
Si vous utilisez l’application n8n Marketplace du guide de récupération compagnon, le dossier de déploiement est généralement /opt/n8n-docker-caddy. Sinon, trouvez le fichier Compose avant de modifier quoi que ce soit. Le nom de service renvoyé par docker compose config --services remplace n8n dans les commandes suivantes.
Ouvrez un shell root sur le Droplet avec l'action ci-dessous avant les commandes. Conservez ce terminal pendant la migration et remplacez N8N_APP_DIR si votre chemin diffère.
sudo -iAvant de continuer : Examinez les chemins retournés avant de changer de dossier. La commande liste seulement des fichiers Compose possibles.
sudo find /opt /srv /home -maxdepth 4 -type f \( -name compose.yml -o -name docker-compose.yml \) -print
N8N_APP_DIR=/opt/n8n-docker-caddy
cd "$N8N_APP_DIR"
sudo docker compose config --servicesCréer une base PostgreSQL avec des accès limités
Créez d’abord le cluster. Ne modifiez pas n8n à ce stade. Ce guide utilise un cluster PostgreSQL Standard Edition, car ses paramètres de connexion comprennent un certificat CA que n8n peut monter. Si vous choisissez Advanced Edition, arrêtez-vous ici et adaptez TLS à son magasin de certificats système au lieu de recopier les étapes du fichier CA ci-dessous.
Revenez ensuite au terminal SSH du Droplet n8n. Définissez les chemins locaux réels du volume et de l'archive dans migration.env. La commande utilise un sous-shell pour garder votre terminal dans le dossier de déploiement. Vérifiez pwd avant l'export.
- Dans votre projet DigitalOcean, ouvrez Databases et cliquez sur Create Database. Vous pouvez aussi choisir Create, puis Managed Database. Sur Create Database Cluster, choisissez PostgreSQL et une version. Le moteur reste fixe. Une mise à niveau majeure prise en charge reste possible après les contrôles de compatibilité et la préparation de la reprise.
- Choisissez la même région que le Droplet n8n. Sélectionnez le plan et le stockage adaptés à la charge actuelle, saisissez n8n-postgres comme nom de cluster, choisissez le projet qui contient n8n, puis cliquez sur Create Database Cluster. Attendez que l’état du cluster affiche Online.
- Ouvrez le nouveau cluster, puis sélectionnez Users & Databases. Dans Databases, saisissez n8n dans Add new database et cliquez sur Save. Dans Users, saisissez n8n_app dans Add new user et cliquez sur Save. Utilisez n8n_app pour n8n. Réservez doadmin à l’administration et à la récupération.
- Sélectionnez Network Access, cliquez sur Add Trusted Sources, choisissez Quick select Droplets, puis sélectionnez le Droplet n8n. Cliquez sur Add Trusted Sources. Pour un contrôle ponctuel en ligne de commande, ajoutez votre adresse IPv4 actuelle depuis cette même fenêtre. Retirez-la après le contrôle. N’ajoutez pas 0.0.0.0/0.
- Retournez à Overview et ouvrez Connection Details. Copiez l’hôte, le port, le nom de la base, le nom d’utilisateur n8n_app et le mot de passe dans un gestionnaire de mots de passe. Téléchargez le certificat CA et copiez-le plus tard sur le Droplet n8n. Ne mettez aucune de ces valeurs dans Git, des notes de workflow ou des captures d’écran.
(
cd /root
git clone https://github.com/TylorMayfield/n8n-digitalocean-postgres-migration.git
cd n8n-digitalocean-postgres-migration
install -m 600 migration.env.example migration.env
)sudo nano /root/n8n-digitalocean-postgres-migration/migration.env
sudo /root/n8n-digitalocean-postgres-migration/scripts/preflight.sh /root/n8n-digitalocean-postgres-migration/migration.env
cd "$N8N_APP_DIR"
pwdEffectuer une bascule planifiée
Bloquez les requêtes entrantes et désactivez les tâches planifiées avant cette séquence. Laissez n8n actif pour lire son UID et son GID ; le script l’arrête ensuite avant l’export. Gardez la même image et la même clé de chiffrement. Attendez un export réussi avant de changer la base.
Le fichier .env se trouve à côté du fichier Compose. Il contient les valeurs que Compose transmet au conteneur n8n. Ajoutez-y les valeurs PostgreSQL. Ajoutez ensuite les entrées environment correspondantes et le montage en lecture seule du certificat CA au service n8n dans compose.yml ou docker-compose.yml. Un fichier .env seul ne donne pas de nouvelles variables à un conteneur en cours d’exécution si le fichier Compose ne les référence pas.
cd "$N8N_APP_DIR"
set -euo pipefail
sudo apt-get update
sudo apt-get install -y unzip
if [[ -f compose.yml ]]; then COMPOSE_FILE=compose.yml; elif [[ -f docker-compose.yml ]]; then COMPOSE_FILE=docker-compose.yml; else echo 'No Compose file'; exit 1; fi
sudo cp .env .env.sqlite-backup
sudo chmod 600 .env .env.sqlite-backup
sudo cp "$COMPOSE_FILE" "$COMPOSE_FILE.sqlite-backup"
N8N_UID=$(sudo docker compose exec -T n8n id -u)
N8N_GID=$(sudo docker compose exec -T n8n id -g)
sudo install -d -o "$N8N_UID" -g "$N8N_GID" -m 700 migration-entities
sudo install -d -m 700 secrets
sudo tee compose.migration.yml > /dev/null <<'YAML'
services:
n8n:
volumes:
- ./migration-entities:/migration
YAML
sudo docker compose stop n8n
sudo docker compose -f "$COMPOSE_FILE" -f compose.migration.yml run --rm --no-deps n8n export:entities --outputDir=/migration
sudo test -s migration-entities/entities.zip
sudo unzip -t migration-entities/entities.zip
# Continue only after export exits successfully and the directory contains the exported entities.
Avant de continuer : Cette configuration change la base utilisée par n8n au démarrage. Conservez les fichiers .env et Compose existants, gardez la clé de chiffrement actuelle et utilisez la nouvelle base seulement après un export d’entités réussi.
sudo nano .envsudo nano $COMPOSE_FILE
Avant de continuer : Exécutez l’importation une seule fois dans une nouvelle base PostgreSQL vide. Elle écrit les entités n8n exportées dans cette base.
set -euo pipefail
# Save the DigitalOcean CA certificate as secrets/do-postgres-ca.crt first.
sudo chmod 644 secrets/do-postgres-ca.crt
# The CA is public verification material; keep database passwords in protected .env.
sudo docker compose -f "$COMPOSE_FILE" -f compose.migration.yml run --rm --no-deps n8n import:entities --inputDir=/migration
# Disable imported schedules/webhooks before the first application start.
sudo docker compose -f "$COMPOSE_FILE" run --rm --no-deps n8n update:workflow --all --active=false
sudo docker compose -f "$COMPOSE_FILE" up -d
Prouver le résultat avant de rouvrir le trafic de production
Connectez-vous en administrateur. Ouvrez un workflow connu, déchiffrez un identifiant connu et terminez une exécution manuelle inoffensive. Gardez les workflows de production désactivés jusqu’à la fin des contrôles. Si un identifiant ne se déchiffre pas, restaurez l’ancien service. Ne réinitialisez pas les identifiants pendant l’enquête.
Testez ensuite la récupération de la base depuis le panneau de contrôle. Ouvrez Databases, sélectionnez le cluster n8n, choisissez Actions, puis Restore from backup. Choisissez un point récent, donnez un nom de test au cluster restauré et sélectionnez Restore to New Cluster. Quand il est online, ajoutez seulement votre adresse d’administration dans Network Access, copiez ses nouveaux paramètres de connexion et effectuez un contrôle psql en lecture seule. Cela prouve le point de récupération de la base, pas que chaque workflow est sûr.
Avant de continuer : Utilisez les informations de connexion du cluster restauré, pas celles de la production, pour le contrôle de récupération.
# Sur le Droplet n8n, vérifiez le service en cours et son journal de démarrage.
sudo docker compose ps
sudo docker compose logs --tail=100 n8n
# Sur une machine d’administration avec le client PostgreSQL installé, utilisez les nouveaux paramètres du cluster restauré.
psql "postgresql://n8n_app:YOUR_PASSWORD@RESTORED_CLUSTER_HOST:RESTORED_CLUSTER_PORT/n8n?sslmode=require" \
-c 'select current_database(), current_user, now();'
# Ouvrez ensuite un workflow, déchiffrez un identifiant et lancez un test manuel inoffensif. Consignez le résultat.Revenir à SQLite avant de reprendre le trafic
Utilisez ce retour uniquement tant que le trafic de production est suspendu et qu'aucune nouvelle donnée n'a été acceptée dans PostgreSQL. Il rétablit les fichiers préservés et le volume SQLite original. Gardez les entrées réseau bloquées pendant la vérification. Si vous avez déjà repris les écritures, arrêtez-vous et préparez une réconciliation; ce retour perdrait les nouvelles données.
cd "$N8N_APP_DIR"
sudo docker compose -f "$COMPOSE_FILE" stop n8n
sudo test -f .env.sqlite-backup
sudo test -f "$COMPOSE_FILE.sqlite-backup"
sudo cp .env.sqlite-backup .env
sudo cp "$COMPOSE_FILE.sqlite-backup" "$COMPOSE_FILE"
sudo docker compose -f "$COMPOSE_FILE" run --rm --no-deps n8n update:workflow --all --active=false
sudo docker compose -f "$COMPOSE_FILE" up -d n8n
sudo docker compose -f "$COMPOSE_FILE" psSavoir ce que PostgreSQL géré ne couvre pas
PostgreSQL géré exécute la base et fournit des sauvegardes ainsi qu’une récupération de l’infrastructure. Vous gardez la responsabilité des accès, de la logique des workflows, des identifiants et de la décision d’exécuter un workflow après récupération. Revoyez cette répartition après le premier test de restauration, pas pendant une panne.
Si n8n traite des données clients importantes ou des actions irréversibles, documentez un objectif de délai de reprise et une perte de données acceptable. La base fait maintenant partie d’un système d’exploitation, pas d’une simple mise à niveau.
Vérifier le résultat
- Résultat attendu
- Un administrateur peut ouvrir un workflow connu, déchiffrer un identifiant connu, réaliser un test manuel inoffensif et se connecter à PostgreSQL avec l’utilisateur applicatif dédié.
- Arrêter si
- Arrêtez si la sauvegarde ne peut pas être lue, si la clé de chiffrement manque, si la base accepte un accès sans restriction, si les identifiants ne se déchiffrent pas ou si un workflow de production peut créer un nouvel état avant la validation.
- Étape suivante
- Consignez la bascule et le test de récupération, retirez l’accès administrateur temporaire et conservez le point de récupération SQLite pendant la durée approuvée.