n8n + NocoDB + Mistral AI — 100% Gratuit, 100% Sous Ton Contrôle

avril 2026 · 33 min de lecture

Temps estimé : 2 à 3 heures pour une installation complète et sécurisée
Niveau : Intermédiaire (notions Linux/terminal requises)
Coût total : 0€


📋 Sommaire

  1. Ce que tu vas installer et pourquoi
  2. Oracle Cloud Free Tier — Comprendre ce que tu as gratuitement
  3. Créer son compte Oracle Cloud
  4. Créer le VPS ARM Ampere A1
  5. Résoudre l'erreur "Out of Capacity"
  6. Ouvrir les ports réseau Oracle
  7. Connexion SSH et préparation du serveur
  8. Installer Docker & Docker Compose
  9. Installer n8n
  10. Installer NocoDB
  11. Récupérer Mistral AI gratuitement
  12. Connecter tout ensemble dans n8n
  13. Sécuriser avec HTTPS (Nginx + Certbot)
  14. Sauvegardes automatiques
  15. Workflow exemple pas-à-pas
  16. Commandes utiles et maintenance
  17. Résolution de problèmes fréquents

1. Ce que tu vas installer et pourquoi

La stack complète

Outil Rôle Équivalent payant remplacé
n8n Orchestrateur d'automatisation (le cerveau) Zapier ($20/mois), Make ($16/mois)
NocoDB Base de données no-code visuelle Airtable (~$20/mois)
Mistral AI IA pour analyser, rédiger, classer ChatGPT Plus (~$20/mois)
Oracle VPS Serveur qui fait tourner tout ça AWS/GCP/DigitalOcean (~$20-50/mois)

Total économisé : ~60-100€/mois

Comment ils s'articulent

Email entrant / Webhook / Trigger
        ↓
    [n8n] — orchestre tout
    ↙         ↘
[Mistral]   [NocoDB]
Analyse      Stocke
le contenu   les données

2. Oracle Cloud Free Tier — Comprendre ce que tu as gratuitement

🔗 Page officielle : oracle.com/cloud/free

Ce qui est inclus POUR TOUJOURS (Always Free)

Oracle est le seul grand cloud à proposer des ressources vraiment gratuites à vie, sans expiration à 12 mois comme AWS ou GCP.

