[{"data":1,"prerenderedAt":233},["ShallowReactive",2],{"seo-verification":3,"blog-deployer-laravel-vps-octane-fr":6},{"google":4,"bing":5},"EycwPY2XMyTkVzas3n1ygeNJFGAH513qrMjfDljzsMQ","",{"key":7,"data":8},"blog-deployer-laravel-vps-octane-fr",{"id":9,"slug":10,"slugs":11,"title":14,"excerpt":15,"readTime":16,"views":17,"isPinned":18,"publishedAt":19,"updatedAt":20,"category":21,"categories":27,"featuredImage":29,"bgImage":30,"posterImage":31,"relatedSolution":29,"intro":32,"sections":33,"ctaTitle":29,"ctaBody":29,"ctaButton":141,"ctaUrl":142,"relatedPosts":143},436,"deployer-laravel-vps-octane",{"fr":10,"en":12,"ar":13,"es":12},"laravel-octane-vps-frankenphp-docker-traefik","laravel-octane-على-vps-frankenphp-docker-traefik","Laravel Octane sur VPS : FrankenPHP, Docker et Traefik","Migrer vers Laravel Octane avec FrankenPHP en Docker Compose derrière Traefik : cycle de vie partagé, checklist compatibilité et zero-downtime en production.",11,0,false,"2026-10-12T00:00:00+00:00","2026-10-13T14:10:28+00:00",{"id":22,"name":23,"slug":24,"color":25,"icon":26},4,"Développement","developpement","bg-warning\u002F10 text-warning","dev",[28],{"id":22,"name":23,"slug":24,"color":25,"icon":26},null,"\u002Fblog\u002Fcovers\u002Fbg.svg","\u002Fblog\u002Fcovers\u002Fdeployer-laravel-vps-octane-poster.svg","PHP-FPM démarre un processus par requête : efficace pour les petites apps, mais coûteux dès que le trafic monte. Laravel Octane change de paradigme — l'application est chargée une seule fois en mémoire et répond à des milliers de requêtes sans se réinitialiser. Le gain est réel : les benchmarks officiels Laravel montrent des multiplicateurs de 4× à 6× sur les requêtes\u002Fseconde par rapport à PHP-FPM 8.3. FrankenPHP, driver Octane recommandé depuis Laravel 11, intègre le serveur HTTP directement dans le binaire PHP — plus besoin de nginx en frontal. Sur un VPS avec accès root, Docker Compose et Traefik, la migration est propre et reproductible.",[34,38,49,52,83,86,97,131,135,138],{"type":35,"title":36,"body":37},"h2","PHP-FPM vs Laravel Octane — ce qui change vraiment","PHP-FPM suit le modèle \"shared nothing\" : chaque requête charge le framework depuis zéro, exécute le code, libère toute la mémoire. C'est robuste par construction — une fuite dans une requête meurt avec elle. Octane rompt ce contrat. L'application est bootstrappée une fois, puis les requêtes s'enchaînent dans le même processus. Le gain de performance est massif, mais la responsabilité du développeur augmente.",{"type":39,"title":40,"items":41},"ul","Les six différences structurelles à connaître",[42,43,44,45,46,47,48],"**Cycle de vie partagé** — le conteneur IoC de Laravel, les providers et les singletons sont instanciés une fois et persistent entre toutes les requêtes d'un worker. Une valeur écrite dans un singleton en requête N est encore là en requête N+1.","**Gain de performance documenté** — les benchmarks de la documentation officielle Laravel Octane indiquent 4× à 6× plus de requêtes\u002Fseconde face à PHP-FPM 8.3 sur des endpoints typiques, grâce à l'élimination du bootstrap PHP à chaque requête.","**Variables statiques = fuites garanties** — toute propriété `static` écrite pendant une requête pollue les suivantes. Les Facades Laravel cachent des références statiques ; certaines sont nettoyées par Octane, d'autres non.","**Fichiers statiques servis par FrankenPHP** — le binaire intègre un serveur HTTP complet. Sur un VPS, plus besoin de nginx devant PHP : FrankenPHP gère TLS, HTTP\u002F2 et HTTP\u002F3 nativement, mais derrière Traefik on lui délègue uniquement HTTP en clair sur le réseau Docker interne.","**Mémoire RSS stable ≠ mémoire fuitée** — la mémoire du process monte au démarrage (chargement du framework) puis se stabilise. Une vraie fuite se détecte par une croissance continue sur des milliers de requêtes, pas par le niveau initial.","**Workers et concurrence** — Octane démarre `--workers=N` processus (FrankenPHP utilise des threads Zend Engine). Chaque worker garde son propre état ; pas de partage mémoire entre workers, mais un même worker traite ses requêtes séquentiellement.","**Compatibilité Laravel 10 et 11** — Octane 2.x supporte Laravel 10+. FrankenPHP comme driver est disponible depuis `laravel\u002Foctane` 2.3. PHP 8.2 minimum, PHP 8.3 recommandé.",{"type":35,"title":50,"body":51},"Prérequis avant de démarrer","Un VPS avec **2 Go de RAM minimum** (4 Go recommandés pour un stack complet avec Redis et queue workers), accès root, Docker 25+ et Docker Compose v2. L'application doit tourner sur **Laravel 10 ou 11**, avec `laravel\u002Foctane` 2.x installé (`composer require laravel\u002Foctane`). Traefik 3.x gérera les certificats Let's Encrypt et le routage HTTPS. Aucun nginx supplémentaire n'est nécessaire : FrankenPHP remplace entièrement la couche HTTP.",{"type":53,"title":54,"steps":55},"steps","Déployer Laravel Octane + FrankenPHP + Traefik en Docker Compose",[56,59,62,65,68,71,74,77,80],{"title":57,"body":58},"Installer laravel\u002Foctane et publier la configuration","Dans votre projet Laravel :\n\n```bash\ncomposer require laravel\u002Foctane\nphp artisan octane:install --server=frankenphp\n```\n\nCela publie `config\u002Foctane.php` et ajoute les variables d'environnement dans `.env.example`. Vérifiez que `OCTANE_SERVER=frankenphp` est bien défini.",{"title":60,"body":61},"Écrire le Dockerfile FrankenPHP","```dockerfile\nFROM dunglas\u002Ffrankenphp:1-php8.3-alpine\n\nRUN install-php-extensions \\\n    pdo_mysql \\\n    redis \\\n    opcache \\\n    pcntl \\\n    zip \\\n    intl\n\nWORKDIR \u002Fapp\n\nCOPY --chown=www-data:www-data . .\n\nRUN composer install --no-dev --optimize-autoloader --no-interaction \\\n && php artisan config:cache \\\n && php artisan route:cache \\\n && php artisan view:cache\n\nEXPOSE 8000\n\nCMD [\"php\", \"artisan\", \"octane:frankenphp\", \"--host=0.0.0.0\", \"--port=8000\", \"--workers=4\", \"--max-requests=500\"]\n```\n\nL'option `--max-requests=500` redémarre le worker après 500 requêtes : un filet de sécurité contre les fuites mémoire résiduelles. Réduisez à 100 en rodage, puis augmentez si la mémoire reste stable.",{"title":63,"body":64},"Écrire le docker-compose.yml complet","```yaml\nservices:\n  app:\n    build: .\n    restart: unless-stopped\n    environment:\n      APP_ENV: production\n      APP_KEY: ${APP_KEY}\n      DB_CONNECTION: mysql\n      DB_HOST: db\n      DB_DATABASE: ${DB_DATABASE}\n      DB_USERNAME: ${DB_USERNAME}\n      DB_PASSWORD: ${DB_PASSWORD}\n      REDIS_HOST: redis\n      CACHE_DRIVER: redis\n      SESSION_DRIVER: redis\n      QUEUE_CONNECTION: redis\n      OCTANE_SERVER: frankenphp\n    networks:\n      - internal\n      - traefik\n    labels:\n      - \"traefik.enable=true\"\n      - \"traefik.http.routers.app.rule=Host(`${DOMAIN}`)\"\n      - \"traefik.http.routers.app.entrypoints=websecure\"\n      - \"traefik.http.routers.app.tls.certresolver=letsencrypt\"\n      - \"traefik.http.services.app.loadbalancer.server.port=8000\"\n    depends_on:\n      db:\n        condition: service_healthy\n      redis:\n        condition: service_healthy\n\n  worker:\n    build: .\n    restart: unless-stopped\n    command: [\"php\", \"artisan\", \"queue:work\", \"redis\", \"--sleep=3\", \"--tries=3\", \"--max-time=3600\"]\n    environment:\n      APP_ENV: production\n      APP_KEY: ${APP_KEY}\n      DB_HOST: db\n      DB_DATABASE: ${DB_DATABASE}\n      DB_USERNAME: ${DB_USERNAME}\n      DB_PASSWORD: ${DB_PASSWORD}\n      REDIS_HOST: redis\n      QUEUE_CONNECTION: redis\n    networks:\n      - internal\n    depends_on:\n      db:\n        condition: service_healthy\n      redis:\n        condition: service_healthy\n\n  scheduler:\n    build: .\n    restart: unless-stopped\n    command: [\"sh\", \"-c\", \"while true; do php artisan schedule:run >> \u002Fdev\u002Fnull 2>&1; sleep 60; done\"]\n    environment:\n      APP_ENV: production\n      APP_KEY: ${APP_KEY}\n      DB_HOST: db\n      DB_DATABASE: ${DB_DATABASE}\n      DB_USERNAME: ${DB_USERNAME}\n      DB_PASSWORD: ${DB_PASSWORD}\n      REDIS_HOST: redis\n    networks:\n      - internal\n    depends_on:\n      db:\n        condition: service_healthy\n\n  db:\n    image: mysql:8.0\n    restart: unless-stopped\n    environment:\n      MYSQL_DATABASE: ${DB_DATABASE}\n      MYSQL_USER: ${DB_USERNAME}\n      MYSQL_PASSWORD: ${DB_PASSWORD}\n      MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}\n    volumes:\n      - db_data:\u002Fvar\u002Flib\u002Fmysql\n    networks:\n      - internal\n    healthcheck:\n      test: [\"CMD\", \"mysqladmin\", \"ping\", \"-h\", \"localhost\"]\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  redis:\n    image: redis:7-alpine\n    restart: unless-stopped\n    volumes:\n      - redis_data:\u002Fdata\n    networks:\n      - internal\n    healthcheck:\n      test: [\"CMD\", \"redis-cli\", \"ping\"]\n      interval: 10s\n      timeout: 3s\n      retries: 5\n\nvolumes:\n  db_data:\n  redis_data:\n\nnetworks:\n  internal:\n  traefik:\n    external: true\n```",{"title":66,"body":67},"Déployer Traefik avec certificats automatiques","Créez un réseau Docker partagé puis démarrez Traefik :\n\n```bash\ndocker network create traefik\n```\n\n`traefik.yml` :\n\n```yaml\nentryPoints:\n  web:\n    address: \":80\"\n    http:\n      redirections:\n        entryPoint:\n          to: websecure\n          scheme: https\n  websecure:\n    address: \":443\"\n\ncertificatesResolvers:\n  letsencrypt:\n    acme:\n      email: admin@exemple.com\n      storage: \u002Fletsencrypt\u002Facme.json\n      httpChallenge:\n        entryPoint: web\n\nproviders:\n  docker:\n    exposedByDefault: false\n    network: traefik\n\napi:\n  dashboard: false\n```\n\n```bash\nmkdir -p \u002Fopt\u002Ftraefik\u002Fletsencrypt\ntouch \u002Fopt\u002Ftraefik\u002Fletsencrypt\u002Facme.json\nchmod 600 \u002Fopt\u002Ftraefik\u002Fletsencrypt\u002Facme.json\ndocker compose -f \u002Fopt\u002Ftraefik\u002Fdocker-compose.yml up -d\n```",{"title":69,"body":70},"Préparer le fichier .env de production","Variables critiques à définir sur le VPS :\n\n```bash\nAPP_ENV=production\nAPP_DEBUG=false\nAPP_KEY=base64:...  # généré avec php artisan key:generate\nDOMAIN=votre-domaine.com\nDB_DATABASE=laravel\nDB_USERNAME=laravel\nDB_PASSWORD=mot_de_passe_fort\nDB_ROOT_PASSWORD=root_mot_de_passe\nOCTANE_SERVER=frankenphp\nCACHE_DRIVER=redis\nSESSION_DRIVER=redis\nQUEUE_CONNECTION=redis\n```\n\nNe committez jamais `.env` dans git. Sur le VPS, gérez-le avec `scp` ou un secret manager.",{"title":72,"body":73},"Exécuter les migrations sans interruption","Avant de basculer vers la nouvelle version, exécutez les migrations depuis un conteneur éphémère qui partage le réseau interne :\n\n```bash\ndocker compose run --rm app php artisan migrate --force\n```\n\nPour un déploiement zero-downtime, utilisez le flag `--step` sur les migrations qui ajoutent des colonnes NOT NULL — ajoutez d'abord la colonne nullable, déployez l'app, puis ajoutez la contrainte dans une seconde migration.",{"title":75,"body":76},"Démarrer la stack et vérifier le healthcheck","```bash\ndocker compose up -d --build\ndocker compose ps\n```\n\nAttendez que `db` et `redis` passent au statut `healthy` avant qu'`app` démarre (géré par `depends_on: condition: service_healthy`).\n\nVérifiez les logs Octane :\n\n```bash\ndocker compose logs -f app\n```\n\nLa sortie normale ressemble à :\n```\nINFO  Server running on http:\u002F\u002F0.0.0.0:8000\nINFO  FrankenPHP workers: 4\n```",{"title":78,"body":79},"Vérifier l'état avec octane:status","```bash\ndocker compose exec app php artisan octane:status\n```\n\nCette commande affiche le serveur actif (frankenphp), le nombre de workers en cours d'exécution et le statut global. Un retour `running` confirme que les workers répondent. En cas de blocage, `octane:reload` redémarre les workers sans couper le serveur.",{"title":81,"body":82},"Configurer le rechargement à chaud pour les déploiements","Lors d'un nouveau déploiement, reconstruisez l'image et rechargez sans downtime :\n\n```bash\ndocker compose build app worker scheduler\ndocker compose up -d --no-deps app worker scheduler\n```\n\nDockerfile en place, cette séquence remplace les conteneurs un par un. Pour Octane, le signal de rechargement (SIGUSR1) recharge les workers sans fermer les connexions actives. Docker Compose gère l'envoi du signal automatiquement via `restart: unless-stopped`.",{"type":35,"title":84,"body":85},"Checklist de compatibilité avant de basculer en production","La migration vers Octane ne nécessite pas de réécrire l'application, mais quelques patterns courants cassent silencieusement. Parcourez cette checklist sur votre code avant le premier déploiement.",{"type":39,"title":87,"items":88},"8 points à vérifier impérativement",[89,90,91,92,93,94,95,96],"**Singletons avec état mutable** — tout service enregistré avec `$this->app->singleton()` qui stocke des données spécifiques à une requête (utilisateur courant, locale, tenant ID) doit être réinitialisé dans un `OctaneServiceProvider` via `Octane::tick()` ou en implémentant un listener `RequestReceived`. Audit : `grep -r 'singleton' app\u002FProviders`.","**Sessions** — avec `SESSION_DRIVER=redis`, les sessions survivent correctement entre requêtes. Le driver `file` peut créer des race conditions si plusieurs workers écrivent simultanément. Migration vers `redis` ou `database` recommandée avant le passage à Octane.","**Connexions base de données** — Octane maintient des connexions DB persistantes par worker. Configurez `DB_POOL_MIN` et `DB_POOL_MAX` dans `config\u002Fdatabase.php` si vous utilisez un pool custom. Vérifiez que MySQL accepte `max_connections ≥ workers × replicas`.","**Variables statiques dans les modèles ou services** — `static $cache = []` dans un Eloquent model ou un repository persiste entre requêtes. Remplacez par une injection de dépendance avec scope requête, ou videz explicitement dans le listener `RequestTerminated`.","**Event listeners non idempotents** — un listener enregistré dans `boot()` d'un ServiceProvider n'est enregistré qu'une fois, mais s'exécute à chaque requête qui déclenche l'événement. Pas de problème en soi, sauf si le listener accumule un état global (compteur, tableau statique).","**Jobs et queues** — les Jobs ne tournent pas dans le process Octane principal mais dans le conteneur `worker` séparé. Ils gardent le cycle PHP-FPM classique. Aucune adaptation requise pour le code des Jobs eux-mêmes.","**Fichiers uploadés et stockage** — `Storage::disk('local')` fonctionne normalement. Attention au chemin `storage_path()` dans un conteneur Docker : montez un volume pour `\u002Fapp\u002Fstorage` afin que les fichiers persistent entre les rebuilds d'image.","**Packages tiers** — certains packages Laravel (Debugbar, Telescope) injectent des middlwares qui accumulent des données en mémoire. Désactivez-les en production avec `APP_ENV=production` ou via la condition dans `config\u002Fdebugbar.php`. Vérifiez la compatibilité Octane sur le dépôt de chaque package.",{"type":98,"title":99,"headers":100,"rows":105},"comparison","FrankenPHP vs Swoole vs RoadRunner : choisir son driver Octane",[101,102,103,104],"Critère","FrankenPHP","Swoole","RoadRunner",[106,111,116,121,126],[107,108,109,110],"Installation","Image Docker officielle `dunglas\u002Ffrankenphp` — zéro extension PECL à compiler","Extension PECL `swoole` — nécessite `pecl install swoole` ou une image custom","Binaire Go séparé (`roadrunner`) — téléchargé via Composer (`spiral\u002Froadrunner`)",[112,113,114,115],"HTTP\u002F2 et HTTP\u002F3","Natif — FrankenPHP est construit sur Caddy qui supporte HTTP\u002F3 (QUIC) d'office","HTTP\u002F2 supporté, HTTP\u002F3 non natif","HTTP\u002F2 via plugin, HTTP\u002F3 non supporté nativement",[117,118,119,120],"Compatibilité extensions PHP","Très large — basé sur PHP-FPM officiel, la majorité des extensions s'installent normalement","Incompatibilités connues avec certaines extensions bloquantes (ex. ext-curl dans certains modes)","Large, mais certaines extensions PECL complexes peuvent nécessiter des adaptations",[122,123,124,125],"Recommandation officielle Laravel","Driver recommandé depuis Laravel 11 (2024), décrit en premier dans la documentation Octane","Premier driver historique, toujours supporté mais moins mis en avant","Supporté, alternatif à Swoole, courant dans les écosystèmes Symfony\u002FSpiral",[127,128,129,130],"Complexité ops","Faible — un seul conteneur, Dockerfile minimal, pas de démon séparé","Moyenne — l'extension swoole doit être compilée avec la bonne version PHP","Moyenne — le binaire RoadRunner doit être synchronisé avec la version du package Composer",{"type":132,"title":133,"body":134},"tip","Surveiller Octane en production avec octane:status","La commande `php artisan octane:status` interroge le serveur FrankenPHP en temps réel et indique le nombre de workers actifs, les workers en cours de traitement d'une requête et l'état global (`running` \u002F `stopped`). Intégrez-la dans votre monitoring :\n\n```bash\n# Vérification simple dans un script de health-check\ndocker compose exec -T app php artisan octane:status | grep -q 'running' && echo OK || echo FAIL\n```\n\nPour recharger les workers sans couper le trafic (après un `git pull` sans rebuild d'image) :\n\n```bash\ndocker compose exec app php artisan octane:reload\n```\n\nSuivez la mémoire RSS du process principal sur la durée : une augmentation continue après des milliers de requêtes signale une fuite. La commande `docker stats app` donne la mémoire en temps réel ; croisez avec `--max-requests=N` pour forcer le recyclage préventif.",{"type":35,"title":136,"body":137},"Dépannage : erreurs fréquentes en production","**Fuite mémoire progressive** : la mémoire du conteneur `app` croît sans jamais redescendre. Cause probable : un singleton accumule des données par requête. Audit avec `php artisan octane:status` sur plusieurs milliers de requêtes. Réduisez `--max-requests` à 100 en attendant d'identifier la source avec Laravel Telescope (en staging) ou un profiler comme Blackfire.\n\n**502 Bad Gateway Traefik** : Traefik ne peut plus joindre le conteneur `app` sur le port 8000. Vérifiez que le conteneur est sur le réseau `traefik` (`docker inspect app | jq '.[0].NetworkSettings.Networks'`), que le label `traefik.http.services.app.loadbalancer.server.port=8000` correspond bien au port exposé, et que le conteneur est `healthy` (`docker compose ps`). Un 502 au démarrage est souvent un `depends_on` manquant vers le conteneur `db`.\n\n**Worker qui redémarre en boucle** : Octane tue et recrée un worker si celui-ci ne répond plus dans le timeout configuré. Cherchez un `FATAL` dans `docker compose logs app`. Cause la plus fréquente : une migration non exécutée qui lève une `QueryException` dès le bootstrap. Lancez `docker compose run --rm app php artisan migrate --force` avant de démarrer la stack.\n\n**Sessions perdues entre requêtes** : `SESSION_DRIVER=file` avec plusieurs workers peut provoquer des lectures sur un fichier en cours d'écriture. Basculez sur `SESSION_DRIVER=redis` — le conteneur `redis` est déjà dans le `docker-compose.yml` ci-dessus.\n\n**Timezone ou locale incorrecte** : dans un conteneur Alpine, la timezone par défaut est UTC. Ajoutez `APP_TIMEZONE=Africa\u002FCasablanca` (ou votre timezone) dans `.env` et `RUN apk add --no-cache tzdata` dans le Dockerfile si des extensions système lisent `\u002Fetc\u002Flocaltime`.",{"type":35,"title":139,"body":140},"Pour aller plus loin","Vous avez maintenant une stack Laravel Octane fonctionnelle sur VPS. Les articles suivants couvrent les étapes naturelles autour de ce déploiement : [Déployer Laravel sur un VPS](\u002Fblog\u002Fdeployer-laravel-vps) décrit la configuration de base sans Octane, utile pour comprendre les différences. [Déployer avec Traefik](\u002Fblog\u002Fdeployer-avec-traefik) approfondit la configuration du reverse proxy (middlewares, rate-limiting, dashboard sécurisé). [Docker Compose production checklist](\u002Fblog\u002Fdocker-compose-production-checklist) liste les 15 points à vérifier avant de considérer un Compose production-ready. [Héberger Redis sur VPS](\u002Fblog\u002Fheberger-redis-vps) détaille la persistance, l'authentification et les limites mémoire de Redis en production. [Checklist de migration PHP](\u002Fblog\u002Fphp-82-fin-de-vie-checklist-migration) est à lire si votre application tourne encore sur PHP 8.2.","Voir les VPS ServOrbit","\u002Fvps-cloud",[144,161,180,196,219],{"id":145,"slug":146,"slugs":147,"title":151,"excerpt":152,"readTime":22,"views":17,"isPinned":18,"publishedAt":153,"updatedAt":154,"category":155,"categories":156,"featuredImage":29,"bgImage":30,"posterImage":158,"relatedSolution":159},5,"deployer-laravel-vps",{"fr":146,"en":148,"ar":149,"es":150},"deploying-laravel-on-a-vps-a-production-guide","نشر-laravel-على-خادم-vps-دليل-الإنتاج","desplegar-laravel-en-un-vps","Déployer Laravel sur un VPS : guide production","Passez Laravel en production sur VPS : PHP, workers, cache, base de données, reverse proxy et HTTPS proprement configurés.","2026-02-09T00:00:00+00:00","2026-09-07T11:26:10+00:00",{"id":22,"name":23,"slug":24,"color":25,"icon":26},[157],{"id":22,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fdeployer-laravel-vps-poster.svg",{"categorySlug":26,"appSlug":160},"laravel-stack",{"id":162,"slug":163,"slugs":164,"title":168,"excerpt":169,"readTime":170,"views":171,"isPinned":18,"publishedAt":172,"updatedAt":154,"category":173,"categories":177,"featuredImage":29,"bgImage":30,"posterImage":179,"relatedSolution":29},38,"deployer-avec-traefik",{"fr":163,"en":165,"ar":166,"es":167},"deploy-your-applications-with-traefik-on-a-vps","انشر-تطبيقاتك-باستخدام-traefik-على-خادم-vps","desplegar-con-traefik","Déployer vos applications avec Traefik sur un VPS","Déployez Traefik en reverse proxy sur votre VPS : routage automatique des conteneurs Docker, certificats SSL Let's Encrypt et load balancing.",3,2,"2026-05-13T00:00:00+00:00",{"id":170,"name":174,"slug":175,"color":176,"icon":175},"Déploiement","deploiement","bg-success\u002F10 text-success",[178],{"id":170,"name":174,"slug":175,"color":176,"icon":175},"\u002Fblog\u002Fcovers\u002Fdeployer-avec-traefik-poster.svg",{"id":181,"slug":182,"slugs":183,"title":187,"excerpt":188,"readTime":189,"views":17,"isPinned":18,"publishedAt":190,"updatedAt":191,"category":192,"categories":193,"featuredImage":29,"bgImage":30,"posterImage":195,"relatedSolution":29},229,"docker-compose-production-checklist",{"fr":182,"en":184,"ar":185,"es":186},"docker-compose-in-production-10-point-checklist","docker-compose-في-الإنتاج-قائمة-التحقق-من-10-نقاط","checklist-docker-compose-en-produccion","Docker Compose en production : checklist des 10 points","Checklist Docker Compose en production : 10 réglages essentiels, health checks, secrets sans downtime, rollback, dépannage des erreurs courantes, CVE-2026-17106.",12,"2026-08-06T00:00:00+00:00","2026-09-29T14:40:45+00:00",{"id":170,"name":174,"slug":175,"color":176,"icon":175},[194],{"id":170,"name":174,"slug":175,"color":176,"icon":175},"\u002Fblog\u002Fcovers\u002Fdocker-compose-production-checklist-poster.svg",{"id":197,"slug":198,"slugs":199,"title":203,"excerpt":204,"readTime":205,"views":17,"isPinned":18,"publishedAt":206,"updatedAt":207,"category":208,"categories":214,"featuredImage":29,"bgImage":30,"posterImage":216,"relatedSolution":217},58,"heberger-redis-vps",{"fr":198,"en":200,"ar":201,"es":202},"hosting-redis-on-a-vps","استضافة-redis-على-خادم-vps","alojar-redis-en-un-vps","Héberger Redis sur un VPS : guide complet","Déployez Redis sur votre VPS Cloud : prérequis RAM\u002FCPU, sécurité (ACL, TLS), persistance RDB\u002FAOF, dépannage et haute disponibilité.",10,"2026-04-23T00:00:00+00:00","2026-09-08T21:59:59+00:00",{"id":209,"name":210,"slug":211,"color":212,"icon":213},6,"Bases de données","bases-de-donnees","bg-teal-500\u002F10 text-teal-400","database",[215],{"id":209,"name":210,"slug":211,"color":212,"icon":213},"\u002Fblog\u002Fcovers\u002Fheberger-redis-vps-poster.svg",{"categorySlug":211,"appSlug":218},"redis-stack",{"id":220,"slug":221,"slugs":222,"title":226,"excerpt":227,"readTime":16,"views":171,"isPinned":18,"publishedAt":228,"updatedAt":154,"category":229,"categories":230,"featuredImage":29,"bgImage":30,"posterImage":232,"relatedSolution":29},206,"php-82-fin-de-vie-checklist-migration",{"fr":221,"en":223,"ar":224,"es":225},"php-82-end-of-life-planning-your-migration","نهاية-دعم-php-82-دليل-الترحيل","php-82-fin-de-vida-planificar-la-migracion","PHP 8.2 fin de vie : checklist de migration","PHP 8.2 atteint son EOL le 31 décembre 2026. Inventaire, tableau comparatif, checklist de migration et dépannage pour passer à PHP 8.3 ou 8.4 sans interruption.","2026-08-01T00:00:00+00:00",{"id":22,"name":23,"slug":24,"color":25,"icon":26},[231],{"id":22,"name":23,"slug":24,"color":25,"icon":26},"\u002Fblog\u002Fcovers\u002Fphp-82-fin-de-vie-checklist-migration-poster.svg",1791900942067]