Mi sitio web, 'One Binary' (2022)
(j3s.sh)- Si un sitio web personal se convierte en un binario único, una sola persona puede entender toda la estructura y darle mantenimiento directamente, reduciendo la carga de depender de la combinación tradicional de SSG + hosting
- Combinaciones como Hugo y GitHub Pages parten de varias condiciones externas, como la continuidad del servicio, el mantenimiento del proyecto, el ecosistema de plugins, el método de despliegue y Go
- Editar HTML manualmente es simple y estable, pero dificulta manejar de forma repetida las funciones comunes y vuelve agotador el flujo de trabajo, por lo que hacía falta una forma más disfrutable de ajustarlo
- Un sitio dinámico basado en Go puede resolver con código del lado del servidor tareas engorrosas en sitios estáticos, como mostrar la IP o actualizar feeds RSS, y devuelve HTML terminado también a herramientas que no son el navegador
- Un sitio web personal dura más si empieza pequeño y crece con la biblioteca estándar y herramientas simples; si se empieza con frameworks grandes, es difícil seguirles el ritmo dentro del tiempo personal
Por qué las herramientas web existentes no encajaban
- Probé varios enfoques, desde Ghost, Hugo, Jekyll y sr.ht con tarball hasta la edición manual de HTML, pero ninguno se ajustaba a mis criterios personales ni me resultaba interesante
- El criterio más importante era tener un sistema que una sola persona pudiera entender de principio a fin y mantener con facilidad
- código fácil de leer
- ciclo de retroalimentación rápido
- diversión e ingenio
- una estructura en la que pudiera profundizar por mi cuenta cuando algo se rompiera
- Los generadores de sitios estáticos (SSG) como Hugo toman plantillas y Markdown como entrada y producen HTML, y normalmente se usan junto con una plataforma de hosting
- La combinación de Hugo y GitHub Pages trae consigo varias condiciones de mantenimiento
- el servicio GitHub Pages debe seguir funcionando
- el producto GitHub Pages debe seguir siendo mantenido
- el proyecto Hugo y la documentación de la comunidad deben seguir vigentes
- puede haber dependencia del ecosistema de plugins
- el binario de Hugo debe seguir generando HTML casi de la misma forma con el paso del tiempo
- el mecanismo de despliegue de GitHub Pages debe seguir funcionando
- se necesita Go
- También existe la opción de fijar una versión específica de Hugo, pero en la práctica a veces hay que actualizar por bugs
Ventajas y límites de editar HTML manualmente
- También elegí alojar el sitio web en una máquina bajo mi propio control y editar HTML a mano con Vim
- La primera versión de j3s.sh se hizo de esa manera, y muchas de las ideas de layout actuales salieron de ahí
- Escribir HTML a mano se sentía como trabajo manual pesado, lo que llevaba a un minimalismo extremo
- meter los estilos directamente en el HTML
- minimizar las funciones compartidas en todo el sitio
- evitar en gran medida el estilizado
- Este enfoque era simple, estable y fácil de mantener
- el HTML escrito podía reutilizarse sin modificaciones
- no había dependencias externas
- daba confianza en que el sitio duraría mucho tiempo
- Aun así, quería manejar con más eficiencia la plantillización de funciones comunes y necesitaba una forma divertida de ajustar el sitio sin usar frameworks existentes
Sitio web en Go como binario único
- Si todo el sitio web se escribe en un solo lenguaje, el resultado puede desplegarse dentro de un único binario
- Go era una opción adecuada para mantenimiento personal y despliegue simple
- fácil de mantener por una sola persona
- enfatiza usar pocas dependencias
- el lenguaje es relativamente simple
- ofrece garantía de compatibilidad hacia atrás
- permite crear fácilmente binarios compilados estáticamente
- en la mayoría de los casos compila en menos de 10 segundos
- tiene una biblioteca estándar bien desarrollada
- Como resultado, j3s.sh se convirtió en un solo binario que sirve el sitio web
La simplicidad que aporta un sitio web dinámico
- Según el caso, un sitio generado dinámicamente puede ser más simple que uno generado de forma estática
- no hace falta idear rodeos para generar contenido
- se puede generar lo necesario al momento
- La función que muestra la dirección IP del visitante se implementa fácilmente con
http.HandlerFuncde Go- lee el encabezado
X-Forwarded-For - conecta un handler a la ruta
/ip - la misma función puede llamarse donde haga falta
- lee el encabezado
- Para implementar la misma función en un sitio estático puede hacer falta una dependencia externa como JavaScript, y también hay que considerar los casos donde no hay JavaScript
- algunos lectores se niegan a ejecutar JavaScript
- Si el servidor ya devuelve HTML con la dirección IP incluida, el cliente recibe una respuesta correcta incluso si no entiende JavaScript
- esto también funciona igual para herramientas que no son navegadores
- El feed RSS de la página principal se genera al iniciar el sitio web
- puede volver a traer las publicaciones más recientes de amigos
- se considera que el fetcher de RSS hecho por el propio autor funcionará durante mucho tiempo sin mantenimiento
- su funcionamiento interno se entiende con precisión
Despliegue y cómo empezar
- El despliegue se resuelve con un script de shell corto
- trae el repositorio Git
- si la rama local está atrasada, ejecuta
git merge origin/main - compila con
go build - mueve el binario a
/usr/local/bin/j3s.sh - reinicia el servicio con
service j3s.sh restart
- Este script se ejecuta cada minuto como cronjob, así que si el repositorio se actualiza, el sitio se vuelve a compilar
- si se prueba localmente y luego se sube, el cambio se refleja en el sitio público en menos de 1 minuto
- es lo bastante simple como para entenderse en 10 segundos si se sabe un poco de shell
- Los sitios web personales dan hoy una sensación distintiva en la web y pueden reflejar a fondo lo que su operador considera importante
- Quien prefiera sitios estáticos puede seguir usándolos, pero para personas con valores parecidos puede encajar bien probar con un sitio web dinámico
- se puede empezar en pequeño
- se pueden agregar ideas divertidas de forma iterativa
- como es tu propio sitio, se puede hardcodear
- puede hacerse en el lenguaje que te guste, como Rust, Perl o Python
- Hay que empezar pequeño
- primero crea
index.htmly concéntrate en servirlo con el lenguaje elegido - agrega RSS o Markdown más adelante, cuando realmente hagan falta
- si es posible, usa las herramientas más simples y mantenibles, como la biblioteca estándar
- en Ruby se puede considerar Sinatra en lugar de Rails, y en Python opciones más pequeñas en vez de Flask, como Gin
- incluso se puede intentar primero implementarlo directamente con 0 librerías
- primero crea
- Si se empieza con frameworks grandes o proyectos con breaking changes constantes, es difícil seguirles el ritmo dentro del tiempo personal y uno puede agotarse rápido
- La web necesita más rareza, emoción y personalidad, y se recomienda intentar crear un sitio web dinámico
1 comentarios
Opiniones de Hacker News
En móvil, el ancho del sitio web no se calcula bien, así que para leer hay que desplazarse de izquierda a derecha.
Justo antes de hacer eso había leído la frase “tengo estándares muy altos y peculiares”, así que, honestamente, me dio un poco de risa :)
pre, por eso se ve como un enorme párrafo ¯_(ツ)_/¯He visto formatos raros muchas veces, pero es la primera vez que veo ausencia total de formato.
Aun así, la primera impresión no es buena.
No lo entiendo.
Está bien que se sienta orgulloso, pero yo simplemente decidí no leerlo.
La clave es qué significa exactamente “mantenerlo simple” y qué significa “comprensible”.
Este tipo de textos se saltan el debate interesante y dan por sentado que su enfoque es simple y que el objetivo es la simplicidad.
Cuando puedes elegir una abstracción —por ejemplo una biblioteca o un framework, un servicio o una API—, ¿es más simple usarla o no usarla?
Si no la usas y lo construyes tú mismo, entiendes mejor cómo funciona todo el sistema, así que en cierto sentido es más simple.
Pero la complejidad sigue apareciendo y, según el caso, también tienes que crear tú mismo capas de abstracción.
En cambio, si la usas, oculta la complejidad, por lo que en el camino normal el sistema puede verse como más simple; pero esa complejidad sigue existiendo y queda escondida, así que no la entiendes.
Ambos enfoques parecen claramente simples desde cierta perspectiva, pero hay que ir más allá de esa evidencia para ver los trade-offs.
Normalmente compras los ingredientes y las herramientas, y la horneas en un horno que ya existe.
Pero si quieres hacer una tarta de manzana desde cero, primero tienes que crear el universo, y probablemente crearías el universo más simple que soporte una tarta de manzana.
Todo el stack podría ser más simple, pero la última etapa —hacer la tarta en sí— podría volverse más compleja, y quizá tampoco sepa excelente.
A cambio, obtienes una tarta que entiendes por completo desde primeros principios.
Quizá te guste esta charla de Rich Hickey: https://paulrcook.com/blog/simple-made-easy
Puedes agregar funciones para hacer que algo sea más fácil de construir o desplegar, pero esa adición vuelve el conjunto más complejo y más difícil de entender o de rastrear cuando hay problemas.
El autor dice al final, con mucha claridad, que cada quien lo haga a su manera.
Además, también dice que no está satisfecho usando sistemas que le resultan difíciles de entender o que le parecen una carga.
Conviene leer más allá del primer párrafo.
¡Muy genial!
No estoy para nada de acuerdo con “¡ustedes también deberían hacerlo así!” :)
La mantenibilidad es uno de mis valores centrales, así que, igual que tú, también hago yo mismo el mantenimiento de mi bicicleta.
Pero para mí no es una prioridad tan absoluta como para que estas decisiones tengan sentido.
La laptop Framework muestra bien nuestra diferencia.
Tú sigues sacando 9 puntos del lado DIY, mientras que yo aseguro mi resiliencia teniendo una ThinkPad de repuesto de hace 10 años con la que puedo levantar Linux y Neovim de urgencia en cualquier momento; y si incluso esa se rompe, confío en que seguirá habiendo muchas ThinkPad por menos de 100 dólares.
Llevo conmigo suficientes conocimientos de ciencias de la computación y matemáticas como para, si algún día hiciera falta, escribir con combinadores de Haskell un parser lento, no oficial y lleno de bugs de Markdown a HTML, pero no creo que ese día llegue pronto.
Si pudiera, me gustaría contratarte.
Serías el contrapeso perfecto para muchísimas personas que se inclinan en la dirección opuesta.
Disfruté mucho leer este texto.
El autor es honesto consigo mismo y serio con sus lectores.
Existe como sí mismo, sin excusas, e intenta alcanzar sus objetivos de una forma que coincide con sus valores y le da placer.
Está bien que esos valores no coincidan con los tuyos; de hecho, eso es algo hermoso.
Ahora tienes una pista sobre un camino que puedes explorar.
El texto es amable, humilde y auténtico, y creo que el autor y el texto hacen del mundo un lugar un poco mejor.
Lo mismo con lo de humilde.
Todo el texto se acerca más a un autoelogio, y en medio aparecen fragmentos al estilo /r/confidentlyincorrect.
Los lectores son solo un elemento secundario, así que por más espartana que sea la experiencia de lectura, eso no es lo central; lo central es la experiencia del autor.
Parece que mucha gente que llegó desde plataformas móviles abandonó la lectura demasiado pronto.
Lo leí por encima, y esta persona casi seguro nos está troleando.
El sitio web dice usar literalmente “plain HTML”, pero en realidad es plain text.
No hay nada de HTML para formato.
No hay títulos, párrafos ni listas, ni siquiera etiquetas a.
El poco HTML y CSS que tiene más bien hacen que el sitio se renderice peor.
El autor es un troll.
Dice que “tengo estándares muy altos y poco comunes”, y que “este script se ejecuta cada minuto como un cronjob y vuelve a compilar el sitio si el repositorio git se actualizó”.
Eso equivale a hacer fetch de un repositorio al que quizá le haga unos pocos commits al año 525,600 veces al año.
Ya entiendo por qué usó la palabra “poco comunes”.
git fetches básicamente algo muy cercano a una sola comparación de strings [0], así que no creo que sea una operación tan costosa como suena.[0] https://stackoverflow.com/a/44476803
No hay que preguntar, hay que decirlo.
Todos mis repositorios git están en el mismo servidor que aloja el sitio web.
git no hace un fetch remoto, sino un fetch local, así que en la práctica termina al instante.
Incluso si fuera un fetch remoto, habría estado bien.
525,600 requests HTTP al año son menos desperdicio que el heartbeat de NetworkManager.
En Arch, el valor predeterminado es 1 request de heartbeat cada 30 segundos.
Como referencia, un servidor nginx básico con 8 CPU puede manejar más de 500,000 requests HTTP por segundo.
Para OP:
Veo muchos comentarios muy críticos acá.
Dicho con respeto… no les hagas caso.
Puede que las críticas tengan razón, pero la industria va rápidamente hacia una estupidez a gran escala siguiendo “hay que hacer” y “debería hacerse” colectivos.
Buena parte de eso, por ahora, no tiene más validez que una leyenda urbana.
Lo que hoy se llama “ingeniería” daría risa si no estuviéramos construyendo activamente el futuro sobre eso.
Mi padre era ingeniero aeroespacial, y creo que se revolcaría en la tumba si viera lo que en el desarrollo de software moderno se llama ingeniería.
Es una sección de comentarios, así que cualquiera tiene libertad de opinar, pero en lo personal, recién después de 25 años en la industria logré ignorar esas voces parlanchinas y, en las raras oportunidades en que puedo, hacer lo que a mí me parece sensato.
¿Y con más razón si se trata de un sitio personal, no?
Esa vieja frase del anuncio de Apple, “para los locos”, ahora suena muy lejos de la verdad.
No sorprende, viendo en qué se convirtió internet y cómo lugares que alguna vez fueron startups ahora son los monstruos corporativos más grandes del panorama.
La cita de Theodore Roosevelt sobre el “hombre en la arena” hoy realmente viene al caso.
Sigue adelante, OP, sigue adelante…
Mi sitio no es un sitio perfectamente optimizado, sino mi parque de juegos sagrado y único.
Todo está escrito por mí y va evolucionando con el tiempo.
Está claro que a veces mi estilo irrita a la gente, y estoy acostumbrado a esas críticas.
A veces tomo decisiones raras para doblar el contenido hasta darle la forma que me gusta, pero creo que justo eso hace que mi contenido sea encantador.
Porque no es igual a todo lo demás que hay afuera.
Tendrá bordes ásperos, pero va a ir mejorando mientras exploro el “formato personal” :)
Para mí, un sitio web es como un proyecto artístico a largo plazo.
Debe representar a su autor, y en mi caso mi sitio me representa sin complejos.
Ya que mostraste lo tuyo, voy a mostrar lo mío.
Mi sitio web, motor de juego y servidor web son un solo binario.
El código fuente son 1000 líneas de C, y el binario pesa 164 KB.
No sé por qué demonios es tan grande.
También incluí mi propio servidor web.
Los servidores existentes agregan demasiada complejidad oculta.
El resultado, un juego de ficción interactiva en alemán, se puede ver acá: http://vmd34232.contaboserver.net/
Sin tracking, sin anuncios, sin fines comerciales.
Podrías intentar comprimir el ejecutable con upx https://upx.github.io/
https://toldby.ai/
El mío no es un binario único, es asp.net.
Estoy totalmente de acuerdo con todos los puntos que plantea el artículo, pero este sitio web es un ejemplo medio malo.
Dice que el sitio es “un solo binario”, pero la estrategia de despliegue incluye compilar en vez de ejecutar el artefacto binario.
Dice que no quiere depender de github pages, pero depende de recursos externos de openlibrary.org.
Dice que hacerlo uno mismo permite aprovechar estándares públicos, pero los archivos
.htmldentro dethoughts/son estructuras de texto plano con una extensión falsa.Cuando la gente toma este camino, normalmente intenta meter todo en la carga inicial de la página, pero acá hay varios archivos estáticos servidos dinámicamente.
El código en Golang no cachea ninguna respuesta ni guarda plantillas en memoria.
En el archivo
go.modhay varias dependencias, y todas parecen no usarse.Lo más importante es que no hay ninguna discusión sobre qué ventaja técnica tiene el espíritu de binario único frente a la infraestructura moderna.
Personalmente creo que es una buena idea, pero este es un mal ejemplo.
Es un binario único que funciona junto con el sistema de archivos.
Todo el contenido está en el sistema de archivos.
El “binario único” es un servidor web Golang liviano que sirve contenido desde el sistema de archivos.
Dice “estándares muy altos y poco comunes”; poco comunes sí, pero el diseño del sitio web resultante es tan pésimo que ni siquiera puede mostrar bien el texto ajustado a la pantalla, así que los estándares son más bien muy bajos.