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
- Ce que tu vas installer et pourquoi
- Oracle Cloud Free Tier — Comprendre ce que tu as gratuitement
- Créer son compte Oracle Cloud
- Créer le VPS ARM Ampere A1
- Résoudre l'erreur "Out of Capacity"
- Ouvrir les ports réseau Oracle
- Connexion SSH et préparation du serveur
- Installer Docker & Docker Compose
- Installer n8n
- Installer NocoDB
- Récupérer Mistral AI gratuitement
- Connecter tout ensemble dans n8n
- Sécuriser avec HTTPS (Nginx + Certbot)
- Sauvegardes automatiques
- Workflow exemple pas-à-pas
- Commandes utiles et maintenance
- 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 ( |
| 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
- Va sur cloud.oracle.com et clique sur "Start for free"
- Renseigne tes informations (nom, email, pays)
- Vérifie ton email et crée un mot de passe fort
- 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.
- 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.
- 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
- Dans le dashboard Oracle Cloud, ouvre le menu hamburger (☰)
- 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"
Clique sur "Change image"
- Sélectionne Ubuntu
- Version : Ubuntu 22.04 (LTS, la plus stable)
- Clique sur "Select image"
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)
- Va dans Networking → Virtual Cloud Networks → vcn-automation
- Clique sur ton subnet → Default Security List
- 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/configpour simplifier la connexion :Host oracle-vps HostName <IP_PUBLIQUE> User ubuntu IdentityFile ~/.ssh/id_ed25519Ensuite :
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
- Va sur console.mistral.ai
- Clique sur "Sign up"
- Inscris-toi avec email ou Google/GitHub
- Vérifie ton email
Étape 2 — Activer le Plan Expériment
- Une fois connecté, va dans "Billing" (ou "Plans")
- Sélectionne "Experiment" (le plan gratuit)
- Lis et accepte les Conditions d'Utilisation
- Clique sur "Subscribe"
- Ton plan Expériment est maintenant actif ✅
Étape 3 — Générer une clé API
- Va dans "API Keys" dans le menu de gauche
- Clique sur "Create new key"
- Donne un nom à ta clé (ex :
n8n-automation) - 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
- Ouvre n8n (
https://n8n.TON-DOMAINE.com) - Va dans Settings → Credentials → Add Credential
- 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
- Settings → Credentials → Add Credential
- 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 :
- Connecte-toi à NocoDB
- Clique sur ton avatar (en haut à droite) → "Team & Auth"
- Onglet "API Tokens" → "Add new token"
- 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 :
- Surveille la boîte Gmail
- Envoie chaque email à Mistral pour analyse
- Mistral extrait : priorité, résumé, action requise
- NocoDB enregistre tout dans une table
Étape 1 — Créer la table dans NocoDB
- Connecte-toi à NocoDB
- "+ New Base" → nomme-la
CRM Automation - "+ New Table" → nomme-la
Emails - Ajoute ces colonnes :
| Nom | Type |
|---|---|
| Sujet | Single Line Text |
| Expéditeur | |
| Date | DateTime |
| Résumé | Long Text |
| Priorité | Single Select (options: Haute, Moyenne, Basse) |
| Action requise | Long Text |
| Traité | Checkbox |
- 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
- Connecte tes credentials Gmail, Mistral et NocoDB
- Clique sur "Execute Workflow" pour tester
- 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
- n8n Docs : docs.n8n.io
- n8n Community : community.n8n.io
- NocoDB Docs : nocodb.com/docs
- NocoDB GitHub : github.com/nocodb/nocodb
- Mistral Docs : docs.mistral.ai
- Mistral Console : console.mistral.ai
- Oracle Free Tier : oracle.com/cloud/free
- Oracle Always Free Resources : docs.oracle.com/...FreeTier
Guide rédigé pour Oracle Cloud Free Tier — VM ARM Ampere A1 (4 CPU / 24 Go RAM) — Ubuntu 22.04 LTS — Avril 2026