Articles sur : 🌍 Hébergement web & PaaS
Cet article est aussi disponible en :

Comment configurer un projet avec hodifly.json ?

Hodifly peut prendre ses réglages dans un fichier hodifly.json à la racine de votre dépôt, plutôt que dans le formulaire de cPanel. Le fichier est facultatif : sans lui, Hodifly détecte ce qu'est votre projet et le formulaire garde les réglages. Avec lui, le dépôt se configure lui-même, la configuration est versionnée avec votre code et revient en arrière avec lui. Déployer deux fois le même dépôt donne deux projets identiques.


{
"mode": "php",
"runtime": "php:8.3",
"docroot": "public",
"build": "npm run build",
"persist": ["config/app.yaml", "storage/uploads/"],
"env": { "required": ["DB_HOST", "DB_USER"] },
"keepReleases": 5
}


Placez-le à la racine du dépôt, ou à la racine du sous-dossier du paquet pour un projet qui vit dans un monorepo. Vous n'avez pas à l'écrire à la main : dans cPanel, ouvrez votre projet et cliquez sur hodifly.json pour en générer un à partir des réglages que vous avez déjà.


Tous les réglages


Réglage

Ce que ça fait

mode

Comment le projet est servi : static, node, python, php ou ruby. Prime sur la détection et sur les réglages du projet.

runtime

La chaîne qui compile, et pour PHP la version qui sert le site : node:22, php:8.3, python:3.12, ruby:3.3, ou none pour aucun outillage. Prime sur les réglages du projet, comme mode.

install

Remplace l'installation des dépendances par défaut (npm ci, composer install).

build

La commande de build. Une chaîne vide veut dire aucun build : le dépôt est publié tel quel.

output

Sites statiques uniquement : le dossier produit par votre build (dist, _site).

docroot

PHP uniquement : le dossier de front controller dans la release, public pour Laravel et Symfony. "." sert la racine du dépôt, pour une application qui n'a pas ce dossier.

startup

Applications Node et Python : le fichier que Passenger exécute pour lancer l'application, relatif à la racine du projet : server.js, dist/main.js pour un build NestJS, passenger_wsgi.py. Voir plus bas.

persist

Les chemins qui doivent survivre à un déploiement. Voir plus bas.

env.required

Les noms des variables d'environnement sans lesquelles votre projet ne tourne pas.

keepReleases

Combien de releases garder pour les retours arrière, de 1 à 50. Cinq par défaut.

noindex

true demande aux moteurs de recherche d'ignorer le site, sur chaque réponse. Pour une préproduction.

forceHttps

Envoie tout visiteur qui arrive en HTTP simple vers l'adresse en https. Hodifly le fait déjà tout seul dès que votre domaine a un certificat : ce réglage sert donc surtout à dire false. Voir plus bas.

spa

Sites statiques uniquement. Sert index.html pour toute adresse qui n'est pas un vrai fichier, pour que les routes d'une application React, Vue ou Angular résistent à un rafraîchissement ou à un lien direct. Déjà automatique quand votre build ressemble à une application monopage : true le force, false le désactive.

crons

Des tâches planifiées, écrites comme dans un vercel.json : une liste de {"path": "/api/cron", "schedule": "*/15 * * * *"}. Chacune appelle cette adresse de votre site selon un horaire. Voir plus bas.

autodeploy

false empêche les push de déployer ; vous déployez à la main depuis cPanel.

previews

true construit une URL de prévisualisation pour chaque pull request.

rebuildEvery

Reconstruire aussi sur minuterie, en minutes : 0, 60, 1440 ou 10080.

snippets

Sites statiques uniquement : {"head": "...", "body": "..."}, du HTML injecté dans chaque page compilée.


Node et Python : le fichier d'entrée


Passenger n'exécute pas npm start : il exécute un fichier, et startup sert à dire lequel. Il accepte un chemin, pas seulement un nom, ce dont une application compilée a besoin :


{
"mode": "node",
"runtime": "node:22",
"build": "npm run build",
"startup": "dist/main.js"
}


Trois points à connaître :


  • L'application est quand même lancée depuis la racine du projet, quelle que soit la profondeur de ce chemin. Les chemins relatifs de votre code, et les dossiers listés dans persist (uploads, assets), continuent de fonctionner.
  • Le fichier doit être en CommonJS. Passenger le charge avec require() : une entrée en module ES (un fichier .mjs, ou un projet en "type": "module") a besoin d'un petit fichier passerelle à la racine, et startup pointe sur la passerelle. Dans un fichier server.cjs : import('./dist/server/server.mjs').catch(e => { console.error(e); process.exit(1); });. Next.js, Nuxt, Astro, SvelteKit et Remix n'ont besoin de rien de tout ça, Hodifly l'écrit pour eux.
  • Votre serveur doit écouter. Un build Angular SSR n'écoute que si son server.mjs est le module principal, ce qu'il n'est pas sous Passenger : retirez cette condition pour que listen() s'exécute toujours, sur process.env.PORT.


