- JavaScript 67.8%
- CSS 24.9%
- HTML 7.2%
| app | ||
| assets-src | ||
| .dockerignore | ||
| .gitignore | ||
| docker-compose.yml | ||
| Dockerfile | ||
| LICENSE | ||
| README.md | ||
La Petite Grenouille — petitegrenouillecorsica.com
Site des chambres d'hôtes de Didier et Nath à Santa-Lucia-di-Moriani (Costa Verde,
Haute-Corse). Domaine canonique petitegrenouillecorsica.com (derrière Cloudflare) ;
grenouille.chauvat.com fait une 301. Les photos et le film viennent de « Bienvenue chez
la grenouille » (assets-src/ = images maîtres PNG 1080p, app/public/img/video/ = hero + film).
Architecture
app/— application Node 24 (Express +node:sqlite+ffmpeg, zéro dépendance native au JS).- Pages assemblées au démarrage depuis
views/layout.html+views/pages/*.html; textes par défaut dans les templates +content.json(méta pages, chambres, mot des hôtes). - API : livre d'or (
/api/livredor), photos/vidéos (/api/photos), espace hôtes (/api/hotes/*, en-têtex-hote-code). - Données dans
/data(volume) :grenouille.db(SQLite WAL) +uploads/+tmp/.
- Pages assemblées au démarrage depuis
- Livre d'or & galerie (page unique
/livre-dor,/galerie→ 301) — mot + jusqu'à 10 photos/vidéos ; anti-spam honeypot + délai + 5/h/IP + Turnstile. Les vidéos sont transcodées en H.264/AAC mp4 (file d'attente ffmpeg) + vignette.- Édition par l'auteur : jeton d'appareil (localStorage) ou mot de passe optionnel
(rééditer ailleurs).
PUT /api/livredor/:id,POST /api/livredor/retrouver.
- Édition par l'auteur : jeton d'appareil (localStorage) ou mot de passe optionnel
(rééditer ailleurs).
- Mode édition inline (hôtes) — depuis
/hotes(code) → barre en bas du site → clic sur un texte (data-edit) ou une image (data-edit-img) pour le modifier en direct. Stocké dans la tableoverrides(le défaut du code reste, l'override gagne), appliqué côté serveur (SEO/no-JS OK). Endpoints :PUT/DELETE /api/hotes/content,POST /api/hotes/content-image. Valeur vide = retour au défaut. - Hero = boucle vidéo 24 s ; bouton « Voir le film » → film complet en modale.
- Perf : assets (css/js/vidéos) versionnés
?v=<hash>(busting cache Cloudflare),Cache-Control: immutablesur les statiques, HTMLno-cache, srcset responsive, preload polices.
Dépôt
Code versionné sur Forgejo (privé) : forgejo.ekaii.fr/admin_ekaii/grenouille, branche main.
Push : git -c http.extraHeader="Authorization: token <FORGEJO_EKAII_ADMIN_TOKEN>" push
(token dans <your-forgejo-token>, jamais stocké dans .git/config).
Le .gitignore exclut node_modules/, data/, .env, .hote-code-prod.
Déploiement (your host)
rsync -a --delete --exclude data/ --exclude .env ~/grenouille/ your-host:/opt/grenouille/
ssh your-host 'cd /opt/grenouille && docker compose up -d --build'
Note : après up, Traefik met 30-90 s à raccrocher le backend (« no available server » transitoire).
.env sur le serveur (non versionné) :
HOTE_CODE=… # code de l'espace hôtes (obligatoire)
CONTACT_TEL=… # affiché sur /infos + footer
CONTACT_EMAIL=… # affiché sur /infos + footer
CANONICAL_HOST=petitegrenouillecorsica.com # 301 depuis les autres hôtes
TURNSTILE_SITEKEY=… # captcha Cloudflare (livre d'or)
TURNSTILE_SECRET=…
DNS : apex + www → A <your-server-ip>, proxy Cloudflare ON (SSL Full strict). Certificat
Let's Encrypt émis par le Traefik de Coolify. L'adresse postale exacte n'est pas publiée
(seulement le village) — choix délibéré.
À personnaliser par Didier et Nath (sans toucher au code)
- Tout se fait via le mode édition inline (
/hotes→ « Aller sur le site ») : textes de l'accueil, descriptifs des chambres (Arum, Magnolia, Iris, Hortensia), mot des hôtes, et remplacement des photos des chambres/sections. - Photos/vidéos de la galerie via l'espace hôtes (catégories
maison,chambres,environs). - Modération du livre d'or (masquer/réafficher) dans l'espace hôtes.