# đŸ—‚ïž Servir un site statique Servir des fichiers est l'autre moitiĂ© du travail de Pingclair. Cette page construit un site statique Ă  partir de `root` et `file_server`, puis ajoute la compression, les en-tĂȘtes de cache, les requĂȘtes partielles et le repli dont une application d'une seule page a besoin, en montrant ce que le serveur rĂ©pond rĂ©ellement Ă  chaque Ă©tape. ## đŸ§Ÿ Avant de commencer - Pingclair installĂ© et en service ([Installation](/fr/start/install/)), service arrĂȘtĂ© le temps des essais : `sudo pc service stop`. - Un rĂ©pertoire Ă  servir. Les exemples utilisent `/srv/site`. ## 📁 Servir un rĂ©pertoire ```caddyfile http://:8080 { root * /srv/site file_server } ``` ```bash sudo cp Pingclairfile /etc/Pingclair/Pingclairfile sudo pingclair validate /etc/Pingclair/Pingclairfile sudo systemctl restart pingclair curl -i http://localhost:8080/ ``` ```text HTTP/1.1 200 OK Content-Type: text/html; charset=utf-8 Last-Modified: Tue, 22 Sep 2026 04:37:54 GMT ETag: "5e-6ab20622" Accept-Ranges: bytes ``` `root *` dĂ©finit la racine du site pour chaque requĂȘte, et `file_server` sert depuis celle-ci. Un chemin inexistant rĂ©pond `404`. ## đŸ—œïž Compression ```caddyfile http://:8080 { root * /srv/site encode zstd gzip file_server } ``` Les arguments sont dans l'ordre de prĂ©fĂ©rence. Le mĂȘme fichier texte de 36 Ko, demandĂ© avec trois en-tĂȘtes `Accept-Encoding` diffĂ©rents, mesurĂ© sur cette configuration : ```text zstd 200 65 bytes content-encoding: zstd gzip 200 301 bytes content-encoding: gzip identity 200 36000 bytes (no content-encoding) ``` Brotli n'est pas implĂ©mentĂ© pour les rĂ©ponses proxifiĂ©es, et le demander est une erreur de compilation plutĂŽt qu'une dĂ©gradation silencieuse : ```text Error: ❌ Configuration Error: Compile error: Unsupported feature: `encode br`: Brotli is not implemented for proxied responses; use `encode zstd gzip` ``` Le message nomme l'alternative, et c'est le but : une configuration qui demande ce que le serveur ne peut pas honorer ne s'exĂ©cute pas du tout. ## ⏳ En-tĂȘtes de cache `file_server` rĂ©pond dĂ©jĂ  aux requĂȘtes conditionnelles — l'`ETag` et le `Last-Modified` ci-dessus sont ce qu'un client renvoie dans `If-None-Match` ou `If-Modified-Since`. La durĂ©e de conservation vous appartient, et elle se place sur les chemins oĂč elle est vraie : ```caddyfile http://:8080 { root * /srv/site encode zstd gzip header Cache-Control "public, max-age=60" @assets path /assets/* header @assets Cache-Control "public, max-age=31536000, immutable" file_server } ``` MesurĂ© : `Cache-Control: public, max-age=60` sur la page, `public, max-age=31536000, immutable` sur `/assets/*`. Une valeur immuable n'est honnĂȘte que si les noms de fichiers changent avec le contenu, ce que font les outils de build en ajoutant un hachage. Les requĂȘtes partielles ne demandent aucune configuration ; un client qui demande les dix premiers octets les obtient : ```text HTTP/1.1 206 Partial Content Content-Length: 10 Content-Range: bytes 0-9/36000 ``` ## 🧭 Applications d'une seule page Une application qui route dans le navigateur a besoin que tout chemin inconnu renvoie son document d'entrĂ©e, tandis que les vrais fichiers continuent d'ĂȘtre servis : ```caddyfile http://:8080 { root * /srv/site try_files {path} /index.html file_server } ``` MesurĂ© : `/assets/big.txt` rĂ©pond toujours `200` avec son propre contenu, et `/some/spa/route` rĂ©pond `200` avec `index.html`. Sans la ligne `try_files`, la seconde requĂȘte est un `404`. ## đŸ—‚ïž Listes de rĂ©pertoire `file_server browse` affiche une liste pour un rĂ©pertoire sans fichier d'index : ```caddyfile http://:8080 { root * /srv/site file_server browse } ``` La liste nomme les entrĂ©es : `/assets/` affiche `big.txt` sous un titre `Index of`. Laissez `browse` de cĂŽtĂ© sauf si le rĂ©pertoire est fait pour ĂȘtre lu ainsi. ## 🔒 Masquer des fichiers ⚠ Les fichiers commençant par un point sont servis comme les autres : `.hidden` a rĂ©pondu `200` dans la configuration ci-dessus, et c'est ainsi que `.git`, `.env` et les sauvegardes d'Ă©diteur finissent sur Internet. Pour les Ă©carter, rĂ©pondez avant que le serveur de fichiers ne s'exĂ©cute : ```caddyfile http://:8080 { root * /srv/site @hidden path /.* respond @hidden "Not found" 404 file_server } ``` MesurĂ© : `/.hidden` rĂ©pond `404` tandis que `/` et `/assets/big.txt` rĂ©pondent toujours `200`. Le `404` plutĂŽt que `403` est dĂ©libĂ©rĂ© — un `403` confirme que le fichier existe. ## ⚠ Quand cela ne marche pas - **`Unsupported feature: 'encode br'`.** Brotli est refusĂ© par son nom ; utilisez `encode zstd gzip`. - **`Unknown directive 'file_server: 
'`.** L'option n'existe pas, et `validate` nomme l'orthographe refusĂ©e au lieu de l'ignorer. - **Une liste de rĂ©pertoire au lieu de la page.** Le rĂ©pertoire n'a pas d'`index.html` : c'est soit voulu, soit un fichier manquant. - **`404` pour une route que l'application gĂšre.** Le repli manque : `try_files {path} /index.html`. - **Une nouvelle page n'apparaĂźt pas aprĂšs un rechargement.** Le rechargement applique la politique, pas un nouvel Ă©couteur ; les fichiers sont lus Ă  chaque requĂȘte, donc ajouter un fichier est immĂ©diat et dĂ©placer l'Ă©couteur ne l'est pas ([ExĂ©cution comme service](/fr/start/service/#-ce-que-signifie-un-rechargement)). ## 🧭 Étapes suivantes - [Proxifier une application](/fr/guides/reverse-proxy/) : l'autre moitiĂ© du serveur. - [`file_server`](/fr/reference/directives/#file_server) : la rĂ©fĂ©rence de la directive. - [`try_files`](/fr/reference/pingclairfile/) : comment le repli est compilĂ©.