Mise en production
Déployez votre site sur un hébergement Hostinger (ou tout serveur Apache avec accès SSH) et vérifiez que tout est prêt avant le lancement.
Déploiement (Hostinger / Apache)
Déployez votre site via rsync pour des mises à jour rapides et automatiques.
Prérequis
- Serveur Apache avec
mod_rewriteetmod_headersactivés (ce sont des fonctionnalités d'Apache activées par défaut chez la plupart des hébergeurs — vous n'avez rien à faire) - PHP 7+ (pour
api/baserow.phpetapi/consent.php) - Certificat SSL (Let's Encrypt ou autre)
- Accès SSH activé sur l'hébergement (Hostinger : plan Premium ou supérieur)
1. Activer et configurer SSH
Sur Hostinger, allez dans hPanel (hpanel.hostinger.com) → Avancé → Accès SSH et notez :
- IP du serveur
- Port (généralement
65002chez Hostinger) - Nom d'utilisateur (ex :
u123456789)
2. Générer une clé SSH (si pas déjà fait)
# Générer une clé SSH ed25519
ssh-keygen -t ed25519 -C "votre@email.com"
# Appuyer sur Entrée pour accepter le chemin par défaut
# Choisir un mot de passe (ou Entrée pour aucun)
Appuyez sur Entrée à chaque question (emplacement du fichier, mot de passe) pour garder les valeurs par défaut. Deux fichiers sont créés : id_ed25519 (votre clé secrète, ne la partagez jamais) et id_ed25519.pub (votre clé publique, à coller sur Hostinger).
- Afficher la clé publique dans le terminal :
cat ~/.ssh/id_ed25519.pub - Copier tout le contenu affiché (de
ssh-ed25519jusqu'à la fin) - Aller sur hpanel.hostinger.com
- Cliquer Hébergement (menu de gauche) → sélectionner votre domaine
- Cliquer Avancé → Accès SSH
- Dans la section Clés SSH, coller la clé publique
- Cliquer Ajouter
- Tester la connexion :
ssh -p 65002 uXXXXXX@xx.xxx.xx.xxx(remplacer par vos valeurs)
3. Première connexion SSH
Connectez-vous une première fois pour accepter l'empreinte du serveur :
# Remplacez USER, IP et PORT par vos valeurs
ssh -p PORT USER@IP
# Tapez "yes" pour accepter l'empreinte
# Entrez votre mot de passe SSH
# Une fois connecté, tapez "exit" pour revenir en local
4. Copier la clé publique sur le serveur
Pour ne plus avoir à taper le mot de passe à chaque déploiement :
# Copier la clé publique (demande le mot de passe une dernière fois)
ssh-copy-id -p PORT USER@IP
# Vérifier que la connexion fonctionne sans mot de passe
ssh -p PORT USER@IP "echo 'SSH OK'"
5. Identifier le dossier du domaine
Sur Hostinger, chaque domaine a son propre dossier. Connectez-vous en SSH pour le trouver :
ssh -p PORT USER@IP
ls ~/domains/
# Résultat : monsite.fr autre-site.com ...
exit
Le chemin de déploiement sera : /home/USER/domains/monsite.fr/public_html/
6. Créer le fichier d'exclusions
Créez un fichier .rsync-exclude à la racine du projet pour lister les fichiers à ne pas envoyer sur le serveur :
# Git + CI
.git/
.gitignore
.gitmodules
.github/
# Dev / documentation (inutile en prod)
CLAUDE.md
README.md
.claude/
.rsync-exclude
# Secrets et config locale (jamais déployés)
.deploy.env
.deploy.env.example
.env.example
.baserow-credentials
# Dev tools (pas utiles en prod)
node_modules/
.playwright-mcp/
.mcp.json
# Scripts locaux (pas utiles en prod)
setup.sh
deploy.sh
generate-sitemap.js
# Configurateur (local uniquement)
configurateur/
# Submodule (les symlinks sont suivis par rsync -L)
.framework/
# Données locales (registre pages, etc.)
data/
# Form builder state (dev only, pas utile en prod)
forms/.meta.json
forms/*.json
# Wireframes bundle (dev only)
wireframes/wireframes-data.json
wireframes/build-data.js
# IDE / OS
.vscode/
.DS_Store
Thumbs.db
Note : le fichier .env n'est pas exclu du déploiement : il est envoyé sur le serveur par rsync et protégé par le .htaccess. Seuls les fichiers de développement et de configuration SSH sont exclus.
Matrice de déploiement
| Fichier / Dossier | GitHub | Serveur (prod) | Template | Notes |
|---|---|---|---|---|
core/, assets/, api/, snippets/ |
✅ | ✅ | ✅ (symlinks) | Framework core — déployé via symlinks suivis par rsync -L |
components/ |
✅ | ✅ | ❌ | Dossier projet (pas un symlink) — copié depuis snippets/components/ par setup.sh |
configurateur/ |
✅ | ❌ | ✅ (symlink) | Outil local uniquement, exclu du déploiement |
wireframes/ |
✅ | ✅ | ❌ | Dossier réel du projet — 375+ sections HTML prêtes à l'emploi |
docs/ |
❌ | ✅* | ❌ | *Déployé uniquement sur framework.beely.studio (la prod de la doc) |
config-site.js |
✅ | ✅ | ✅ | Configuration client — spécifique à chaque projet |
.env |
❌ | ✅ | ❌ | Secrets API (Baserow, CORS) — nécessaire côté serveur |
.env.example |
✅ | ❌ | ✅ | Template documenté, inutile en prod |
.deploy.env |
❌ | ❌ | ❌ | Config SSH locale uniquement |
.deploy.env.example |
✅ | ❌ | ✅ | Template documenté |
.htaccess |
✅ | ✅ | ✅ | Config Apache serveur |
setup.sh |
✅ | ❌ | ✅ | Script d'initialisation local |
deploy.sh |
✅ | ❌ | ✅ | Script de déploiement local |
CLAUDE.md, README.md |
✅ | ❌ | ✅ | Documentation dev, inutile en prod |
.vscode/ |
❌ | ❌ | ❌ | Config IDE locale |
sitemap.xml |
❌ | ✅ | ❌ | Généré par generate-sitemap.js avant chaque déploiement |
pages/ |
✅ | ✅ | ✅ | Pages HTML du site |
data/ |
❌ | ❌ | ❌ | Données locales (registre pages, métadonnées médias) |
404.html |
✅ | ✅ | ✅ | Page d'erreur Apache |
Rappel : .gitignore contrôle ce qui va sur GitHub. .rsync-exclude contrôle ce qui va sur le serveur. Ce sont deux périmètres indépendants.
7. Configurer le déploiement
Astuce : si vous avez utilisé init-project.sh, cette étape est déjà faite automatiquement. Passez à l’étape 8.
Le script deploy.sh lit les informations de connexion depuis un fichier .deploy.env (non committé dans git). Copiez le template et remplissez-le :
cp .deploy.env.example .deploy.env
Contenu de .deploy.env :
# Production
PROD_HOST=xx.xxx.xx.xxx
PROD_PORT=65002
PROD_USER=uXXXXXX
PROD_PATH=/home/uXXXXXX/domains/monsite.fr/public_html/
PROD_URL=https://monsite.fr
# Pré-production (optionnel)
PREPROD_HOST=
PREPROD_PORT=
PREPROD_USER=
PREPROD_PATH=
PREPROD_URL=
Rendez le script exécutable (une seule fois) :
chmod +x deploy.sh
8. Déployer
# Simuler le déploiement en production (dry-run)
./deploy.sh prod --dry-run
# Déployer en production
./deploy.sh prod
# Déployer en pré-production
./deploy.sh preprod
# Dry-run pré-production
./deploy.sh preprod --dry-run
Comment ça marche :
rsyncne transfère que les fichiers modifiés (très rapide après le premier déploiement)--deletesupprime sur le serveur les fichiers supprimés en local (synchronisation miroir)--dry-runsimule sans rien modifier, parfait pour vérifier avant de déployer- Préprod non indexée : chaque déploiement préprod ajoute un header
X-Robots-Tag: noindex, nofollowdans le.htaccessdu serveur — la préprod n’apparaîtra jamais dans Google
9. Configurer le fichier .env
Créez un fichier .env à la racine de votre projet dans VSCode. Ce fichier contient les variables utilisées par les API PHP côté serveur :
# .env (à la racine du projet)
SITE_ORIGIN=https://monsite.fr
BASEROW_TOKEN=votre_token_api_ici
Le fichier .env est inclus dans le déploiement rsync et sera envoyé automatiquement sur le serveur. Il est protégé par le .htaccess (inaccessible depuis le web) et exclu du versionning Git via .gitignore. C'est sûr car le fichier .htaccess contient une règle qui renvoie une erreur 403 (accès interdit) à quiconque tente d'accéder au .env depuis un navigateur. Le fichier est sur le serveur mais invisible depuis le web.
Aucun accès SSH à Hostinger n'est nécessaire pour la configuration : tout se fait en local dans VSCode.
| Variable | Utilisé par | Description |
|---|---|---|
SITE_ORIGIN | Tous les proxies | Domaine autorisé pour les requêtes CORS |
BASEROW_TOKEN | api/baserow.php | Token API Baserow (read-only) |
10. Vérifier le .htaccess
Le fichier .htaccess fourni gère automatiquement :
- HTTPS : redirection HTTP → HTTPS (301)
- URLs propres :
/blogau lieu de/blog.html - Page 404 : page d'erreur personnalisée
- Sécurité : headers (HSTS, X-Frame-Options, X-Content-Type-Options, CSP — une règle de sécurité qui dit au navigateur « ce site n'a le droit de charger des scripts que depuis ces sources précises », ce qui empêche les pirates d'injecter du code malveillant), tous les dotfiles bloqués (
.env,.deploy.env, etc.), dossierdata/protégé, rate limiting sur les endpoints PHP (protection anti-spam : si quelqu'un soumet plus de 5 formulaires par minute, il est automatiquement bloqué) - Anti-cache CDN : désactive le cache LiteSpeed/HCDN sur les fichiers CSS, JS et HTML pour que chaque déploiement soit immédiatement visible (headers
no-cache,CDN-Cache-Control: no-store,CacheLookup off)
Testez que mod_rewrite fonctionne en accédant à https://votre-site.fr/blog (sans .html).
11. Protection HTTP — htpasswd (optionnel)
Protégez un site en développement ou pré-production par mot de passe (HTTP Basic Auth). Une popup d'authentification apparaîtra dans le navigateur avant de pouvoir accéder au site.
Via le configurateur (recommandé)
- Lancez le serveur Python :
python3 configurateur/configurator-server.py - Ouvrez le configurateur :
http://localhost:XXXX/configurateur/ - Cliquez sur l'onglet Protection HTTP dans la sidebar
- Cochez Activer la protection HTTP
- Renseignez un identifiant et un mot de passe
- Cliquez sur Enregistrer
Le serveur génère automatiquement :
.htpasswdà la racine du projet (mot de passe hashé en APR1/MD5)- Le bloc
AuthType Basicdans le.htaccess
Pour désactiver : décochez la case et cliquez sur Enregistrer. Le .htpasswd est supprimé et le bloc auth retiré du .htaccess.
Manuellement
1. Générer le fichier .htpasswd :
# 📂 Dossier : racine du projet
htpasswd -cm .htpasswd admin
# Entrez le mot de passe quand demandé
2. Ajouter ce bloc en haut du .htaccess (après ErrorDocument 404) :
# --- BEGIN Protection HTTP (htpasswd) ---
AuthType Basic
AuthName "Accès restreint"
AuthUserFile /chemin/absolu/vers/votre/projet/.htpasswd
Require valid-user
# --- END Protection HTTP (htpasswd) ---
Important : AuthUserFile doit être un chemin absolu (pas relatif). Un chemin absolu commence par / et part de la racine du serveur, comme /home/u123456789/domains/monsite.fr/public_html/.htpasswd. Ne mettez jamais un chemin relatif (comme ../.htpasswd), sinon ça ne fonctionnera pas.
3. Pour désactiver : supprimez le bloc du .htaccess et le fichier .htpasswd.
Rappel : pensez à désactiver la protection avant la mise en production du site final.
12. Sitemap
Le sitemap est généré automatiquement à chaque déploiement par deploy.sh. Il utilise l'URL du site configurée dans .deploy.env (PROD_URL ou PREPROD_URL).
Vous pouvez aussi le générer manuellement :
node generate-sitemap.js https://votre-site.fr
Cela crée sitemap.xml et robots.txt avec les URLs propres. Soumettez le sitemap dans Google Search Console :
- Allez sur search.google.com/search-console
- Cliquez Ajouter une propriété et entrez l'URL de votre site
- Vérifiez la propriété (méthode recommandée : enregistrement DNS ou fichier HTML)
- Dans le menu de gauche, cliquez Sitemaps
- Dans le champ « Ajouter un sitemap », entrez
sitemap.xml - Cliquez Envoyer
Récap : fichiers à personnaliser par projet
Chaque nouveau projet nécessite de remplir 3 fichiers :
| Fichier | Contenu | Committé ? |
|---|---|---|
config-site.js | Nom du site, favicon, analytics, informations légales, config blog (tableId) | Oui |
.env | Secrets : token Baserow, CORS origin | Non |
.deploy.env | Connexion SSH : host, port, user, path pour prod et préprod | Non |
Les fichiers .env.example et .deploy.env.example servent de templates documentés (committés dans git).
Pour le dépôt Git, configurez le remote au démarrage du projet :
git remote add origin https://github.com/votre-user/votre-projet.git
git push -u origin main
Récap : workflow quotidien
Une fois tout configuré, le cycle de développement-déploiement est simple :
# 1. Modifier le code en local (Live Server pour prévisualiser)
# 2. Commiter les changements
git add -A
git commit -m "Update hero section design"
# 3. Pousser sur GitHub
git push
# 4. Déployer en production
./deploy.sh prod
Déploiement automatique (GitHub Actions)
Pour les projets avec un client qui modifie le contenu via GitHub, GitHub Actions déploie automatiquement à chaque commit.
Fonctionnement
- Le client modifie un fichier JSON sur GitHub et commit
- GitHub Actions valide le JSON, compile le contenu dans le HTML, et déploie via SSH/rsync
- Le site est mis à jour en ~15 secondes
Le déploiement SSH inclut un système de retry automatique (jusqu'à 3 tentatives avec 10s d'attente) pour gérer les connexions instables de certains hébergeurs.
Configuration
Dans GitHub → Settings → Secrets and variables → Actions, créer ces secrets :
| Secret | Valeur | Où la trouver |
|---|---|---|
SSH_PRIVATE_KEY | Clé SSH privée | cat ~/.ssh/id_ed25519 |
PROD_HOST | IP du serveur | .deploy.env → PROD_HOST |
PROD_PORT | Port SSH | .deploy.env → PROD_PORT |
PROD_USER | Utilisateur SSH | .deploy.env → PROD_USER |
PROD_PATH | Chemin sur le serveur | .deploy.env → PROD_PATH |
Le workflow .github/workflows/deploy.yml est copié automatiquement par setup.sh.
Voir Contenu éditable pour le guide client complet.
Sécurité
- La clé SSH est stockée dans les GitHub Secrets — jamais visible, même par les admins du repo
- Chaque projet a ses propres secrets — un client ne peut déclencher que le déploiement de son site
- La clé SSH est restreinte au rsync vers un seul répertoire — pas d'accès shell au serveur
- Le client n'a accès qu'au repo de son site — pas aux autres projets
Voir la documentation Contenu éditable pour le workflow client complet.
Déploiement manuel (FTP / cPanel)
Si vous n'utilisez pas SSH/rsync, vous pouvez déployer manuellement via le gestionnaire de fichiers cPanel ou un client FTP (FileZilla, Cyberduck, etc.). Cette méthode fonctionne avec tous les hébergeurs (Hostinger, o2switch, Infomaniak, etc.).
1. Uploader les fichiers
Connectez-vous à votre espace d'hébergement et accédez au dossier de votre domaine (généralement public_html/).
- cPanel : Gestionnaire de fichiers → naviguez dans
public_html/→ glissez-déposez vos fichiers - FTP : connectez votre client avec les identifiants fournis par votre hébergeur et uploadez dans le dossier du domaine
2. Fichiers à ne pas envoyer
Excluez ces fichiers/dossiers du transfert (ils sont inutiles en production) :
.git/ # Historique Git
.claude/ # Configuration Claude Code
CLAUDE.md # Instructions Claude Code
.deploy.env # Config SSH locale
.rsync-exclude # Liste d'exclusion rsync
deploy.sh # Script de déploiement
generate-sitemap.js # Générateur de sitemap (Node.js)
3. Créer le .env sur le serveur
Le fichier .env n'est pas dans Git, il faut le créer manuellement sur le serveur. Dans le gestionnaire de fichiers cPanel, créez un nouveau fichier .env à la racine du site :
# .env (racine du site sur le serveur)
SITE_ORIGIN=https://votre-site.fr
BASEROW_TOKEN=votre-token-baserow
Le .htaccess fourni bloque automatiquement l'accès à ce fichier depuis le navigateur.
4. Vérifications après upload
- ☐ PHP actif : la plupart des hébergeurs mutualisés l'activent par défaut
- ☐
.htaccesslu : testez que les URLs propres fonctionnent (/blogau lieu de/blog.html) - ☐ HTTPS actif : activez le certificat SSL dans votre panneau d'hébergement si ce n'est pas fait. Sur Hostinger : hPanel → Sécurité → SSL. Sur o2switch : cPanel → SSL/TLS.
- ☐
.envinaccessible : vérifiez quehttps://votre-site.fr/.envretourne une erreur 403 - ☐ Dossier
data/: il sera créé automatiquement parconsent.phpau premier consentement cookies
Le projet étant zéro-dépendance, il n'y a aucun npm install ou build à lancer. Les fichiers fonctionnent tels quels.
Checklist de lancement
Vérifiez chaque point avant de considérer le site comme prêt à être lancé.
- ☐
tokens.css: couleurs principales (--color-primary,--color-secondary) - ☐
tokens.css: polices personnalisées (--font-heading,--font-body) - ☐
tokens.css: arrondis, ombres, conteneur max-width si besoin - ☐ Test dark mode : toutes les pages lisibles en mode sombre
config-site.js)- ☐ SITE_CONFIG : nom du site (
name) renseigné - ☐ SITE_CONFIG : favicon (
favicon) renseigné - ☐ COOKIES_CONFIG : IDs analytics renseignés (ou vides si non utilisés)
- ☐ COOKIES_CONFIG : textes du bandeau cookies adaptés
- ☐ COOKIES_CONFIG :
privacyUrlpointe vers/confidentialite.html - ☐ COOKIES_CONFIG :
consentEndpointconfiguré (/api/consent.php) - ☐ BLOG_CONFIG : connexion Baserow renseignée (si blog),
tableIdrenseigné (le token est dans.env, pas dans config-site.js) - ☐ LEGAL_CONFIG : toutes les infos entreprise remplies (company, SIRET, adresse, etc.)
- ☐ LEGAL_CONFIG : infos hébergeur remplies (nom, adresse, URL)
- ☐ LEGAL_CONFIG : section développeur remplie ou laissée vide (masquée automatiquement)
- ☐
mentions-legales.html: ouvrir et vérifier que toutes les infos s'affichent (pas de[...]) - ☐
confidentialite.html: vérifier le tableau cookies (doit lister les services configurés) - ☐ Bouton « Gérer mes préférences cookies » fonctionnel sur la page confidentialité
- ☐ Bandeau cookies : lien vers la politique de confidentialité visible
- ☐ Footer de chaque page : liens vers mentions légales et confidentialité
- ☐ Textes légaux validés par un professionnel du droit
- ☐
api/consent.phpfonctionnel (tester un accept/refus et vérifierdata/consents.csv)
- ☐ Header : logo, navigation finale, liens corrects
- ☐ Footer : copyright à jour, liens légaux présents
- ☐ Toutes les balises
<title>uniques et descriptives - ☐ Toutes les balises
<meta description>renseignées - ☐
404.html: texte et lien personnalisés - ☐
generate-sitemap.jsexécuté avec l'URL finale - ☐
robots.txtgénéré et correct
- ☐
.env:SITE_ORIGINrenseigné avec l'URL de production - ☐
.env:BASEROW_TOKENrenseigné (si blog) - ☐ HTTPS actif et fonctionnel
- ☐ URLs propres fonctionnelles (
/blogau lieu de/blog.html) - ☐
.htaccess: vérifier que.envet tous les dotfiles sont inaccessibles depuis le navigateur - ☐
data/: vérifier que le dossier est inaccessible depuis le navigateur - ☐ HSTS actif (header
Strict-Transport-Security) - ☐ Rate limiting actif sur les endpoints PHP (
api/rate-limit.php) - ☐ Page 404 accessible (
/page-inexistante)
- ☐ Test mobile : toutes les pages responsive
- ☐ Test dark mode : lisibilité de toutes les pages
- ☐ Test bandeau cookies : accepter, refuser, personnaliser
- ☐ Test pages légales : infos dynamiques correctes
- ☐ Test blog : listing, article, filtres (si blog actif)
- ☐ Test 404 : page d'erreur personnalisée
- ☐ Test formulaires : validation, envoi (si formulaires actifs)
- ☐ Supprimer les fichiers inutiles du serveur (
.git/,snippets/)
Problèmes courants
- Le déploiement échoue : vérifiez que
.deploy.envest bien rempli et que la clé SSH est configurée (ssh-keygen -t ed25519). - Le
.envn'est pas envoyé : vérifiez qu'il n'est pas listé dans.rsync-exclude(il ne devrait pas y être). - Les URLs propres ne fonctionnent pas : vérifiez que
mod_rewriteest activé sur le serveur Apache et que le.htaccessest bien déployé. - Le CSS/JS n'est pas à jour après déploiement : le
.htaccessdésactive déjà le cache CDN. Videz le cache navigateur (Ctrl+Shift+R).