VM ARM Ampere A1 (⭐ Celle qu'on va utiliser)

  • 4 OCPUs (processeur ARM)
  • 24 Go de RAM — généreuse pour faire tourner 3 services
  • 200 Go de stockage (boot volume)
  • 10 To de bande passante sortante/mois
  • Tu peux faire une seule VM avec tout (4 CPU / 24 Go) ou plusieurs petites

VM AMD Micro (en bonus)

  • 2 VMs avec 1 CPU + 1 Go RAM chacune (trop petites pour notre stack, mais utiles en complément)

Autres ressources gratuites incluses

  • 1 Load Balancer (10 Mbps)
  • 20 Go d'Object Storage (compatible S3)
  • 1 adresse IP publique réservée
  • Monitoring, Vault (secrets), Notifications

⚠️ Point important : Les instances ARM sont très demandées. Dans les régions populaires, tu auras une erreur "Out of Capacity". La solution est expliquée à l'étape 5.


3. Créer son compte Oracle Cloud

🔗 Inscription : signup.cloud.oracle.com

Étapes d'inscription

  1. Va sur cloud.oracle.com et clique sur "Start for free"
  2. Renseigne tes informations (nom, email, pays)
  3. Vérifie ton email et crée un mot de passe fort
  4. Choisis ta région Home — c'est la région principale de ton compte

⚠️ Choisir la bonne région — C'est DÉFINITIF

La région Home ne peut pas être changée après la création. Choisis selon ta priorité :

Si tu es en... Région recommandée Code
France Frankfurt ou Paris eu-frankfurt-1 / eu-paris-1
Europe générale Frankfurt (le plus stable) eu-frankfurt-1
Monde entier US East ou US West us-ashburn-1

💡 Conseil : Frankfurt (eu-frankfurt-1) est souvent le plus stable pour les Européens car la capacité ARM y est plus disponible.

  1. Carte bancaire requise pour vérification — Oracle effectue une vérification de ~1€ qui est remboursée. Aucun débit tant que tu ne dépasses pas le Free Tier.
  2. Valide ton numéro de téléphone

Upgrade vers Pay As You Go (PAYG) — Recommandé dès le départ

⚠️ Sans PAYG, l'accès aux instances ARM est quasi impossible dans les régions populaires.

Aller dans Billing → Upgrade and Manage Payment → Upgrade to Pay As You Go

Ce que ça change :

  • Tes ressources Free Tier restent gratuites à 100%
  • Tu as accès à un pool de ressources plus grand
  • Oracle te facture uniquement si tu dépasses les limites Free Tier (ce qui ne devrait jamais arriver avec notre stack)
  • La mise à niveau prend 1 à 2 jours

4. Créer le VPS ARM Ampere A1

Prérequis : Générer une clé SSH

Avant de créer l'instance, génère une paire de clés SSH sur ta machine locale.

Sur Mac / Linux :

ssh-keygen -t ed25519 -C "oracle-automation-vps"
# Appuie sur Entrée pour accepter le chemin par défaut
# Choisis ou non un mot de passe

# Afficher la clé publique (à copier)
cat ~/.ssh/id_ed25519.pub

Sur Windows (PowerShell) :

ssh-keygen -t ed25519 -C "oracle-automation-vps"
# La clé publique sera dans C:\Users\TonNom\.ssh\id_ed25519.pub
Get-Content ~/.ssh/id_ed25519.pub

Créer l'instance

  1. Dans le dashboard Oracle Cloud, ouvre le menu hamburger (☰)
  2. Va dans Compute → Instances → Create Instance

Configuration détaillée

Onglet "Name and placement"

  • Name : automation-stack
  • Compartment : laisse sur le compartment racine (ton nom de compte)
  • Availability domain : AD-1 (tu peux en choisir un autre si erreur de capacité)

Onglet "Image and shape"

  1. Clique sur "Change image"

    • Sélectionne Ubuntu
    • Version : Ubuntu 22.04 (LTS, la plus stable)
    • Clique sur "Select image"
  2. Clique sur "Change shape"

    • Cliquer sur "Ampere" (onglet ARM)
    • Sélectionne VM.Standard.A1.Flex — tu verras le badge "Always Free-eligible"
    • OCPUs : glisse jusqu'à 4
    • Memory : glisse jusqu'à 24 GB
    • Clique sur "Select shape"

Onglet "Networking"

  • Primary network : "Create a new virtual cloud network"
  • VCN name : vcn-automation
  • Subnet : "Create a new public subnet"
  • Subnet name : subnet-public
  • Assign a public IPv4 address : OUI (obligatoire pour accès internet)

Onglet "Add SSH keys"

  • Sélectionne "Paste public keys"
  • Colle le contenu de ta clé publique (id_ed25519.pub)

Onglet "Boot volume"

  • Boot volume size : 100 GB (tu as 200 Go gratuits, utilise-en la moitié)
  • Laisse le reste par défaut

Cliquer sur "Create"

⚠️ Si tu vois "Out of Capacity", lis l'étape suivante avant de paniquer.

L'instance met 2 à 5 minutes à démarrer. Note l'adresse IP publique affichée dans les détails.


5. Résoudre l'erreur "Out of Capacity"

C'est l'erreur la plus fréquente. Les régions populaires manquent de capacité ARM. Voici les solutions, par ordre d'efficacité.

Solution 1 — Changer d'Availability Domain

Dans la même région, essaie AD-2 puis AD-3 (s'ils existent dans ta région).

Solution 2 — Essayer une autre région

Va dans Account → Manage Regions et ajoute une région moins chargée. Les régions US sont souvent plus disponibles.

Solution 3 — Script d'automatisation (la plus fiable)

Ce script tente de créer l'instance en boucle jusqu'à trouver de la capacité disponible.

Étape 1 — Récupérer les IDs nécessaires via Cloud Shell

Dans le dashboard Oracle, clique sur l'icône Cloud Shell (terminal en haut à droite).

# Récupérer ton Compartment ID
oci iam compartment list --include-root --query 'data[0].id' --raw-output

# Récupérer les Availability Domains disponibles
oci iam availability-domain list --compartment-id <COMPARTMENT_ID>

# Récupérer les Subnet IDs
oci network subnet list --compartment-id <COMPARTMENT_ID>

# Récupérer l'ID de l'image Ubuntu 22.04 ARM
oci compute image list \
  --compartment-id <COMPARTMENT_ID> \
  --operating-system "Canonical Ubuntu" \
  --operating-system-version "22.04" \
  --shape "VM.Standard.A1.Flex" \
  --query 'data[0].id' --raw-output

Étape 2 — Script de retry

#!/bin/bash
# Remplace les valeurs entre < >

COMPARTMENT_ID="<TON_COMPARTMENT_ID>"
SUBNET_ID="<TON_SUBNET_ID>"
IMAGE_ID="<TON_IMAGE_ID_UBUNTU22>"
SSH_KEY="<TA_CLE_SSH_PUBLIQUE>"

AD_LIST=("AD-1" "AD-2" "AD-3")
# Adapte selon ta région, ex pour Frankfurt:
# AD_LIST=("bgAk:EU-FRANKFURT-1-AD-1" "bgAk:EU-FRANKFURT-1-AD-2" "bgAk:EU-FRANKFURT-1-AD-3")

while true; do
  for AD in "${AD_LIST[@]}"; do
    echo "Tentative dans $AD..."
    RESULT=$(oci compute instance launch \
      --availability-domain "$AD" \
      --compartment-id "$COMPARTMENT_ID" \
      --shape "VM.Standard.A1.Flex" \
      --shape-config '{"ocpus": 4, "memoryInGBs": 24}' \
      --subnet-id "$SUBNET_ID" \
      --image-id "$IMAGE_ID" \
      --assign-public-ip true \
      --ssh-authorized-keys-file <(echo "$SSH_KEY") \
      --display-name "automation-stack" \
      2>&1)
    
    if echo "$RESULT" | grep -q '"lifecycle-state": "PROVISIONING"'; then
      echo "✅ Instance créée avec succès dans $AD !"
      exit 0
    else
      echo "❌ Échec dans $AD. Prochaine tentative dans 60s..."
    fi
  done
  sleep 60
done

⏱️ Ce script peut tourner plusieurs heures. Lance-le depuis le Cloud Shell Oracle pour ne pas dépendre de ta connexion locale.


6. Ouvrir les ports réseau Oracle

Oracle a deux niveaux de pare-feu à configurer. Les deux sont obligatoires.

Niveau 1 — Security List (dans le dashboard Oracle)

  1. Va dans Networking → Virtual Cloud Networks → vcn-automation
  2. Clique sur ton subnet → Default Security List
  3. Clique sur "Add Ingress Rules" et ajoute ces règles :
Source CIDR Protocol Port Description
0.0.0.0/0 TCP 22 SSH
0.0.0.0/0 TCP 80 HTTP
0.0.0.0/0 TCP 443 HTTPS

Note : Les ports 5678 (n8n) et 8080 (NocoDB) n'ont pas besoin d'être ouverts directement si tu utilises Nginx comme reverse proxy (recommandé). Si tu veux y accéder directement pendant les tests, ajoute-les temporairement.

Niveau 2 — UFW sur Ubuntu (configuré à l'étape 7)


7. Connexion SSH et préparation du serveur

Se connecter

ssh -i ~/.ssh/id_ed25519 ubuntu@<IP_PUBLIQUE_DE_TON_VPS>

# Si c'est la première connexion, tape "yes" pour accepter l'empreinte

💡 Astuce : Ajoute un alias dans ~/.ssh/config pour simplifier la connexion :

Host oracle-vps
    HostName <IP_PUBLIQUE>
    User ubuntu
    IdentityFile ~/.ssh/id_ed25519

Ensuite : ssh oracle-vps

Mise à jour et outils essentiels

# Mise à jour complète
sudo apt update && sudo apt upgrade -y

# Outils essentiels
sudo apt install -y curl wget git ufw fail2ban htop nano unzip

# Vérifier les ressources disponibles
free -h        # RAM
df -h          # Disque
nproc          # Nombre de CPUs

Configurer UFW (pare-feu logiciel)

# Activer UFW et ouvrir les ports nécessaires
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw --force enable

# Vérifier le statut
sudo ufw status verbose

Configurer fail2ban (protection brute-force SSH)

sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# Vérifier que SSH est protégé
sudo fail2ban-client status sshd

Configurer le swap (recommandé pour stabilité)

Même avec 24 Go de RAM, un peu de swap est utile pour les pics de charge :

sudo fallocate -l 4G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile

# Rendre le swap permanent au redémarrage
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

# Vérifier
free -h

8. Installer Docker & Docker Compose

# Script d'installation officiel Docker
curl -fsSL https://get.docker.com -o get-docker.sh
sudo sh get-docker.sh

# Ajouter ton utilisateur au groupe docker (évite sudo à chaque commande)
sudo usermod -aG docker $USER

# Recharger les groupes sans se déconnecter
newgrp docker

# Vérifier l'installation
docker --version
docker compose version

Activer Docker au démarrage

sudo systemctl enable docker
sudo systemctl start docker

Test rapide

docker run --rm hello-world
# Doit afficher "Hello from Docker!"

⚠️ Important pour ARM : Oracle utilise des processeurs ARM (Ampere). Toutes les images Docker que tu pulls doivent supporter linux/arm64. Les images officielles de n8n, NocoDB et PostgreSQL supportent ARM nativement.


9. Installer n8n

🔗 Documentation officielle : docs.n8n.io/hosting
🔗 Image Docker : hub.docker.com/r/n8nio/n8n

Créer la structure de fichiers

mkdir -p ~/stacks/n8n
cd ~/stacks/n8n

Créer le fichier de variables d'environnement

nano .env

Colle et adapte ce contenu :

# ===== CONFIGURATION N8N =====

# Domaine public de ton instance n8n
N8N_HOST=n8n.TON-DOMAINE.com

# Protocole (https en production)
N8N_PROTOCOL=https

# URL complète des webhooks (important pour les intégrations externes)
WEBHOOK_URL=https://n8n.TON-DOMAINE.com/

# Fuseau horaire
GENERIC_TIMEZONE=Europe/Paris
TZ=Europe/Paris

# ===== SÉCURITÉ =====
# Clé de chiffrement des credentials (génère une clé aléatoire de 32+ chars)
# Commande pour générer : openssl rand -hex 32
N8N_ENCRYPTION_KEY=CHANGE_MOI_avec_openssl_rand_-hex_32

# Authentification basique (change ces valeurs !)
N8N_BASIC_AUTH_ACTIVE=true
N8N_BASIC_AUTH_USER=admin
N8N_BASIC_AUTH_PASSWORD=MotDePasseTresSecurise123!

# ===== BASE DE DONNÉES =====
DB_TYPE=postgresdb
DB_POSTGRESDB_HOST=postgres
DB_POSTGRESDB_PORT=5432
DB_POSTGRESDB_DATABASE=n8n
DB_POSTGRESDB_USER=n8n
DB_POSTGRESDB_PASSWORD=MotDePasseDB_n8n_456!
DB_POSTGRESDB_SCHEMA=public

# ===== POSTGRES =====
POSTGRES_DB=n8n
POSTGRES_USER=n8n
POSTGRES_PASSWORD=MotDePasseDB_n8n_456!

🔑 Générer une clé de chiffrement sécurisée :

openssl rand -hex 32

Créer le docker-compose.yml

nano docker-compose.yml
version: "3.8"

services:
  # ===== Base de données n8n =====
  postgres:
    image: postgres:15-alpine
    container_name: n8n-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: ${POSTGRES_DB}
      POSTGRES_USER: ${POSTGRES_USER}
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - n8n_postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER}"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - n8n-net

  # ===== n8n =====
  n8n:
    image: docker.n8n.io/n8nio/n8n:latest
    container_name: n8n
    restart: unless-stopped
    ports:
      - "127.0.0.1:5678:5678"   # Accessible uniquement en local (Nginx fera le proxy)
    environment:
      # Déploiement
      N8N_HOST: ${N8N_HOST}
      N8N_PORT: 5678
      N8N_PROTOCOL: ${N8N_PROTOCOL}
      WEBHOOK_URL: ${WEBHOOK_URL}
      GENERIC_TIMEZONE: ${GENERIC_TIMEZONE}
      TZ: ${TZ}
      # Sécurité
      N8N_ENCRYPTION_KEY: ${N8N_ENCRYPTION_KEY}
      N8N_BASIC_AUTH_ACTIVE: ${N8N_BASIC_AUTH_ACTIVE}
      N8N_BASIC_AUTH_USER: ${N8N_BASIC_AUTH_USER}
      N8N_BASIC_AUTH_PASSWORD: ${N8N_BASIC_AUTH_PASSWORD}
      # Base de données
      DB_TYPE: ${DB_TYPE}
      DB_POSTGRESDB_HOST: ${DB_POSTGRESDB_HOST}
      DB_POSTGRESDB_PORT: ${DB_POSTGRESDB_PORT}
      DB_POSTGRESDB_DATABASE: ${DB_POSTGRESDB_DATABASE}
      DB_POSTGRESDB_USER: ${DB_POSTGRESDB_USER}
      DB_POSTGRESDB_PASSWORD: ${DB_POSTGRESDB_PASSWORD}
    volumes:
      - n8n_data:/home/node/.n8n
      - n8n_local_files:/files
    depends_on:
      postgres:
        condition: service_healthy
    networks:
      - n8n-net

volumes:
  n8n_data:
  n8n_postgres_data:
  n8n_local_files:

networks:
  n8n-net:
    driver: bridge

Lancer n8n

docker compose up -d

# Suivre les logs au démarrage
docker compose logs -f n8n

# Vérifier que tout tourne
docker compose ps

Tu devrais voir quelque chose comme :

n8n-postgres   Running (healthy)
n8n            Running

10. Installer NocoDB

🔗 Documentation officielle : nocodb.com/docs/self-hosting
🔗 GitHub : github.com/nocodb/nocodb
🔗 Image Docker : hub.docker.com/r/nocodb/nocodb

Option rapide — Auto-Upstall (recommandée pour débuter)

NocoDB propose un script qui installe tout automatiquement (Docker, PostgreSQL, Redis, SSL) :

bash <(curl -sSL http://install.nocodb.com/noco.sh) <(mktemp)

Ce script te demandera ton domaine et s'occupe de tout. C'est la méthode la plus simple.


Option manuelle — Docker Compose (plus de contrôle)

mkdir -p ~/stacks/nocodb
cd ~/stacks/nocodb

Créer le fichier .env :

nano .env
# ===== NOCODB =====
NC_PUBLIC_URL=https://nocodb.TON-DOMAINE.com

# JWT Secret (génère avec : openssl rand -hex 32)
JWT_SECRET=CHANGE_MOI_avec_openssl_rand_-hex_32

# Désactiver la télémétrie
NC_DISABLE_TELE=true

# Fuseau horaire
NC_TIMEZONE=Europe/Paris

# ===== POSTGRES =====
POSTGRES_PASSWORD=MotDePasseDB_nocodb_789!

Créer le docker-compose.yml :

nano docker-compose.yml
version: "3.8"

services:
  # ===== Base de données NocoDB =====
  nocodb-postgres:
    image: postgres:15-alpine
    container_name: nocodb-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: nocodb
      POSTGRES_USER: nocodb
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - nocodb_postgres_data:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U nocodb"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      - nocodb-net

  # ===== NocoDB =====
  nocodb:
    image: nocodb/nocodb:latest
    container_name: nocodb
    restart: unless-stopped
    ports:
      - "127.0.0.1:8080:8080"   # Accessible uniquement en local (Nginx fait le proxy)
    environment:
      NC_DB: "pg://nocodb-postgres:5432?u=nocodb&p=${POSTGRES_PASSWORD}&d=nocodb"
      NC_AUTH_JWT_SECRET: ${JWT_SECRET}
      NC_PUBLIC_URL: ${NC_PUBLIC_URL}
      NC_DISABLE_TELE: ${NC_DISABLE_TELE}
      NC_TIMEZONE: ${NC_TIMEZONE}
    volumes:
      - nocodb_data:/usr/app/data
    depends_on:
      nocodb-postgres:
        condition: service_healthy
    networks:
      - nocodb-net

volumes:
  nocodb_data:
  nocodb_postgres_data:

networks:
  nocodb-net:
    driver: bridge

Lancer NocoDB :

docker compose up -d
docker compose logs -f nocodb

# Vérifier
docker compose ps

Premier accès à NocoDB

Pour tester avant d'avoir le HTTPS configuré :

# Accès temporaire via tunnel SSH (sur ta machine locale)
ssh -L 8080:localhost:8080 oracle-vps
# Puis ouvre http://localhost:8080 dans ton navigateur

Crée un compte admin à la première connexion.


11. Récupérer Mistral AI Gratuitement

Comprendre les deux offres gratuites de Mistral

Mistral propose deux choses distinctes et gratuites :

A) Le Plan Expériment (API) — Ce qu'on utilise pour n8n

🔗 Console Mistral : console.mistral.ai

  • Accès à l'API de tous les modèles Mistral (Small, Medium, Large, Codestral...)
  • Aucune carte bancaire requise — juste un numéro de téléphone pour vérification
  • Limites du plan gratuit :
    • 2 requêtes par minute
    • 500 000 tokens par minute
    • 1 milliard de tokens par mois par modèle — très généreux pour débuter
  • ⚠️ Attention : Sur le plan Expériment, tes requêtes peuvent être utilisées pour entraîner les modèles Mistral. Pour plus de confidentialité, passe sur le plan Scale (payant).

B) Le Chat Le Chat (interface web) — Pour usage personnel

🔗 Le Chat : chat.mistral.ai

  • ~25 messages/jour gratuits sur les modèles Medium et Small
  • Interface similaire à ChatGPT, pour usage quotidien sans API

Créer son compte et obtenir sa clé API

Étape 1 — Créer un compte

  1. Va sur console.mistral.ai
  2. Clique sur "Sign up"
  3. Inscris-toi avec email ou Google/GitHub
  4. Vérifie ton email

Étape 2 — Activer le Plan Expériment

  1. Une fois connecté, va dans "Billing" (ou "Plans")
  2. Sélectionne "Experiment" (le plan gratuit)
  3. Lis et accepte les Conditions d'Utilisation
  4. Clique sur "Subscribe"
  5. Ton plan Expériment est maintenant actif ✅

Étape 3 — Générer une clé API

  1. Va dans "API Keys" dans le menu de gauche
  2. Clique sur "Create new key"
  3. Donne un nom à ta clé (ex : n8n-automation)
  4. Copie et sauvegarde ta clé immédiatement — elle ne sera plus affichée ensuite !
Format de la clé : sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Étape 4 — Tester ta clé API

curl -X POST https://api.mistral.ai/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sk-TA_CLE_ICI" \
  -d '{
    "model": "mistral-small-latest",
    "messages": [
      {
        "role": "user",
        "content": "Réponds juste OK si tu me lis."
      }
    ],
    "max_tokens": 10
  }'

