Mon site web, « One Binary » (2022)
(j3s.sh)- Transformer un site personnel en binaire unique permet à une seule personne d’en comprendre toute l’architecture et d’en assurer elle-même la maintenance, ce qui réduit la charge de dépendance des combinaisons SSG + hébergement traditionnelles
- Des combinaisons comme Hugo et GitHub Pages supposent de multiples conditions externes : continuité du service, maintenance du projet, écosystème de plugins, mode de déploiement, Go, etc.
- L’édition manuelle de HTML est simple et stable, mais elle rend difficile la gestion répétée de fonctionnalités communes et finit par fatiguer le flux de travail ; il fallait donc une approche plus agréable à ajuster
- Un site dynamique en Go peut gérer côté serveur des tâches fastidieuses pour un site statique, comme l’affichage de l’IP ou la mise à jour d’un flux RSS, et renvoie un HTML complet aussi à des outils autres que le navigateur
- Pour un site personnel, il vaut mieux commencer petit et le faire grandir avec la bibliothèque standard et des outils simples ; démarrer avec un gros framework devient difficile à suivre dans le temps personnel disponible
Pourquoi les outils web existants ne convenaient pas
- Ghost, Hugo, Jekyll, sr.ht avec tarball, jusqu’à l’édition manuelle de HTML : plusieurs approches ont été essayées, sans correspondre à des critères personnels ni susciter d’intérêt
- Le critère le plus important était un système qu’une seule personne puisse comprendre de bout en bout et maintenir facilement
- code facile à lire
- boucle de retour rapide
- plaisir et ingéniosité
- structure dans laquelle on peut soi-même creuser quand quelque chose casse
- Un générateur de site statique (SSG) comme Hugo prend des templates et du Markdown en entrée pour produire du HTML, généralement utilisé avec une plateforme d’hébergement
- La combinaison Hugo + GitHub Pages implique plusieurs conditions de maintenance
- le service GitHub Pages doit continuer à fonctionner
- le produit GitHub Pages doit continuer à être maintenu
- le projet Hugo et sa documentation communautaire doivent être maintenus
- cela peut dépendre d’un écosystème de plugins
- le binaire Hugo doit continuer à générer le HTML quasiment de la même manière au fil du temps
- le mécanisme de déploiement de GitHub Pages doit continuer à fonctionner
- Go est nécessaire
- Il est possible d’épingler une version précise de Hugo, mais en pratique des bugs finissent parfois par imposer une mise à niveau
Les avantages et limites de l’édition manuelle de HTML
- Une autre option consistait à héberger le site sur une machine contrôlée directement et à éditer le HTML à la main dans Vim
- La première version de j3s.sh a été créée ainsi, et une bonne partie des idées de mise en page actuelles en vient
- Écrire du HTML à la main donne l’impression d’un travail pénible, ce qui pousse vers un minimalisme extrême
- styles intégrés directement dans le HTML
- réduction au minimum des fonctionnalités communes à l’échelle du site
- évitement d’un stylage trop important
- Cette approche était simple, stable et facile à maintenir
- le HTML écrit pouvait être réutilisé sans modification
- il n’y avait aucune dépendance externe
- cela donnait confiance dans la longévité du site
- En revanche, il y avait le souhait de gérer plus efficacement la mise en template des éléments communs, avec une méthode agréable à ajuster sans framework existant
Un site web en binaire unique avec Go
- En écrivant tout le site web dans un seul langage, il devient possible de le déployer sous la forme d’un binaire unique
- Go était un choix bien adapté à une maintenance individuelle et à un déploiement simple
- facile à maintenir par une seule personne
- met l’accent sur un usage limité des dépendances
- langage relativement simple
- compatibilité ascendante garantie
- création facile de binaires compilés statiquement
- compilation en moins de 10 secondes dans la plupart des cas
- bibliothèque standard très riche
- Au final, j3s.sh est devenu un unique binaire qui sert le site web
La simplicité qu’apporte un site web dynamique
- Dans certains cas, un site généré dynamiquement peut être plus simple qu’un site généré statiquement
- pas besoin d’inventer des contournements pour produire le contenu
- on peut générer ce qu’il faut à la volée
- La fonction qui affiche l’adresse IP du visiteur se met en place simplement avec
http.HandlerFuncde Go- lecture de l’en-tête
X-Forwarded-For - rattachement d’un handler à la route
/ip - possibilité d’appeler la même fonction là où c’est nécessaire
- lecture de l’en-tête
- Pour obtenir la même chose sur un site statique, il peut falloir une dépendance externe comme JavaScript, tout en tenant compte des cas où JavaScript n’est pas disponible
- certains lecteurs refusent d’exécuter JavaScript
- Si le serveur renvoie déjà un HTML contenant l’adresse IP, le client reçoit la bonne réponse même s’il ne comprend pas JavaScript
- cela fonctionne aussi de la même façon pour des outils qui ne sont pas des navigateurs
- Le flux RSS de la page d’accueil est généré au démarrage du site web
- il peut récupérer à nouveau les derniers billets des amis
- le fetcher RSS maison devrait continuer à fonctionner longtemps sans maintenance
- son fonctionnement interne est compris précisément
Déploiement et manière de commencer
- Le déploiement se fait via un court script shell
- récupération du dépôt Git
- exécution de
git merge origin/mainsi la branche locale a du retard - build avec
go build - déplacement du binaire vers
/usr/local/bin/j3s.sh - redémarrage du service avec
service j3s.sh restart
- Ce script est exécuté chaque minute par un cronjob ; si le dépôt est mis à jour, le site est reconstruit
- un test en local puis un upload se reflètent sur le site public en moins d’une minute
- c’est assez simple pour être compris en 10 secondes avec un peu de connaissance du shell
- Un site personnel donne aujourd’hui une impression singulière sur le web et peut refléter en profondeur ce que son opérateur juge important
- Si le site statique vous convient, il n’y a aucune raison d’en changer, mais pour des personnes partageant des valeurs similaires, tenter un site web dynamique peut très bien convenir
- on peut commencer petit
- on peut ajouter de façon itérative des idées amusantes
- comme c’est son propre site, on peut y mettre du code en dur
- on peut le faire dans son langage préféré, comme Rust, Perl ou Python
- Il faut commencer petit
- commencer par créer
index.htmlpuis se concentrer sur sa mise à disposition avec le langage choisi - ajouter RSS ou Markdown plus tard, quand le besoin apparaît
- utiliser si possible les outils les plus simples et maintenables, comme la bibliothèque standard
- en Ruby, envisager une option plus légère comme Sinatra plutôt que Rails ; en Python, une option plus légère comme Gin plutôt que Flask
- on peut aussi commencer par voir si une implémentation maison sans aucune bibliothèque est possible
- commencer par créer
- Commencer avec un gros framework ou un projet qui introduit sans cesse des breaking changes est difficile à suivre dans le temps personnel disponible et peut vite devenir épuisant
- Le web a besoin de plus d’étrangeté, d’enthousiasme et de personnalité, et il est recommandé d’essayer de créer un site web dynamique
1 commentaires
Avis de Hacker News
Sur mobile, la largeur du site web n’est pas calculée correctement, donc il faut faire défiler horizontalement pour lire le texte.
Juste avant ça, j’avais lu la phrase « j’ai des standards très élevés et inhabituels », donc honnêtement ça m’a un peu fait rire :)
pre, ce qui le fait ressembler à un énorme paragraphe ¯_(ツ)_/¯J’ai souvent vu des mises en forme étranges, mais c’est la première fois que j’en vois une totalement absente.
Mais la première impression reste mauvaise.
Je ne comprends pas.
C’est bien qu’il en soit fier, mais moi, j’ai simplement décidé de ne pas lire.
Le point central, c’est ce que veut vraiment dire « garder les choses simples » et ce que signifie « être compréhensible ».
Ce genre de textes saute les débats intéressants et part du principe que leur approche est simple et que l’objectif est la simplicité.
Quand on a le choix d’utiliser une abstraction, par exemple une bibliothèque, un framework, un service ou une API, est-ce plus simple de l’utiliser, ou de ne pas l’utiliser ?
Si on ne l’utilise pas et qu’on construit soi-même, on comprend mieux le fonctionnement de tout le système ; dans un certain sens, c’est donc plus simple.
Mais la complexité apparaît quand même et, selon les cas, il faut aussi créer soi-même des couches d’abstraction.
À l’inverse, si on l’utilise, on masque la complexité, donc dans le parcours normal le système peut sembler plus simple ; mais cette complexité existe toujours, elle est simplement cachée, et on ne la comprend pas.
Les deux approches paraissent manifestement simples depuis un certain point de vue, mais il faut dépasser cette évidence pour voir les compromis.
En général, on achète les ingrédients et les ustensiles, puis on la cuit dans un four déjà existant.
Mais si l’on veut faire une tarte aux pommes à partir de zéro, il faut d’abord créer l’univers, et on finira probablement par créer l’univers le plus simple capable de prendre en charge une tarte aux pommes.
Toute la stack peut être plus simple, mais la dernière étape — faire réellement la tarte — peut devenir plus complexe, et le goût ne sera peut-être pas optimal.
En revanche, on obtient une tarte que l’on comprend entièrement à partir des premiers principes.
Vous pourriez aimer cette présentation de Rich Hickey : https://paulrcook.com/blog/simple-made-easy
On peut ajouter des fonctionnalités pour rendre quelque chose plus facile à créer ou à déployer, mais ces ajouts rendent l’ensemble plus complexe et plus difficile à comprendre ou à déboguer.
L’auteur dit très clairement, à la fin, que chacun doit faire à sa manière.
Il dit aussi qu’il n’est pas satisfait d’utiliser des systèmes qu’il trouve difficiles à comprendre ou lourds.
Ce serait bien de lire aussi au-delà du premier paragraphe.
Très chouette !
Je ne suis absolument pas d’accord avec le « vous devriez faire pareil ! » :)
La maintenabilité fait partie de mes valeurs fondamentales, donc comme vous je fais aussi moi-même l’entretien de mon vélo.
Mais pour moi, ce n’est pas à ce point la priorité numéro un, donc ce genre de choix n’aurait pas de sens.
Le portable Framework illustre bien notre différence.
Vous continuez à viser un 9/10 côté DIY, alors que moi, j’assure ma résilience avec un ThinkPad de secours vieux de 10 ans capable de faire tourner Linux et Neovim en urgence à tout moment, et si même celui-là tombe en panne, je pars du principe qu’il y aura encore longtemps plein de ThinkPad à moins de 100 dollars.
J’emporte avec moi assez de connaissances en informatique et en mathématiques pour pouvoir un jour, si nécessaire, écrire avec des combinateurs Haskell un parseur lent, non officiel et plein de bugs de Markdown vers HTML, mais je ne pense pas que ce jour arrive bientôt.
Si je le pouvais, j’aimerais vous recruter.
Vous seriez le contrepoids parfait face aux nombreuses personnes qui penchent dans la direction opposée.
J’ai vraiment pris plaisir à lire cet article.
L’auteur est honnête avec lui-même et sérieux envers ses lecteurs.
Il existe tel qu’il est, sans excuses, et cherche à atteindre ses objectifs d’une manière qui correspond à ses valeurs et lui procure du plaisir.
Même si ces valeurs ne correspondent pas aux vôtres, ce n’est pas grave ; au contraire, c’est beau.
Vous avez maintenant un indice sur une voie que vous pouvez explorer.
Le texte est bienveillant, humble et authentique, et je pense que l’auteur comme son texte rendent le monde un peu meilleur.
Même chose pour l’humilité.
L’ensemble du texte ressemble plutôt à de l’autocongratulation, avec par endroits des fragments dignes de /r/confidentlyincorrect.
Le lecteur n’est qu’un élément secondaire ; même si l’expérience de lecture est spartiate, ce n’est pas le cœur du sujet, car l’expérience de l’auteur est ce qui compte.
On dirait que beaucoup de gens venus de plateformes mobiles ont abandonné la lecture trop tôt.
J’ai parcouru rapidement, et je suis presque sûr que cette personne est en train de nous troller.
Le site dit utiliser littéralement du « plain HTML », mais en réalité c’est du plain text.
Il n’y a ici aucun HTML de mise en forme.
Pas de titres, pas de paragraphes, pas de listes, même pas de balise a.
Le peu de HTML et de CSS présent rend même le rendu du site pire.
L’auteur est un troll.
Il dit avoir « des critères très élevés et atypiques », et précise que « ce script s’exécute toutes les minutes via un cronjob et reconstruit le site si le dépôt git a été mis à jour ».
En gros, il récupère 525 600 fois par an un dépôt qui ne recevra que quelques commits dans l’année.
Je comprends pourquoi le mot « atypique » est là.
git fetchrevient en pratique à peu près à une simple comparaison de chaînes [0], donc je ne pense pas que ce soit une opération aussi coûteuse que ce qui est suggéré.[0] https://stackoverflow.com/a/44476803
Il ne faut pas demander, il faut avertir.
Tous mes dépôts git se trouvent sur le même serveur que celui qui héberge le site web.
git ne fait pas de fetch distant, mais un fetch local, donc c’est pratiquement instantané.
Et même si c’était un fetch distant, ça irait quand même.
525 600 requêtes HTTP par an, c’est moins gaspilleur que le heartbeat de NetworkManager.
Sur Arch, la valeur par défaut est une requête de heartbeat toutes les 30 secondes.
À titre de référence, un serveur nginx de base avec 8 CPU peut traiter plus de 500 000 requêtes HTTP par seconde.
À l’OP :
Je vois ici beaucoup de commentaires très critiques.
Avec tout le respect… ne t’en soucie pas.
Les critiques ont peut-être raison, mais le secteur suit des « il faut » et des « ça devrait » collectifs et fonce rapidement vers une bêtise à grande échelle.
Une bonne partie de tout ça n’a, pour l’instant, guère plus de validité qu’une légende urbaine.
Ce qu’on appelle aujourd’hui « ingénierie » serait risible si nous n’étions pas activement en train de construire l’avenir dessus.
Mon père était ingénieur en aérospatiale, et je pense qu’il se retournerait dans sa tombe en voyant ce que le développement logiciel moderne appelle de l’ingénierie.
C’est une section de commentaires, donc chacun est libre de parler, mais personnellement, il m’a fallu 25 ans dans l’industrie pour ignorer ces voix bavardes et, dans les rares occasions où c’est possible, faire ce qui me semble avoir du sens.
Et a fortiori quand il s’agit d’un site personnel, non ?
La vieille formule de la publicité Apple, « à ceux qui sont assez fous », semble aujourd’hui bien éloignée de la vérité.
Vu ce qu’est devenu Internet, et vu que des entreprises qui étaient autrefois des startups sont désormais les plus grands monstres du paysage, ce n’est pas surprenant.
La citation de Theodore Roosevelt sur « l’homme dans l’arène » sonne vraiment juste ces temps-ci.
Continue, OP, continue…
Mon site web n’est pas un site parfaitement optimisé, c’est mon terrain de jeu sacré et singulier.
Tout est écrit à la main et évolue avec le temps.
Je sais bien que mon style peut irriter certaines personnes, et je suis habitué à ce genre de critiques.
Je prends parfois des décisions étranges pour plier le contenu dans une forme qui me plaît, mais je pense que c’est précisément ce qui rend mon contenu attachant.
Parce qu’il n’est pas comme tout le reste.
Il y aura sans doute des aspérités, mais en explorant ce « format personnel », ça s’améliorera avec le temps :)
Pour moi, un site web est comme un projet artistique au long cours.
Il doit représenter son auteur, et dans mon cas, mon site me représente fièrement.
Puisque tu as montré le tien, je vais montrer le mien.
Mon site web, mon moteur de jeu et mon serveur web sont un seul binaire.
Le source fait 1 000 lignes de C, et le binaire pèse 164 Ko.
Je ne sais pas pourquoi il est aussi foutrement gros.
J’ai aussi inclus le serveur web moi-même.
Les serveurs existants ajoutent trop de complexité cachée.
Le résultat, un jeu de fiction interactive en allemand, est visible ici : http://vmd34232.contaboserver.net/
Pas de tracking, pas de publicité, pas d’objectif commercial.
Tu peux essayer de compresser l’exécutable avec upx : https://upx.github.io/
https://toldby.ai/
Le mien n’est pas un binaire unique, c’est de l’asp.net.
Je suis entièrement d’accord avec tous les points soulevés dans l’article, mais ce site web est un assez mauvais exemple.
Il dit que le site est « un seul binaire », mais la stratégie de déploiement inclut la compilation au lieu d’exécuter un artefact binaire.
Il dit ne pas vouloir dépendre de github pages, mais dépend de ressources externes d’openlibrary.org.
Il dit qu’en faisant soi-même, on peut tirer parti des standards ouverts, mais les fichiers
.htmldansthoughts/sont des structures en texte brut avec une fausse extension.Quand les gens choisissent cette voie, ils essaient généralement de tout intégrer au chargement initial de la page, alors qu’ici il y a plusieurs fichiers statiques servis dynamiquement.
Le code Golang ne met aucune réponse en cache et ne garde pas les templates en mémoire.
Le fichier
go.modcontient plusieurs dépendances, qui semblent toutes inutilisées.Plus important encore, il n’y a aucune discussion sur les avantages techniques de l’esprit du binaire unique par rapport à l’infrastructure moderne.
Personnellement, je trouve l’idée bonne, mais c’est un mauvais exemple.
C’est un binaire unique qui fonctionne avec le système de fichiers.
Tout le contenu est dans le système de fichiers.
Le « binaire unique » est un serveur web Golang léger qui sert le contenu depuis le système de fichiers.
« Des critères très élevés et atypiques », dit-il ; atypiques, oui, mais le design du site web produit est si mauvais qu’il n’arrive même pas à afficher correctement le texte à l’écran, donc les critères sont au contraire très bas.