Vous pouvez aussi le définir dans cPanel, dans le champ Fichier de démarrage du projet. Le fichier l'emporte sur le champ.


Une application Ruby n'a pas ce réglage : Rack démarre toujours depuis config.ru.


Ce qu'il ne peut délibérément pas régler


  • Le sous-dossier du paquet et la branche. C'est par eux que Hodifly trouve ce fichier.
  • Le domaine et le dossier sur votre compte. Le même dépôt sur deux domaines, ce sont deux projets : l'adresse appartient à l'hébergement, pas au code.
  • Tout ce qui est secret : les valeurs des variables d'environnement, le secret du webhook de déploiement, l'URL du build hook, votre jeton GitLab. Un dépôt est le dernier endroit où ils doivent finir. env.required les nomme, cPanel les détient.


persist : ce qui survit à un déploiement


Chaque déploiement crée une nouvelle release, et les anciennes disparaissent dès qu'il en existe keepReleases plus récentes. Tout ce que votre application écrit dans son propre dossier est donc en sursis, et tout ce que votre dépôt ne livre pas est absent de chaque release. persist règle les deux : chaque chemin listé est déplacé une fois dans un dossier situé hors de toute release, puis relié dans chaque nouvelle, ce qui lui fait survivre aux déploiements et aux retours arrière.


  • Un / final veut dire dossier, sans slash c'est un fichier. C'est la seule façon pour Hodifly de savoir quoi créer quand le chemin n'existe encore nulle part.
  • Le premier déploiement fixe le contenu de départ. Si votre dépôt livre le chemin, cette copie est conservée. Sinon, le chemin est créé vide et le journal de déploiement affiche exactement où, pour que vous le remplissiez en FTP. Rien n'est jamais recopié depuis un fichier .example : ce qu'un modèle doit devenir vous appartient.
  • Ensuite, c'est la copie persistée qui gagne. Une version qui apparaîtrait plus tard dans le dépôt est ignorée.
  • Le storage/ de Laravel, les var/log et var/sessions de Symfony et toute base SQLite nommée dans votre configuration sont déjà pris en charge. Ne les listez pas.
  • Vous ne pouvez pas persister le dossier depuis lequel votre site est servi : il figerait le site sur une release et aucun déploiement ne pourrait plus remplacer le code.


Un retour arrière restaure le code, jamais les données : vos uploads, votre base et votre configuration restent ceux d'aujourd'hui. Voir « Puis-je revenir en arrière après un mauvais déploiement ? ».


Tâches planifiées (crons)


crons lance des tâches selon un horaire. Il s'écrit exactement comme les crons d'un vercel.json : un projet qui arrive de Vercel n'a rien à changer.