Réponse attendue :

{
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "OK"
      }
    }
  ]
}

Choisir le bon modèle Mistral

Modèle Cas d'usage Vitesse Qualité
mistral-small-latest Tâches simples, classification, résumé ⚡⚡⚡ ⭐⭐⭐
mistral-medium-latest Analyse complexe, rédaction ⚡⚡ ⭐⭐⭐⭐
mistral-large-latest Tâches très complexes, code avancé ⭐⭐⭐⭐⭐
open-mistral-7b Modèle open-source, usage basique ⚡⚡⚡⚡ ⭐⭐

Pour notre stack, mistral-small-latest est le meilleur choix : rapide, efficace, et largement suffisant pour analyser des emails, classer des données et générer des résumés.


Stocker sa clé API de façon sécurisée sur le serveur

Ne mets jamais ta clé directement dans le code ou les docker-compose. Utilise un fichier .env :

# Sur le serveur VPS
nano ~/stacks/secrets.env
MISTRAL_API_KEY=sk-ta-cle-ici
# Restreindre les permissions (lisible uniquement par toi)
chmod 600 ~/stacks/secrets.env

12. Connecter tout ensemble dans n8n

Ajouter Mistral comme credential dans n8n

  1. Ouvre n8n (https://n8n.TON-DOMAINE.com)
  2. Va dans Settings → Credentials → Add Credential
  3. Cherche "HTTP Request" ou "Mistral Cloud" (si disponible dans ta version)

Pour une intégration via HTTP Request (universelle) :

  • Credential Name : Mistral API
  • Authentication : Generic Credential Type
  • Generic Auth Type : Header Auth
  • Name : Authorization
  • Value : Bearer sk-TA_CLE_MISTRAL

Ou via Mistral Cloud node (versions récentes de n8n) :

  • Credential Name : Mistral
  • API Key : sk-TA_CLE_MISTRAL

Ajouter NocoDB comme credential dans n8n

  1. Settings → Credentials → Add Credential
  2. Cherche "NocoDB"

Configuration :

Champ Valeur
Credential Name NocoDB Local
Host http://nocodb:8080 (si même réseau Docker) ou http://localhost:8080
API Token Généré dans NocoDB → Account → Team & Auth → API Tokens

Comment générer le token dans NocoDB :

  1. Connecte-toi à NocoDB
  2. Clique sur ton avatar (en haut à droite) → "Team & Auth"
  3. Onglet "API Tokens""Add new token"
  4. Donne un nom et copie le token généré

Mettre n8n et NocoDB sur le même réseau Docker

Pour que n8n puisse communiquer directement avec NocoDB sans passer par internet :

# Créer un réseau partagé
docker network create automation-shared

# Connecter n8n
docker network connect automation-shared n8n

# Connecter NocoDB
docker network connect automation-shared nocodb

Maintenant dans n8n, l'URL de NocoDB est http://nocodb:8080.


13. Sécuriser avec HTTPS (Nginx + Certbot)

Prérequis

  • Un nom de domaine (ex: mondomaine.com)
  • Deux sous-domaines pointant vers ton IP Oracle :
    • n8n.mondomaine.com → A record vers <IP_VPS>
    • nocodb.mondomaine.com → A record vers <IP_VPS>

💡 Si tu n'as pas de domaine, tu peux en obtenir un gratuit sur freenom.com ou utiliser DuckDNS pour un sous-domaine gratuit.

Installer Nginx et Certbot

sudo apt install -y nginx certbot python3-certbot-nginx
sudo systemctl enable nginx
sudo systemctl start nginx

Configurer Nginx pour n8n

sudo nano /etc/nginx/sites-available/n8n
server {
    listen 80;
    server_name n8n.TON-DOMAINE.com;

    location / {
        proxy_pass http://localhost:5678;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        proxy_read_timeout 90;
        proxy_connect_timeout 90;
        proxy_send_timeout 90;
    }
}

Configurer Nginx pour NocoDB

sudo nano /etc/nginx/sites-available/nocodb
server {
    listen 80;
    server_name nocodb.TON-DOMAINE.com;

    location / {
        proxy_pass http://localhost:8080;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_cache_bypass $http_upgrade;
        # NocoDB nécessite des timeouts plus longs pour les grosses opérations
        proxy_read_timeout 300;
    }
}

Activer les sites et obtenir les certificats SSL

# Activer les sites
sudo ln -s /etc/nginx/sites-available/n8n /etc/nginx/sites-enabled/
sudo ln -s /etc/nginx/sites-available/nocodb /etc/nginx/sites-enabled/

# Supprimer le site par défaut
sudo rm /etc/nginx/sites-enabled/default

# Tester la configuration Nginx
sudo nginx -t

# Si OK, recharger Nginx
sudo systemctl reload nginx

# Générer les certificats SSL (Let's Encrypt — gratuit)
sudo certbot --nginx \
  -d n8n.TON-DOMAINE.com \
  -d nocodb.TON-DOMAINE.com \
  --email ton@email.com \
  --agree-tos \
  --non-interactive

# Recharger Nginx avec les nouvelles configs SSL
sudo systemctl reload nginx

Configurer le renouvellement automatique des certificats

Certbot configure normalement un timer automatique, mais vérifie :

sudo certbot renew --dry-run
# Si "Congratulations, all simulated renewals succeeded", c'est bon

# Vérifier le timer systemd
sudo systemctl list-timers | grep certbot

14. Sauvegardes automatiques

Script de sauvegarde complet

nano ~/backup.sh
#!/bin/bash
# ================================================
# Script de sauvegarde — Stack n8n + NocoDB
# ================================================

DATE=$(date +%Y%m%d_%H%M%S)
BACKUP_DIR=~/backups/$DATE
LOG_FILE=~/backups/backup.log

mkdir -p "$BACKUP_DIR"

echo "[$DATE] Début de la sauvegarde..." | tee -a "$LOG_FILE"

# ===== SAUVEGARDE n8n =====
echo "Sauvegarde n8n..." | tee -a "$LOG_FILE"

# Workflows et credentials (volume Docker)
docker run --rm \
  -v n8n_n8n_data:/source \
  -v "$BACKUP_DIR":/backup \
  alpine tar czf /backup/n8n_data.tar.gz -C /source . \
  && echo "✅ n8n data sauvegardé" | tee -a "$LOG_FILE" \
  || echo "❌ Erreur sauvegarde n8n data" | tee -a "$LOG_FILE"

# Base de données n8n PostgreSQL
docker exec n8n-postgres \
  pg_dump -U n8n n8n | gzip > "$BACKUP_DIR/n8n_postgres.sql.gz" \
  && echo "✅ n8n PostgreSQL sauvegardé" | tee -a "$LOG_FILE" \
  || echo "❌ Erreur sauvegarde n8n PostgreSQL" | tee -a "$LOG_FILE"

# ===== SAUVEGARDE NocoDB =====
echo "Sauvegarde NocoDB..." | tee -a "$LOG_FILE"

# Base de données NocoDB PostgreSQL
docker exec nocodb-postgres \
  pg_dump -U nocodb nocodb | gzip > "$BACKUP_DIR/nocodb_postgres.sql.gz" \
  && echo "✅ NocoDB PostgreSQL sauvegardé" | tee -a "$LOG_FILE" \
  || echo "❌ Erreur sauvegarde NocoDB PostgreSQL" | tee -a "$LOG_FILE"

# Fichiers NocoDB (uploads, etc.)
docker run --rm \
  -v nocodb_nocodb_data:/source \
  -v "$BACKUP_DIR":/backup \
  alpine tar czf /backup/nocodb_data.tar.gz -C /source . \
  && echo "✅ NocoDB data sauvegardé" | tee -a "$LOG_FILE" \
  || echo "❌ Erreur sauvegarde NocoDB data" | tee -a "$LOG_FILE"

# ===== SAUVEGARDE CONFIGS =====
echo "Sauvegarde des configurations..." | tee -a "$LOG_FILE"
cp ~/stacks/n8n/.env "$BACKUP_DIR/n8n.env.bak"
cp ~/stacks/nocodb/.env "$BACKUP_DIR/nocodb.env.bak"
cp ~/stacks/n8n/docker-compose.yml "$BACKUP_DIR/n8n-docker-compose.bak"
cp ~/stacks/nocodb/docker-compose.yml "$BACKUP_DIR/nocodb-docker-compose.bak"

# ===== NETTOYAGE =====
echo "Nettoyage des vieilles sauvegardes..." | tee -a "$LOG_FILE"
find ~/backups -maxdepth 1 -type d -mtime +7 -exec rm -rf {} + 2>/dev/null
find ~/backups -name "*.log" -size +5M -exec truncate -s 1M {} \;

# ===== RÉSUMÉ =====
BACKUP_SIZE=$(du -sh "$BACKUP_DIR" | cut -f1)
echo "[$DATE] ✅ Sauvegarde terminée. Taille : $BACKUP_SIZE" | tee -a "$LOG_FILE"
echo "Fichiers :" | tee -a "$LOG_FILE"
ls -lh "$BACKUP_DIR" | tee -a "$LOG_FILE"
chmod +x ~/backup.sh

# Tester la sauvegarde
~/backup.sh
ls ~/backups/

Planifier via cron (chaque nuit à 2h)

crontab -e

Ajoute cette ligne :

0 2 * * * /home/ubuntu/backup.sh >> /home/ubuntu/backups/cron.log 2>&1

Restaurer depuis une sauvegarde

# Restaurer la base n8n
gunzip -c ~/backups/<DATE>/n8n_postgres.sql.gz | docker exec -i n8n-postgres psql -U n8n n8n

# Restaurer la base NocoDB
gunzip -c ~/backups/<DATE>/nocodb_postgres.sql.gz | docker exec -i nocodb-postgres psql -U nocodb nocodb

# Restaurer les fichiers n8n
docker run --rm \
  -v n8n_n8n_data:/target \
  -v ~/backups/<DATE>:/backup \
  alpine tar xzf /backup/n8n_data.tar.gz -C /target

15. Workflow exemple pas-à-pas

Scénario : Analyse automatique d'emails entrants

Ce que fait ce workflow :

  1. Surveille la boîte Gmail
  2. Envoie chaque email à Mistral pour analyse
  3. Mistral extrait : priorité, résumé, action requise
  4. NocoDB enregistre tout dans une table

Étape 1 — Créer la table dans NocoDB

  1. Connecte-toi à NocoDB
  2. "+ New Base" → nomme-la CRM Automation
  3. "+ New Table" → nomme-la Emails
  4. Ajoute ces colonnes :
Nom Type
Sujet Single Line Text
Expéditeur Email
Date DateTime
Résumé Long Text
Priorité Single Select (options: Haute, Moyenne, Basse)
Action requise Long Text
Traité Checkbox
  1. Récupère l'ID de la table dans l'URL : https://nocodb.mondomaine.com/dashboard/#/nc/.../table/<TABLE_ID>

Étape 2 — Créer le workflow dans n8n

Ouvre n8n → "New Workflow" → mode JSON → colle ce workflow :

{
  "name": "Email → Mistral → NocoDB",
  "nodes": [
    {
      "name": "Gmail Trigger",
      "type": "n8n-nodes-base.gmailTrigger",
      "parameters": {
        "pollTimes": {"item": [{"mode": "everyMinute"}]},
        "filters": {}
      }
    },
    {
      "name": "Préparer message Mistral",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const email = $input.item.json;\nreturn {\n  sujet: email.subject || '(sans sujet)',\n  expediteur: email.from?.value?.[0]?.address || 'inconnu',\n  corps: (email.text || email.snippet || '').substring(0, 2000),\n  date: email.date || new Date().toISOString()\n};"
      }
    },
    {
      "name": "Mistral - Analyser email",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "method": "POST",
        "url": "https://api.mistral.ai/v1/chat/completions",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headers": {
          "parameters": [{"name": "Content-Type", "value": "application/json"}]
        },
        "bodyParametersUi": {
          "parameter": []
        },
        "body": "={\n  \"model\": \"mistral-small-latest\",\n  \"messages\": [\n    {\n      \"role\": \"system\",\n      \"content\": \"Tu es un assistant qui analyse des emails professionnels. Réponds UNIQUEMENT en JSON valide avec ces champs : {\\\"priorite\\\": \\\"Haute|Moyenne|Basse\\\", \\\"resume\\\": \\\"résumé en 1-2 phrases\\\", \\\"action\\\": \\\"action requise ou 'Aucune'\\\"}\"\n    },\n    {\n      \"role\": \"user\",\n      \"content\": \"Analyse cet email.\\nSujet: {{ $json.sujet }}\\nExpéditeur: {{ $json.expediteur }}\\nContenu: {{ $json.corps }}\"\n    }\n  ],\n  \"max_tokens\": 200\n}",
        "sendBody": true
      }
    },
    {
      "name": "Parser réponse Mistral",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const response = $input.item.json;\nconst content = response.choices[0].message.content;\nlet parsed;\ntry {\n  parsed = JSON.parse(content);\n} catch(e) {\n  parsed = { priorite: 'Moyenne', resume: content, action: 'Vérifier manuellement' };\n}\nreturn {\n  ...$node['Préparer message Mistral'].json,\n  ...parsed\n};"
      }
    },
    {
      "name": "NocoDB - Créer ligne",
      "type": "n8n-nodes-base.nocoDb",
      "parameters": {
        "operation": "create",
        "projectId": "TON_PROJECT_ID",
        "table": "Emails",
        "dataToSend": "defineBelow",
        "fieldsUi": {
          "fieldValues": [
            {"fieldName": "Sujet", "fieldValue": "={{ $json.sujet }}"},
            {"fieldName": "Expéditeur", "fieldValue": "={{ $json.expediteur }}"},
            {"fieldName": "Date", "fieldValue": "={{ $json.date }}"},
            {"fieldName": "Résumé", "fieldValue": "={{ $json.resume }}"},
            {"fieldName": "Priorité", "fieldValue": "={{ $json.priorite }}"},
            {"fieldName": "Action requise", "fieldValue": "={{ $json.action }}"}
          ]
        }
      }
    }
  ]
}

