[{"data":1,"prerenderedAt":189},["ShallowReactive",2],{"seo-verification":3,"blog-self-host-grist-vps-ma-fr":6,"promo-bar-likely":157},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-self-host-grist-vps-ma-fr",{"id":9,"slug":10,"slugs":11,"title":15,"excerpt":16,"readTime":17,"views":18,"isPinned":19,"noindex":19,"publishedAt":20,"updatedAt":21,"category":22,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":32,"intro":35,"sections":36,"ctaTitle":125,"ctaBody":126,"ctaButton":127,"ctaUrl":128,"relatedPosts":129},218,"self-host-grist-vps",{"fr":10,"en":12,"ar":13,"es":14},"self-hosting-grist-on-a-vps-open-source-airtable-alternative","استضافة-grist-على-vps-بديل-airtable-مفتوح-المصدر","alojar-grist-en-un-vps-alternativa-a-airtable","Héberger Grist sur un VPS : tableur-base de données open-source","Déployez Grist sur VPS : Docker Compose, reverse proxy HTTPS, formules Python, SSO OIDC, sauvegardes automatiques, dépannage — alternative open-source à Airtable.",7,3,false,"2026-08-04T00:00:00+00:00","2026-11-04T16:30:26+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},"Self-hosting","self-hosting","bg-indigo-500\u002F10 text-indigo-400","cloud",[28],{"id":17,"name":23,"slug":24,"color":25,"icon":26},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fself-host-grist-vps-poster.svg",{"categorySlug":33,"appSlug":34},"developpement","grist","Google Sheets stocke des listes. Airtable ajoute des relations entre tables, mais facture 20 $ par utilisateur par mois. Grist fait les deux, en open-source, sur votre propre serveur : des colonnes typées, des références entre tables, des formules Python qui s'exécutent côté serveur, et une API REST générée automatiquement sur chaque document. Résultat : un outil de modélisation de données complet, sans abonnement, sans vendor lock-in.",[37,41,50,53,66,69,72,75,78,122],{"type":38,"title":39,"body":40},"h2","Pourquoi Grist plutôt qu'un Google Sheets ou un Airtable","Google Sheets est un tableur : il stocke des données à plat, les calculs sont limités à des fonctions de feuille, et les relations entre feuilles reposent sur des VLOOKUP fragiles. Airtable résout cela avec des bases relationnelles, mais à 20 $ par utilisateur par mois, l'addition monte vite pour une agence ou une équipe technique.\n\nGrist combine les deux mondes : une interface tableur familière sur une base de données relationnelle réelle. Chaque document contient des tables avec des colonnes typées (texte, numérique, date, référence, pièce jointe), des relations explicites entre tables via des colonnes de référence, et des formules Python qui s'exécutent côté serveur — pas dans le navigateur. Sur votre VPS, Grist coûte 0 $ par mois supplémentaire.",{"type":42,"title":43,"items":44},"ul","Ce que Grist fait que Google Sheets ne fait pas",[45,46,47,48,49],"**Relations entre tables** : une colonne de référence dans `Commandes` pointe vers `Clients` — pas un VLOOKUP cassable, une vraie clé étrangère avec autocomplétion.","**Formules Python côté serveur** : `import datetime`, `import re`, `import uuid` — et toute bibliothèque Python pure. Les formules s'exécutent dans un sandbox serveur, pas dans le navigateur.","**API REST automatique** : chaque document expose `\u002Fapi\u002Fdocs\u002F\u003Cid>\u002Ftables\u002F\u003Ctable>\u002Frecords` sans configuration. Intégrez Grist dans n8n, Make ou tout client HTTP.","**Vues multiples sur les mêmes données** : grid, carte, graphique, calendrier, widget personnalisé — chaque vue est filtrée et configurée indépendamment sans dupliquer les données.","**Règles d'accès par ligne et par colonne** : limitez la lecture ou l'écriture d'une ligne selon l'attribut de l'utilisateur — assez fin pour des documents multi-tenant.",{"type":38,"title":51,"body":52},"Prérequis et architecture Docker","Un VPS avec **1 Go de RAM minimum** et Docker installé suffit pour démarrer. Grist se déploie en un seul conteneur `gristlabs\u002Fgrist` qui embarque Node.js (serveur web), Python (sandbox de formules) et SQLite (stockage des documents). Un volume nommé `\u002Fpersist` stocke les fichiers `.grist` — un fichier par document. Aucun service externe requis : pas de PostgreSQL, pas de Redis, pas de Celery.\n\nLe port par défaut est **8484**. Vérifiez qu'il est accessible depuis localhost avant de configurer le reverse proxy (`curl -sI http:\u002F\u002Flocalhost:8484\u002F`).",{"type":54,"title":55,"steps":56},"steps","Docker Compose complet et déploiement",[57,60,63],{"title":58,"body":59},"Créer l'arborescence et le docker-compose.yml","Connectez-vous en SSH sur votre VPS et créez le répertoire de stack :\n\n```bash\nmkdir -p \u002Fopt\u002Fstacks\u002Fgrist && cd \u002Fopt\u002Fstacks\u002Fgrist\n```\n\nCréez le fichier `docker-compose.yml` suivant :\n\n```yaml\nservices:\n  grist:\n    image: gristlabs\u002Fgrist:1.7.20\n    container_name: grist\n    restart: unless-stopped\n    ports:\n      - \"127.0.0.1:8484:8484\"\n    volumes:\n      - grist_data:\u002Fpersist\n    environment:\n      GRIST_SESSION_SECRET: \"REMPLACEZ_PAR_openssl_rand_hex_32\"\n      APP_HOME_URL: \"https:\u002F\u002Fgrist.votredomaine.com\"\n      GRIST_DEFAULT_EMAIL: \"admin@localhost.local\"\n      GRIST_SANDBOX_FLAVOR: \"gvisor\"\n\nvolumes:\n  grist_data:\n```\n\nGénérez le secret de session avant de démarrer : `openssl rand -hex 32`. Ne réutilisez jamais cette valeur entre deux instances.",{"title":61,"body":62},"Démarrer et vérifier","```bash\ndocker compose up -d\ndocker compose logs -f grist\n```\n\nAttendez le message `Grist server ready`. Vérifiez le statut HTTP :\n\n```bash\ncurl -sI http:\u002F\u002Flocalhost:8484\u002F\n```\n\nVous devez obtenir `HTTP\u002F1.1 200 OK` ou une redirection `302`. Si le conteneur redémarre en boucle, consultez la section Dépannage ci-dessous.",{"title":64,"body":65},"Configurer nginx comme reverse proxy HTTPS","Installez nginx et certbot sur le VPS, puis créez `\u002Fetc\u002Fnginx\u002Fsites-available\u002Fgrist.conf` :\n\n```nginx\nserver {\n    listen 80;\n    server_name grist.votredomaine.com;\n    return 301 https:\u002F\u002F$host$request_uri;\n}\n\nserver {\n    listen 443 ssl;\n    server_name grist.votredomaine.com;\n\n    ssl_certificate \u002Fetc\u002Fletsencrypt\u002Flive\u002Fgrist.votredomaine.com\u002Ffullchain.pem;\n    ssl_certificate_key \u002Fetc\u002Fletsencrypt\u002Flive\u002Fgrist.votredomaine.com\u002Fprivkey.pem;\n    ssl_protocols TLSv1.2 TLSv1.3;\n\n    # En-têtes de sécurité\n    add_header Strict-Transport-Security \"max-age=63072000; includeSubDomains\" always;\n    add_header X-Frame-Options SAMEORIGIN always;\n    add_header X-Content-Type-Options nosniff always;\n    add_header Referrer-Policy strict-origin-when-cross-origin always;\n\n    location \u002F {\n        proxy_pass http:\u002F\u002F127.0.0.1:8484;\n        proxy_set_header Host $host;\n        proxy_set_header X-Real-IP $remote_addr;\n        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n        proxy_set_header X-Forwarded-Proto $scheme;\n        proxy_http_version 1.1;\n        proxy_set_header Upgrade $http_upgrade;\n        proxy_set_header Connection \"upgrade\";\n        proxy_read_timeout 300s;\n    }\n}\n```\n\nObtenez le certificat puis activez le vhost :\n\n```bash\ncertbot certonly --nginx -d grist.votredomaine.com\nln -s \u002Fetc\u002Fnginx\u002Fsites-available\u002Fgrist.conf \u002Fetc\u002Fnginx\u002Fsites-enabled\u002F\nnginx -t && systemctl reload nginx\n```\n\nMettez ensuite à jour `APP_HOME_URL` dans le Compose et redémarrez le conteneur : `docker compose up -d`.",{"type":38,"title":67,"body":68},"Formules Grist avancées : VLOOKUP et références croisées","Grist remplace les VLOOKUP fragiles de Google Sheets par des **colonnes de référence** et des **fonctions de lookup typées**. Dans une table `Commandes` avec une colonne `Client` de type `Reference → Clients`, accéder au nom du client s'écrit simplement `$Client.Nom` — pas de VLOOKUP.\n\nPour des agrégations, Grist propose `lookupRecords()` et `lookupOne()` :\n\n```python\n# Dans la table Clients — montant total des commandes d'un client\nSUM(Commandes.lookupRecords(Client=$id).Montant)\n\n# Dans la table Commandes — récupérer le code postal du client\nClients.lookupOne(Nom=$Client.Nom).CodePostal\n\n# Calcul de marge avec import Python standard\nimport datetime\ndelai = (datetime.date.today() - $DateCommande).days\n$Montant * (1 - 0.02 * delai \u002F\u002F 30)  # remise progressive par mois\n```\n\nLes formules Python s'exécutent dans un **sandbox gVisor** (variable `GRIST_SANDBOX_FLAVOR=gvisor`) : le processus Python n'a pas accès au système de fichiers ni au réseau, ce qui isole les calculs même dans un contexte multi-tenant.",{"type":38,"title":70,"body":71},"Authentification SSO avec OIDC (facultatif)","Par défaut, `GRIST_DEFAULT_EMAIL` connecte automatiquement un seul utilisateur sans mot de passe — suffisant pour un usage solo ou une équipe de confiance sur réseau privé. Pour un déploiement multi-utilisateurs avec authentification réelle, Grist supporte **OpenID Connect (OIDC)** avec Authentik, Keycloak, Google Workspace ou tout provider compatible.\n\nAjoutez ces variables dans le Compose :\n\n```yaml\nenvironment:\n  GRIST_OIDC_IDP_ISSUER: \"https:\u002F\u002Fauth.votredomaine.com\u002Fapplication\u002Fo\u002Fgrist\u002F\"\n  GRIST_OIDC_IDP_CLIENT_ID: \"votre-client-id\"\n  GRIST_OIDC_IDP_CLIENT_SECRET: \"votre-client-secret\"\n  GRIST_OIDC_IDP_SCOPES: \"openid email profile\"\n  GRIST_OIDC_SP_HOST: \"https:\u002F\u002Fgrist.votredomaine.com\"\n```\n\nRetirer `GRIST_DEFAULT_EMAIL` dès qu'OIDC est configuré — les deux variables sont incompatibles. Le premier utilisateur qui se connecte via OIDC devient administrateur du site.",{"type":38,"title":73,"body":74},"Sauvegardes : volumes Docker et export","Les documents Grist résident dans le volume Docker `grist_data`, sous `\u002Fpersist\u002Fdocs\u002F`. Deux stratégies complémentaires :\n\n**Snapshot du volume** (sauvegarde complète, recommandé) : montez `\u002Fpersist\u002Fdocs\u002F` dans un job Backrest (disponible dans le catalogue ServOrbit). Backrest snapshote le dossier via restic et envoie les incréments chiffrés vers S3, Backblaze B2 ou SFTP — sans arrêter Grist.\n\n```bash\n# Sauvegarde manuelle d'urgence\ndocker run --rm \\\n  -v grist_data:\u002Fsource:ro \\\n  -v \u002Fbackups\u002Fgrist:\u002Fdest \\\n  alpine tar czf \u002Fdest\u002Fgrist-$(date +%Y%m%d).tar.gz -C \u002Fsource .\n```\n\n**Export par document** : dans Grist, menu Document → Export → `.grist` (format natif SQLite) ou CSV\u002FXLSX par table. L'export `.grist` est suffisant pour migrer un document vers une autre instance.\n\nGrist conserve également un **historique de snapshots par document** (Document → History) — pratique pour restaurer une version précédente sans quitter l'interface, jusqu'à la limite de rétention configurée.",{"type":38,"title":76,"body":77},"Dépannage courant","**Le conteneur redémarre en boucle** : vérifiez les logs (`docker compose logs grist`). La cause la plus fréquente est un `GRIST_SESSION_SECRET` vide ou trop court — il doit faire au moins 32 caractères hexadécimaux. Vérifiez aussi les permissions du volume : `docker exec grist ls -la \u002Fpersist`.\n\n**Erreurs CORS sur l'API** : si vous appelez `\u002Fapi\u002Fdocs\u002F…` depuis un domaine différent, ajoutez `GRIST_ALLOWED_HOSTS=grist.votredomaine.com` et assurez-vous que `APP_HOME_URL` correspond exactement à l'URL publique (avec `https:\u002F\u002F`, sans slash final).\n\n**Lenteur sur grands datasets** : Grist évalue toutes les formules à chaque modification. Sur des tables de plus de 100 000 lignes, limitez les `lookupRecords()` à des colonnes indexées et évitez les formules Python avec imports lourds dans des colonnes de trigger. La variable `GRIST_MAX_ROWS_PER_TABLE` (défaut non borné) permet de poser une limite préventive.\n\n**Problème d'accès après changement de domaine** : mettez à jour `APP_HOME_URL`, effacez les cookies du navigateur et redémarrez le conteneur. Les sessions actives utilisent l'ancienne URL et deviennent invalides.",{"type":79,"title":80,"intro":81,"headers":82,"rows":87,"conclusion":121},"comparison","Grist vs NocoDB vs Baserow : choisir son tableur open-source","Les trois outils occupent le créneau « Airtable open-source », mais avec des positionnements différents.",[83,84,85,86],"Critère","Grist","NocoDB","Baserow",[88,93,98,103,108,112,117],[89,90,91,92],"Stockage","SQLite par document (fichier .grist)","PostgreSQL ou MySQL (base partagée)","PostgreSQL (base partagée)",[94,95,96,97],"Formules","Python côté serveur (sandbox)","Pas de formules natives","Formules limitées, JS côté client",[99,100,101,102],"API REST","Automatique sur chaque document","Automatique sur chaque base","Automatique",[104,105,106,107],"Auth SSO","OIDC natif","LDAP, OIDC (Enterprise)","SSO payant (plans > Pro)",[109,110,111,111],"Sauvegardes","Fichier .grist par document","Dump PostgreSQL",[113,114,115,116],"Cas d'usage idéal","Modélisation de données, formules complexes","Remplacement Airtable orienté équipe","Interface no-code pour équipes métier",[118,119,120,120],"Ressources (démarrage)","1 Go RAM, Docker","2 Go RAM, Docker + PostgreSQL","Grist est le seul des trois à isoler chaque document dans un fichier SQLite autonome — ce qui simplifie la sauvegarde et la migration d'un document individuel. NocoDB et Baserow partagent une base PostgreSQL unique, ce qui facilite la gestion centralisée mais complique la portabilité d'un projet.",{"type":123,"body":124},"tip","Pour mettre à jour Grist, modifiez le tag d'image dans le Compose (`gristlabs\u002Fgrist:1.7.20` → version suivante), arrêtez le conteneur (`docker compose down`), puis redémarrez (`docker compose up -d`). Le volume `grist_data` persiste entre les versions. Consultez les release notes sur github.com\u002Fgristlabs\u002Fgrist-core avant chaque mise à jour — certaines versions introduisent des migrations de schéma qui ne sont pas réversibles.","Votre Airtable, sur votre serveur","Déployez Grist sur un VPS ServOrbit et modélisez vos données sans abonnement, sans vendor lock-in — API REST, formules Python, collaboration temps réel.","Déployer Grist","\u002Fapplications\u002Fdeveloppement\u002Fgrist",[130,148,167],{"id":131,"slug":132,"slugs":133,"title":137,"excerpt":138,"readTime":139,"views":140,"isPinned":19,"noindex":19,"publishedAt":141,"updatedAt":21,"category":142,"categories":143,"featuredImage":29,"bgImage":30,"posterImage":145,"relatedSolution":146},188,"self-host-nocobase-vps",{"fr":132,"en":134,"ar":135,"es":136},"self-host-nocobase-on-a-vps-no-code-platform-for-internal-tools","استضافة-nocobase-على-vps-منصة-بلا-كود-لأدواتك-الداخلية","alojar-nocobase-en-un-vps-no-code-herramientas-internas","Héberger NocoBase sur un VPS : no-code pour vos outils métier","Déployez NocoBase sur votre VPS — la plateforme no-code\u002Flow-code pour créer des outils internes, CRM et workflows. Apache-2.0, 23 k+ étoiles, v2.1.26.",10,1,"2026-07-22T00:00:00+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},[144],{"id":17,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fself-host-nocobase-vps-poster.svg",{"categorySlug":33,"appSlug":147},"nocobase",{"id":149,"slug":150,"slugs":151,"title":155,"excerpt":156,"readTime":18,"views":140,"isPinned":19,"noindex":157,"publishedAt":158,"updatedAt":159,"category":160,"categories":161,"featuredImage":29,"bgImage":30,"posterImage":163,"relatedSolution":164},157,"self-host-nocodb-vps",{"fr":150,"en":152,"ar":153,"es":154},"how-to-self-host-nocodb-on-a-vps","كيفية-استضافة-nocodb-ذاتيا-على-خادم-vps","como-autoalojar-nocodb-en-un-vps","Comment auto-héberger NocoDB sur un VPS","Déployez NocoDB sur votre VPS : l'alternative open source et auto-hébergée à Airtable. Transformez toute base de données en tableur intelligent avec API REST et GraphQL.",true,"2026-01-20T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":17,"name":23,"slug":24,"color":25,"icon":26},[162],{"id":17,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fself-host-nocodb-vps-poster.svg",{"categorySlug":165,"appSlug":166},"bases-de-donnees","nocodb",{"id":168,"slug":169,"slugs":170,"title":174,"excerpt":175,"readTime":176,"views":18,"isPinned":19,"noindex":19,"publishedAt":177,"updatedAt":178,"category":179,"categories":184,"featuredImage":29,"bgImage":30,"posterImage":186,"relatedSolution":187},67,"heberger-meilisearch-vps",{"fr":169,"en":171,"ar":172,"es":173},"hosting-meilisearch-on-a-vps","استضافة-meilisearch-على-خادم-vps","alojar-meilisearch-en-un-vps","Héberger Meilisearch sur un VPS","Hébergez Meilisearch sur votre VPS : moteur de recherche instantané, tolérant aux fautes et typo-tolérant. Guide Docker, master key et SSL.",5,"2026-04-14T00:00:00+00:00","2026-09-08T22:00:01+00:00",{"id":180,"name":181,"slug":165,"color":182,"icon":183},6,"Bases de données","bg-teal-500\u002F10 text-teal-400","database",[185],{"id":180,"name":181,"slug":165,"color":182,"icon":183},"\u002Fblog\u002Fcovers\u002Fheberger-meilisearch-vps-poster.svg",{"categorySlug":165,"appSlug":188},"meilisearch",1794270789772]