Strapi : CMS headless self-hosted
Strapi est un CMS headless open-source, base Node.js. API REST et GraphQL generees automatiquement. Idеal pour decoupler un backoffice (Strapi) d'un frontend (Next.js, Nuxt, mobile).
Introduction
Strapi vous permet de :
- Definir des content types via interface web (Content-Type Builder)
- Acceder a vos donnees via REST + GraphQL automatiquement
- Gerer les permissions (roles, plugins)
- Plugin marketplace (i18n, email, upload S3, etc.)
- Webhooks, locales, drafts/published
Stack typique : Strapi (backend + admin) + Next.js (frontend) + PostgreSQL (db) + S3/MinIO (medias).
Prerequis
- VPS Linux 2 vCPU, 4 Go RAM, 20 Go SSD
- Node.js 18+
- PostgreSQL 14+
- Acces root
Etape 1 : Preparer PostgreSQL
sudo apt install -y postgresql
sudo -u postgres psql
CREATE DATABASE strapi;
CREATE USER strapiuser WITH ENCRYPTED PASSWORD 'pass-fort';
GRANT ALL PRIVILEGES ON DATABASE strapi TO strapiuser;
\c strapi
GRANT ALL ON SCHEMA public TO strapiuser;
\q
Etape 2 : Creer le projet Strapi
cd /var/www
npx create-strapi-app@latest strapi --quickstart --no-run
Suivez l'assistant :
- Choose between databases: postgres
- Database name:
strapi - Host:
127.0.0.1 - Port:
5432 - Username:
strapiuser - Password:
pass-fort - Enable SSL connection: N
cd /var/www/strapi
Etape 3 : Premier demarrage
npm run build
npm run start
Strapi ecoute sur :1337. Visitez http://IP_VPS:1337/admin.
Creez le premier compte admin.
Etape 4 : Definir un Content Type
Dans l'admin : Content-Type Builder > Create new collection type.
Exemple "Article" :
- title : Text
- slug : UID (genere depuis title)
- content : Rich Text (Markdown)
- cover : Media (single)
- author : Relation > many-to-one > User
- publishedAt : Datetime
Save. Strapi genere automatiquement :
- API REST :
GET /api/articles,POST /api/articles, etc. - Schema GraphQL si plugin GraphQL installe
Etape 5 : Gerer les permissions
Settings > Users & Permissions Plugin > Roles.
- Public : qui peut acceder sans auth
- Authenticated : qui peut acceder en etant logge
Pour rendre les articles lisibles publiquement :
Public > Article > cochez find et findOne.
Etape 6 : Tester l'API
curl http://IP_VPS:1337/api/articles
Reponse JSON. Filtrer / paginer :
curl 'http://IP_VPS:1337/api/articles?filters[title][$contains]=hello&pagination[limit]=10'
Populer les relations :
curl 'http://IP_VPS:1337/api/articles?populate=cover,author'
Etape 7 : Token API pour acces machine
Settings > API Tokens > Create.
Type : Read-only, Full access, ou custom. Notez le token genere (une seule fois affiche).
curl http://IP_VPS:1337/api/articles \
-H "Authorization: Bearer VOTRE_TOKEN"
Etape 8 : Activer GraphQL
npm install @strapi/plugin-graphql
Restart Strapi. GraphQL playground sur :1337/graphql (en dev).
Exemple query :
query {
articles {
data {
attributes {
title
slug
content
}
}
}
}
Etape 9 : Upload S3 / MinIO
Pour stocker les medias ailleurs que sur disque local :
npm install @strapi/provider-upload-aws-s3
config/plugins.js :
module.exports = ({ env }) => ({
upload: {
config: {
provider: 'aws-s3',
providerOptions: {
accessKeyId: env('AWS_ACCESS_KEY_ID'),
secretAccessKey: env('AWS_ACCESS_SECRET'),
region: env('AWS_REGION'),
params: {
Bucket: env('AWS_BUCKET'),
},
},
},
},
});
.env :
AWS_ACCESS_KEY_ID=xxx
AWS_ACCESS_SECRET=xxx
AWS_REGION=eu-west-3
AWS_BUCKET=mon-bucket
Etape 10 : Mise en prod avec PM2
sudo npm install -g pm2
cd /var/www/strapi
pm2 start npm --name strapi -- start
pm2 startup
pm2 save
Devant Strapi, configurez Nginx en reverse proxy :
server {
listen 443 ssl http2;
server_name strapi.votre-domaine.fr;
client_max_body_size 50M;
location / {
proxy_pass http://localhost:1337;
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;
}
}
Etape 11 : Backups
PostgreSQL :
pg_dump -U strapiuser -h 127.0.0.1 strapi | gzip > strapi-$(date +%F).sql.gz
Uploads (si local) :
tar czf strapi-uploads-$(date +%F).tar.gz /var/www/strapi/public/uploads
Strapi a aussi un module export/import :
npx strapi export --no-encrypt
npx strapi import --file export.tar.gz
Etape 12 : Variables d'env critiques
/var/www/strapi/.env :
HOST=0.0.0.0
PORT=1337
APP_KEYS=cle1,cle2,cle3,cle4
API_TOKEN_SALT=...
ADMIN_JWT_SECRET=...
TRANSFER_TOKEN_SALT=...
JWT_SECRET=...
DATABASE_CLIENT=postgres
DATABASE_HOST=127.0.0.1
DATABASE_PORT=5432
DATABASE_NAME=strapi
DATABASE_USERNAME=strapiuser
DATABASE_PASSWORD=pass-fort
⚠️ Generez des secrets robustes en prod :
openssl rand -base64 16
Depannage
"ECONNREFUSED" sur PostgreSQL
Verifiez que PG accepte les connexions locales :
sudo nano /etc/postgresql/14/main/pg_hba.conf
host all all 127.0.0.1/32 md5
sudo systemctl restart postgresql
Admin panel 502
Strapi pas demarre, ou build en cours :
pm2 logs strapi
Verifiez aussi npm run build execute apres chaque update.
Lent au startup
Strapi 4 charge tous les content types, plugins, hooks au boot. Normal de prendre 30s. En cluster, lancez plusieurs instances derriere un load balancer.
Memory issues
Augmentez la RAM du VPS, ou limitez NODE_OPTIONS=--max-old-space-size=2048 dans .env.
Commandes utiles
npm run develop # mode dev (hot reload)
npm run build # build production
npm run start # start production
npm run console # repl Strapi
npx strapi export --no-encrypt # backup complet
npx strapi import --file f.tar.gz
# Logs
pm2 logs strapi
sudo tail -f /var/log/postgresql/postgresql-14-main.log
Conclusion
Strapi vous donne :
- Backoffice editable + API automatique
- Permissions fines et roles
- Multi-tenant, i18n, drafts
- API REST et GraphQL
- Decouplage backend / frontend
Pour aller plus loin :
- Couplez avec Next.js pour le frontend (ISR)
- Activez Cloudinary pour des medias optimises
- Pour gros volumes, utilisez Strapi Cloud ou un cluster sur Kubernetes
Ressources
- Documentation officielle : https://docs.strapi.io
- Site officiel : https://strapi.io
- Marketplace plugins : https://market.strapi.io
- Github : https://github.com/strapi/strapi



