💡 Tu peux construire ce workflow visuellement dans n8n sans coller du JSON. Les nœuds sont : Gmail Trigger → Code → HTTP Request (Mistral) → Code → NocoDB.

Étape 3 — Activer le workflow

  1. Connecte tes credentials Gmail, Mistral et NocoDB
  2. Clique sur "Execute Workflow" pour tester
  3. Active le workflow avec le toggle en haut à droite

16. Commandes utiles et maintenance

Gestion des conteneurs

# Voir tous les conteneurs et leur état
docker ps -a

# Redémarrer un service
cd ~/stacks/n8n && docker compose restart n8n
cd ~/stacks/nocodb && docker compose restart nocodb

# Voir les logs en temps réel
docker compose logs -f n8n
docker compose logs -f nocodb

# Voir les 100 dernières lignes de logs
docker compose logs --tail=100 n8n

Mise à jour des services

# Mettre à jour n8n
cd ~/stacks/n8n
docker compose pull
docker compose up -d
docker image prune -f   # Supprimer les vieilles images

# Mettre à jour NocoDB
cd ~/stacks/nocodb
docker compose pull
docker compose up -d
docker image prune -f

Surveiller les ressources

# Utilisation CPU et RAM en temps réel
htop

# Utilisation des ressources par conteneur Docker
docker stats