{
"crons": [
{ "path": "/api/cron/digest", "schedule": "0 7 * * *" },
{ "path": "/wp-cron.php", "schedule": "*/15 * * * *" }
]
}


  • Une tâche appelle une adresse de votre site. À chaque échéance, Hodifly demande ce chemin sur le domaine de votre projet, en HTTPS. Votre code y répond comme à n'importe quel visiteur : cela fonctionne de la même façon pour un site statique avec des fonctions API, une application PHP ou une application Node, Python ou Ruby, et c'est toujours la version en ligne qui s'exécute.
  • schedule reprend les cinq champs habituels de cron : minute, heure, jour du mois, mois, jour de la semaine, dans le fuseau horaire du serveur. Les raccourcis comme @daily ne sont pas acceptés : écrivez 0 0 * * *.
  • path commence par / et peut porter des paramètres, comme /cron.php?job=cleanup.
  • Chaque appel est signé. N'importe qui connaissant l'adresse peut l'appeler : chaque appel porte donc un en-tête Authorization: Bearer contenant la variable d'environnement CRON_SECRET du projet. Votre code la compare à process.env.CRON_SECRET (ou l'équivalent dans votre langage) et refuse tout le reste.
  • Vous n'avez pas à créer ce secret. Si le projet n'a pas de CRON_SECRET, le déploiement qui ajoute sa première tâche en crée un au hasard et le signale dans le journal de déploiement. Il apparaît dans Hodifly > votre projet > Variables d'environnement, où vous pouvez le lire ou le remplacer. Une application Node, Python ou Ruby le reçoit dès ce déploiement ; une application PHP le lit à partir du suivant. Un CRON_SECRET que vous avez défini vous-même n'est jamais remplacé.
  • Les tâches apparaissent dans cPanel > Tâches Cron, dans un bloc marqué comme géré par Hodifly. Ce bloc est réécrit à chaque déploiement : modifiez le fichier plutôt que le bloc. Les tâches que vous ajoutez vous-même en dehors ne sont jamais touchées.
  • Retirez la clé (ou le fichier) et le déploiement suivant retire les tâches. Une prévisualisation de pull request n'y touche jamais, et un retour arrière garde celles en place.
  • Jusqu'à 20 tâches, avec 5 minutes chacune pour répondre. Si le dépôt contient aussi un vercel.json avec des crons, la liste de hodifly.json la remplace, et le journal de déploiement le signale.


Une application Laravel n'en a pas besoin pour son planificateur : quand votre application planifie des tâches, Hodifly maintient déjà une tâche schedule:run chaque minute, en plus de celles que vous listez ici.


HTTPS : votre site redirige tout seul


Hodifly envoie tout visiteur qui arrive en HTTP simple vers l'adresse en https de la même page, avec une redirection permanente. Les sites statiques, les applications PHP et les applications Node, Python ou Ruby en bénéficient toutes, et vous n'avez rien à demander.


Il y a une condition, et c'est toute la raison d'être de forceHttps : la redirection n'apparaît qu'une fois qu'un vrai certificat couvre effectivement votre domaine. Le premier déploiement d'un nouveau site arrive presque toujours avant que le certificat soit émis, et envoyer les visiteurs vers un https que leur navigateur refuse rendrait le site indisponible jusqu'à son arrivée. Le premier déploiement est donc servi en clair et le signale dans son journal, le certificat est émis, et le déploiement suivant active la redirection de lui-même.


  • "forceHttps": false désactive la redirection, pour un site qui a une raison de répondre en clair.
  • "forceHttps": true redirige sans attendre le certificat. À n'utiliser que si vous savez qu'il est déjà là : tant qu'il ne l'est pas, le site est injoignable.


Les adresses que votre autorité de certification vérifie, sous /.well-known/, ne sont jamais redirigées : l'émission et le renouvellement continuent de fonctionner en HTTP.


Quels réglages s'appliquent quand


Hodifly relit le fichier depuis votre code à chaque déploiement pour tout ce qui décrit le build : build, install, output, docroot, startup, persist, env.required, keepReleases, noindex, forceHttps, spa et crons. Vous modifiez, vous poussez, c'est fait.


startup est dans cette liste à dessein : c'est le build qui décide quel fichier lance votre application, donc déplacer votre point d'entrée ne doit jamais obliger à retourner dans cPanel pour que quelque chose démarre. La valeur utilisée est réenregistrée sur le projet : le champ Fichier de démarrage affiche donc ce qui tourne réellement.


mode et runtime l'emportent eux aussi à chaque déploiement. Ils décident de la façon dont votre application est installée avant toute compilation : Hodifly les lit donc dans votre dépôt, au commit déployé. S'ils diffèrent du projet, le déploiement bascule d'abord le projet (avec la commande de build, le dossier publié et le fichier de démarrage adaptés au nouveau mode), et les premières lignes du journal de déploiement l'indiquent. Ensuite, la page Réglages affiche la valeur comme définie par hodifly.json : pour la changer, modifiez le fichier et poussez.


Votre offre d'hébergement décide toujours des types d'application possibles. Si le fichier demande une application Node.js, Python ou Ruby et que votre offre ne les inclut pas, le projet garde son mode actuel et le journal de déploiement explique pourquoi. Revenir à une version construite dans un autre mode est aussi refusé : redéployez plutôt ce commit.


Le reste (autodeploy, previews, rebuildEvery, snippets) s'applique à la création du projet, ou quand vous changez son sous-dossier de paquet. Modifier l'un d'eux plus tard dans le fichier suppose de le modifier aussi dans le formulaire.


Là où hodifly.json et un « vercel.json » disent la même chose, hodifly.json l'emporte, et le journal de déploiement le signale.


Vérifier un fichier avant de le pousser


Collez-le dans le validateur sur hodifly.app/fr/validate. Il vous dit si le fichier est valide et, plus utile encore, ce qu'il fera exactement au prochain déploiement.


Bon à savoir


  • Un fichier qui n'est pas du JSON valide ne casse jamais un déploiement : il est ignoré, avec un avertissement dans le journal, et le déploiement continue avec les réglages du formulaire.
  • Limites : 256 Ko pour le fichier, 500 réglages, 4 Ko par valeur.
  • env.required est un bon filet de sécurité. S'il manque une variable, le déploiement s'arrête en quelques secondes en la nommant, au lieu de laisser votre site répondre une page blanche.

Mis à jour le : 12/10/2026

Cet article a-t-il répondu à vos questions ?

Partagez vos commentaires

Annuler

Merci !