Intégrer des fichiers statiques dans votre binaire Go avec statik
Intégrer des fichiers statiques dans votre binaire Go avec statik
Construire des applications web en Go implique souvent de jongler entre un binaire et une collection de ressources statiques — pages HTML, styles CSS, bundles JavaScript, images, polices, etc. Livrer un seul exécutable contenant tout peut simplifier le déploiement, réduire la confusion sur les chemins de fichiers et éviter les erreurs de ressources manquantes en production. L'écosystème Go propose un outil pratique à cette fin : statik.
statik est un petit outil en ligne de commande qui parcourt un répertoire et génère un fichier source Go qui enregistre le contenu avec un http.FileSystem.
Ce guide vous montre comment installer l'outil, générer des fichiers embarqués, les utiliser dans le code et quelques bonnes pratiques.
Pourquoi utiliser statik ?
- Déploiement à fichier unique – livrez un seul binaire, sans fichiers externes. Idéal pour les images Docker, les fonctions serverless ou pour embarquer des ressources dans une CLI.
- Accès type‑sûr – le package généré offre un fs.FileSystem typé; les erreurs de compilation apparaissent dès le début.
- Sortie déterministe – par défaut, statik conserve les dates de modification des fichiers ; des drapeaux optionnels permettent de désactiver cette option pour des scénarios CI.
1. Installez le CLI statik
# Go 1.22+ supporte `go install` avec @latest
go install github.com/rakyll/statik@latest
Sur les anciennes versions de Go vous pouvez récupérer le module manuellement :
go get github.com/rakyll/statik
Le binaire se trouvera dans $GOPATH/bin ou $HOME/go/bin selon votre environnement.
2. Préparez un dossier d’assets statiques
Créez un dossier nommé public (ou n’importe quel nom) et mettez-y vos assets :
└─ public/
├─ index.html
├─ styles.css
├─ script.js
└─ images/
└─ logo.png
N’hésitez pas à utiliser un nom de répertoire différent ; rappelez‑vous simplement du chemin que vous passerez à statik.
3. Générez le code Go
Exécutez statik sur le dossier. Deux options courantes :
-src: le chemin vers le répertoire source.-srcpath: le nom du package dans lequel sera inclus le code généré.
# Usage classique
statik -src=./public
Cela produit un dossier statik contenant un fichier statik.go qui enregistre tout depuis public.
Filtrage par extension
Si vous ne voulez incorporer que certains types de fichiers dans un seul binaire (pour garder la taille raisonnable), utilisez le drapeau -include :
statik -src=./public -include=*.html,*.css,*.js
Ou exclure :
statik -src=./public -exclude=*.png,*.jpg
Ignorer les horodatages de modification
Dans les pipelines CI, le checkout Git peut donner des valeurs mtime différentes de celles de développement, ce qui rompt les tests déterministes. Pour les supprimer, utilisez -m :
statik -m -src=./public
4. Utiliser le système de fichiers embarqué dans votre code
Importez le package généré et initialisez un fs.FileSystem.
package main
import (
"fmt"
"log"
"net/http"
"io"
"github.com/rakyll/statik/fs"
// Import du package généré ; le nom du package est celui créé par -srcpath,
// généralement `statik` si vous n’utilisez pas de chemin personnalisé.
_ "./statik"
)
func main() {
// Créer une instance du système de fichiers statik
statikFS, err := fs.New()
if err != nil {
log.Fatalf("statik: %v", err)
}
// Lire éventuellement un seul fichier
r, err := statikFS.Open("/index.html")
if err != nil {
log.Fatalf("open: %v", err)
}
defer r.Close()
content, _ := io.ReadAll(r)
fmt.Println("Loaded \"index.html\" content:", string(content)[:100])
// Servir le contenu via HTTP
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(statikFS)))
log.Println("Serving on http://localhost:8080/static/")
log.Fatal(http.ListenAndServe(":8080", nil))
}
Exécution du programme :
go run main.go
Ouvrez http://localhost:8080/static/index.html pour voir votre page statique servie depuis le binaire.
5. Conseils & astuces
- Gardez vos assets légers – statik fonctionne mieux quand la taille totale reste inférieure à quelques mégaoctets.
- Utilisez le drapeau
-md5(fonctionnalité future, pas encore publiée) pour stocker des sommes de contrôle MD5 pour l’intégrité. - Évitez les reconstructions binaires massives – relancez statik uniquement lorsque les assets changent. Automatisez avec un target Makefile ou des hooks git.
- Vérifiez les builds déterministes – des tests unitaires peuvent ouvrir un fichier depuis le FS généré et en vérifier le contenu ou le timestamp.
6. Où d'autre peut-on utiliser statik ?
- Outils CLI qui ont besoin de modèles locaux.
- Fonctions Go serverless – embarquez les dépendances et les assets directement.
- Applications de bureau Go – incluez icônes, fichiers d’aide et modèles de configuration.
L'outil est maintenu activement ; consultez le dépôt GitHub pour les nouvelles versions et améliorations.
Conclusion
Emballer les ressources statiques avec votre binaire Go simplifie le déploiement et réduit les dépendances externes. statik fournit une solution élégante, sans configuration supplémentaire, qui s'intègre proprement avec le http.FileSystem de Go. En suivant les étapes ci‑dessus, vous pourrez générer, embarquer et servir des fichiers statiques en quelques minutes, tout en gardant vos environnements de production épurés et simples.