# Espace disque
df -h
docker system df   # Espace utilisé par Docker

Nettoyer Docker (libérer de l'espace)

# Supprimer les images non utilisées
docker image prune -f

# Nettoyage complet (attention : supprime conteneurs arrêtés, images, volumes orphelins)
docker system prune -a --volumes

17. Résolution de problèmes fréquents

n8n ne démarre pas

# Voir les erreurs
docker compose -f ~/stacks/n8n/docker-compose.yml logs n8n

# Vérifier que PostgreSQL est sain
docker inspect n8n-postgres | grep -A5 "Health"

# Solution courante : attendre que PostgreSQL soit prêt
docker compose -f ~/stacks/n8n/docker-compose.yml down
docker compose -f ~/stacks/n8n/docker-compose.yml up -d

Erreur "Out of Host Capacity" Oracle

→ Voir étape 5

NocoDB inaccessible après redémarrage

# Vérifier que les deux conteneurs tournent
cd ~/stacks/nocodb
docker compose ps

# Si NocoDB est en "Restarting" (boucle de redémarrage)
docker compose logs nocodb   # Lire l'erreur

# Solution courante : la DB n'est pas prête
docker compose restart nocodb   # Réessayer après que postgres est sain

Erreur SSL Certbot

# Vérifier que les DNS pointent bien vers ton IP
dig n8n.TON-DOMAINE.com
nslookup n8n.TON-DOMAINE.com

# Regénérer le certificat
sudo certbot --nginx -d n8n.TON-DOMAINE.com --force-renewal

Mistral retourne une erreur 429 (rate limit)

Avec le plan Expériment, la limite est de 2 requêtes par minute. Solutions :

# Dans n8n, ajoute un nœud "Wait" entre le trigger et l'appel Mistral
# Configure-le sur 35 secondes (pour être sous la limite)

Ou passe sur un modèle open-source moins limité comme open-mistral-7b.

Le VPS est lent ou consomme trop de RAM

# Vérifier ce qui consomme
docker stats --no-stream

# Réduire la mémoire allouée à PostgreSQL (optionnel)
# Ajoute dans le docker-compose de postgres :
# command: postgres -c shared_buffers=256MB -c max_connections=50

🎯 Récapitulatif des URLs et accès

Service URL Port interne
n8n https://n8n.TON-DOMAINE.com 5678
NocoDB https://nocodb.TON-DOMAINE.com 8080
Mistral API https://api.mistral.ai externe
Oracle Console https://cloud.oracle.com externe
Mistral Console https://console.mistral.ai externe

📚 Ressources officielles


Guide rédigé pour Oracle Cloud Free Tier — VM ARM Ampere A1 (4 CPU / 24 Go RAM) — Ubuntu 22.04 LTS — Avril 2026

Ce guide vient de Build With Nath

La communauté est gratuite. J’y publie ces guides au fil de l’eau et on y répond aux questions.

Autres guides · Guides

Vous dirigez une entreprise et vous voulez savoir lequel de vos process mérite ce genre de traitement ? Le diagnostic vous le dit en trois minutes, ou on en parle trente minutes.