Pourquoi self-héberger Payload CMS sur un VPS
Payload CMS adopte une approche radicalement code-first : votre schéma de contenu est défini en TypeScript dans des fichiers de configuration, versionnés avec Git, et depuis sa version 3 Payload s'installe directement dans une application Next.js via le App Router. Cela signifie qu'un VPS vous permet d'héberger le CMS et le site front dans un seul et même processus Node, partageant le build et le runtime. Vous obtenez un typage de bout en bout, des migrations de schéma gérées dans le code, et aucune dépendance à une interface graphique pour modéliser vos contenus. Le self-hosting est ici l'option naturelle : Payload est pensé pour être déployé comme n'importe quelle app Next.js, et un VPS vous donne le contrôle de la base (MongoDB ou PostgreSQL), des uploads et des variables d'environnement, sans plateforme intermédiaire.
Bénéfices concrets
- Schéma de contenu défini en TypeScript et versionné avec Git : revue de code et historique complets
- CMS et front Next.js dans un seul runtime : un seul build, un seul process à déployer
- Typage de bout en bout entre la config Payload, l'API et le front, sans génération manuelle
- Choix de la base : MongoDB ou PostgreSQL via les adaptateurs officiels
- Migrations de schéma pilotées par le code (
payload migrate), reproductibles entre environnements - Local API : accès direct aux données sans appel HTTP depuis le code serveur Next.js
Prérequis matériels et logiciels
Payload reposant sur Next.js, le build est exigeant : prévoyez un VPS de 2 vCPU et 4 Go de RAM pour builder et faire tourner l'application confortablement, surtout si le front Next.js est conséquent. Installez Node.js 20 LTS, Docker et Docker Compose. Côté base, provisionnez MongoDB 7 ou PostgreSQL 16 selon l'adaptateur choisi (@payloadcms/db-mongodb ou @payloadcms/db-postgres). Pointez votre domaine vers l'IP du VPS. Comptez 15 Go de disque pour les node_modules, le build .next, les uploads et les sauvegardes de base.
Déploiement pas à pas
Choisir et configurer l'adaptateur de base
Dans payload.config.ts, déclarez l'adaptateur : mongooseAdapter pour MongoDB ou postgresAdapter pour PostgreSQL, en lisant l'URL de connexion depuis DATABASE_URI. Ce choix est structurant : PostgreSQL impose des migrations, MongoDB est plus souple sur le schéma.
Définir le secret et builder l'app Next.js
Renseignez PAYLOAD_SECRET (clé de chiffrement des tokens) dans l'environnement. Lancez npm run build : comme Payload 3 vit dans Next.js, cette commande compile à la fois l'admin Payload et votre front. Surveillez la RAM pendant le build.
Conteneuriser avec Docker Compose
Créez un Dockerfile node:20-alpine qui build l'app et lance npm start, puis un docker-compose.yml reliant le service app à un service mongo ou postgres. Montez un volume pour les uploads et passez DATABASE_URI et PAYLOAD_SECRET en variables. Lancez docker compose up -d.
Exécuter les migrations (PostgreSQL)
Si vous utilisez l'adaptateur PostgreSQL, appliquez le schéma avec npm run payload migrate après le démarrage des conteneurs. Avec MongoDB, le schéma est appliqué automatiquement, aucune migration manuelle n'est nécessaire.
Configurer Nginx en reverse proxy
Pointez un vhost vers http://127.0.0.1:3000 (port Next.js par défaut). Augmentez client_max_body_size pour les uploads de médias et ajoutez les en-têtes X-Forwarded-Proto pour que Payload génère des URLs HTTPS correctes.
Sécuriser avec SSL et fixer l'URL serveur
Exécutez certbot --nginx -d mondomaine.ma, puis définissez serverURL: 'https://mondomaine.ma' dans payload.config.ts. Cette URL conditionne les liens des médias, les emails de réinitialisation et le bon fonctionnement du panneau admin derrière le proxy.
Payload CMS vs Strapi : quel CMS headless self-héberger ?
| Critère | Payload CMS | Strapi |
|---|---|---|
| Approche de configuration | Code-first en TypeScript, versionné avec Git | GUI-first via le Content-Type Builder |
| Intégration front | Native dans Next.js (un seul runtime) | Découplé, front et CMS séparés |
| Bases supportées | MongoDB et PostgreSQL | PostgreSQL, MySQL, SQLite |
| Typage | TypeScript de bout en bout natif | Types générés, intégration moins serrée |
| Accès aux données serveur | Local API sans appel HTTP | API REST/GraphQL via HTTP |
| Modélisation du contenu | Dans le code, par les développeurs | Dans l'interface, accessible aux non-dev |
| RAM nécessaire au build | Élevée (build Next.js) | Élevée (build admin React) |
| Idéal pour | Équipes dev, projets Next.js typés | Équipes mixtes, modélisation visuelle |
Exploitez la Local API de Payload dans vos composants serveur Next.js : au lieu d'appeler votre propre API via fetch, importez getPayload et interrogez la base directement (payload.find({ collection: 'posts' })). Vous supprimez un aller-retour HTTP et gagnez en latence comme en sécurité. Pour les médias, branchez le plugin @payloadcms/storage-s3 afin de stocker les uploads hors du VPS, et automatisez un dump quotidien de votre base via un cron pour garantir des sauvegardes hors-serveur.