Meu website, 'One Binary' (2022)
(j3s.sh)- Ao transformar um website pessoal em um binário único, uma única pessoa consegue entender toda a estrutura e fazer a manutenção diretamente, reduzindo o peso das dependências em comparação com combinações tradicionais de SSG e hospedagem
- Combinações como Hugo e GitHub Pages pressupõem várias condições externas, como continuidade do serviço, manutenção do projeto, ecossistema de plugins, método de deploy e até Go
- Editar HTML manualmente é simples e estável, mas dificulta lidar com recursos comuns de forma repetida e torna o fluxo de trabalho cansativo, então era necessário um jeito mais agradável de ajustar o site
- Um site dinâmico em Go permite tratar no código do servidor tarefas incômodas em sites estáticos, como mostrar o IP ou atualizar feeds RSS, e retorna HTML completo também para ferramentas que não são o navegador
- Em websites pessoais, o ideal é começar pequeno e crescer com biblioteca padrão e ferramentas simples; começar com frameworks grandes dificulta acompanhar tudo dentro do tempo livre
Por que as ferramentas tradicionais de website não serviram
- Foram testadas várias abordagens, de Ghost, Hugo, Jekyll, sr.ht com tarball, até edição manual de HTML, mas nenhuma se encaixou nos critérios pessoais nem pareceu interessante
- O critério mais importante era um sistema que uma pessoa pudesse entender de ponta a ponta e manter com facilidade
- código fácil de ler
- ciclo de feedback rápido
- diversão e esperteza
- estrutura em que fosse possível investigar diretamente quando algo quebrasse
- Geradores de sites estáticos (SSG) como Hugo recebem templates e Markdown como entrada e geram HTML, normalmente usados junto com uma plataforma de hospedagem
- A combinação de Hugo com GitHub Pages traz várias condições de manutenção
- o serviço GitHub Pages precisa continuar funcionando
- o produto GitHub Pages precisa continuar sendo mantido
- o projeto Hugo e sua documentação comunitária precisam ser mantidos
- pode haver dependência do ecossistema de plugins
- o binário do Hugo precisa continuar gerando HTML praticamente da mesma forma com o passar do tempo
- o mecanismo de deploy do GitHub Pages precisa continuar funcionando
- Go é necessário
- Existe a opção de fixar uma versão específica do Hugo, mas na prática podem surgir bugs que acabam exigindo upgrade
Vantagens e limites da edição manual de HTML
- Também foi escolhida a abordagem de hospedar o website em uma máquina sob controle direto e editar HTML na mão com Vim
- A primeira versão de j3s.sh foi feita desse jeito, e muitas das ideias de layout atuais vieram dali
- Escrever HTML manualmente faz o processo parecer um trabalho pesado e repetitivo, o que leva a um minimalismo extremo
- estilos colocados diretamente no HTML
- minimização de recursos comuns em todo o site
- pouca estilização
- Esse método era simples, estável e fácil de manter
- o HTML escrito podia ser reutilizado sem modificação
- não havia dependências externas
- isso transmitia confiança de que o site duraria muito tempo
- Ainda assim, havia o desejo de tratar com mais eficiência a templateização de recursos comuns e de ter uma forma divertida de ajustar o site sem recorrer a frameworks existentes
Website em Go como binário único
- Ao escrever o website inteiro em uma única linguagem, é possível empacotar o resultado e distribuí-lo como um único binário
- Go era uma escolha adequada para manutenção individual e deploy simples
- fácil para uma pessoa manter
- enfatiza o uso reduzido de dependências
- a linguagem é relativamente simples
- há garantia de compatibilidade retroativa
- é fácil gerar binários compilados estaticamente
- na maioria dos casos, compila em menos de 10 segundos
- a biblioteca padrão é muito bem desenvolvida
- Como resultado, j3s.sh se tornou um único binário que serve o website
A simplicidade trazida por um website dinâmico
- Dependendo do caso, um website gerado dinamicamente pode ser mais simples do que um gerado estaticamente
- não é preciso pensar em contornos para gerar conteúdo
- o necessário pode ser gerado na hora
- O recurso de exibir o endereço IP do visitante é implementado facilmente com
http.HandlerFuncem Go- lê o header
X-Forwarded-For - conecta um handler ao caminho
/ip - a mesma função pode ser chamada onde for necessário
- lê o header
- Para implementar o mesmo recurso em um site estático, talvez fosse preciso depender de algo externo como JavaScript, além de considerar casos sem JavaScript
- alguns leitores se recusam a executar JavaScript
- Se o servidor já retorna HTML com o endereço IP incluído, o cliente recebe a resposta correta mesmo sem entender JavaScript
- isso funciona do mesmo jeito também para ferramentas que não são navegador
- O feed RSS da página inicial é gerado no momento em que o website inicia
- é possível buscar novamente os posts mais recentes dos amigos
- a avaliação é de que o fetcher de RSS feito à mão continuará funcionando por muito tempo sem manutenção
- seu funcionamento interno é compreendido com exatidão
Deploy e como começar
- O deploy é feito com um script de shell curto
- traz o repositório Git
- se o branch local estiver atrasado, executa
git merge origin/main - faz o build com
go build - move o binário para
/usr/local/bin/j3s.sh - reinicia o serviço com
service j3s.sh restart
- Esse script roda a cada minuto como cronjob, reconstruindo o site quando o repositório é atualizado
- ao testar localmente e enviar, a mudança aparece no site público em menos de 1 minuto
- é simples o suficiente para quem entende um pouco de shell compreender em menos de 10 segundos
- Websites pessoais têm hoje uma sensação única na web e podem refletir profundamente aquilo que o operador considera importante
- Quem combina mais com sites estáticos pode continuar usando-os, mas para quem compartilha valores parecidos, tentar um website dinâmico pode funcionar muito bem
- é possível começar pequeno
- dá para adicionar ideias interessantes de forma iterativa
- como o site é seu, não há problema em hardcode
- pode ser feito na linguagem de que você gosta, como Rust, Perl ou Python
- É preciso começar pequeno
- primeiro, faça um
index.htmle foque em servi-lo com a linguagem escolhida - RSS ou Markdown podem ser adicionados depois, quando realmente forem necessários
- se possível, use as ferramentas mais simples e mais fáceis de manter, como a biblioteca padrão
- em Ruby, pode fazer mais sentido considerar Sinatra em vez de Rails; em Python, opções menores podem ser melhores que frameworks mais pesados
- também vale tentar primeiro implementar tudo diretamente, sem bibliotecas
- primeiro, faça um
- Se começar com frameworks grandes ou projetos que vivem introduzindo breaking changes, fica difícil acompanhar no tempo pessoal disponível e o cansaço chega rápido
- A web precisa de mais estranheza, empolgação e personalidade, e vale a pena tentar criar websites dinâmicos
1 comentários
Opiniões no Hacker News
No mobile, a largura do site não é calculada corretamente, então é preciso rolar para a esquerda e para a direita para ler o texto
Logo antes de fazer isso, eu tinha lido a frase “tenho padrões muito altos e incomuns”, então, sinceramente, achei meio engraçado :)
pre, parecendo um parágrafo gigante ¯_(ツ)_/¯Já vi formatação estranha muitas vezes, mas foi a primeira vez que vi ausência total de formatação
Ainda assim, a primeira impressão não é boa
Não entendo
É ótimo que a pessoa tenha orgulho do que faz, mas eu simplesmente decidi não ler
A questão central é o que diabos significa “manter simples” e o que significa algo ser “compreensível”
Textos assim pulam o debate interessante e assumem que a própria abordagem é simples e que o objetivo é a simplicidade
Quando você pode escolher uma abstração, por exemplo uma biblioteca ou framework, um serviço ou API, é mais simples usar ou não usar?
Se você não usa e faz por conta própria, passa a saber melhor como o sistema inteiro funciona, então, em certo sentido, é mais simples
Mas a complexidade ainda surge e, dependendo do caso, você também precisa criar as próprias camadas de abstração
Por outro lado, se você usa, a complexidade fica escondida; então, no caminho feliz, o sistema pode ser visto como mais simples, mas essa complexidade ainda existe e está oculta, então você não a entende
Ambas as formas parecem obviamente simples de uma determinada perspectiva, mas é preciso ir além dessa obviedade para enxergar os trade-offs
Normalmente, você compra os ingredientes e as ferramentas e assa em um forno já existente
Mas, para fazer uma torta de maçã do zero, primeiro é preciso criar o universo, e provavelmente você criaria o universo mais simples que suporte tortas de maçã
A stack inteira pode ser mais simples, mas a etapa final, fazer a torta de fato, pode ficar mais complexa, e talvez o sabor não seja o melhor
Em compensação, você obtém uma torta que entende completamente a partir dos primeiros princípios
Talvez você goste desta palestra do Rich Hickey: https://paulrcook.com/blog/simple-made-easy
É possível adicionar funcionalidades para tornar algo mais fácil de criar ou distribuir, mas esse acréscimo torna o todo mais complexo e dificulta entender ou rastrear problemas
No fim, o autor diz com muita clareza que cada um deve fazer do seu jeito
Além disso, ele também diz que não fica satisfeito usando sistemas que lhe parecem difíceis de entender ou pesados
Seria bom ler também depois do primeiro parágrafo
Muito legal!
Eu definitivamente não concordo com “vocês também deveriam fazer assim!” :)
Manutenibilidade é um dos meus valores centrais, então, assim como você, também faço a manutenção da minha bicicleta
Mas, para mim, isso não é uma prioridade tão absoluta a ponto de escolhas como essas fazerem sentido
O notebook Framework é um ponto que mostra bem a nossa diferença
Você continua tirando nota 9 no lado DIY, mas eu garanto minha resiliência tendo um ThinkPad reserva de 10 anos em que posso rodar Linux e Neovim às pressas a qualquer momento; e, se até ele quebrar, confio que ainda haverá muitos ThinkPads por menos de 100 dólares no futuro
Carrego comigo conhecimento suficiente de ciência da computação e matemática para, se um dia for necessário, escrever com combinadores em Haskell um parser lento, não oficial e cheio de bugs de Markdown para HTML, mas não acho que esse dia vá chegar tão cedo
Se fosse possível, eu gostaria de contratar você
Você seria o contrapeso perfeito para inúmeras pessoas que pendem na direção oposta
Gostei muito de ler este texto
O autor é honesto consigo mesmo e sincero com os leitores
Ele existe como é, sem desculpas, e tenta alcançar seus objetivos de uma forma alinhada aos seus valores e que lhe dá prazer
Tudo bem se esses valores não combinam com os seus; na verdade, isso é algo bonito
Agora você ganhou pistas sobre um caminho que pode explorar
O texto é gentil, humilde e autêntico, e acho que o autor e o texto tornam o mundo um pouco melhor
O mesmo vale para dizer que é humilde
O texto inteiro está mais para autoelogio, e aqui e ali aparecem trechos no estilo /r/confidentlyincorrect
O leitor é apenas um alvo secundário; por isso, por mais espartana que seja a experiência do leitor, esse não é o ponto central, e sim a experiência do autor
Parece que muita gente que veio de plataformas mobile desistiu de ler cedo demais
Dei uma olhada por alto, e tenho quase certeza de que essa pessoa está nos trollando
O site diz literalmente que usa “plain HTML”, mas na prática é plain text
Não há nenhum HTML de formatação aqui
Não há títulos, parágrafos, listas, nem sequer tags a
O pouco de HTML e CSS incluído, na verdade, faz o site renderizar pior
O autor é um troll
Dizendo “tenho critérios muito altos e peculiares”, ele afirma que “esse script roda a cada minuto como um cronjob e reconstrói o site se o repositório git tiver sido atualizado”
Ou seja, acaba fazendo fetch 525.600 vezes por ano em um repositório que talvez receba só alguns commits por ano
Dá para entender por que entrou a palavra “peculiares”
git fetchna prática é quase só uma comparação de strings [0], então não acho que seja uma operação tão custosa quanto parece[0] https://stackoverflow.com/a/44476803
Não é para perguntar, é para avisar
Meus repositórios git ficam todos no mesmo servidor que hospeda o site
O git não faz fetch remoto, faz fetch local, então termina praticamente na hora
Mesmo que fosse fetch remoto, estaria tudo bem
525.600 requisições HTTP por ano são menos desperdício do que o heartbeat do NetworkManager
No Arch, o padrão é 1 requisição de heartbeat a cada 30 segundos
Para referência, um servidor nginx básico com 8 CPUs consegue processar mais de 500 mil requisições HTTP por segundo
Ao OP:
Vejo muitos comentários bem críticos por aqui
Falando com todo respeito… não ligue
As críticas podem até estar certas, mas o setor está caminhando rapidamente para uma estupidez em larga escala ao seguir um conjunto coletivo de “deve” e “tem que ser assim”
Boa parte disso, por enquanto, tem uma validade que não passa de lenda urbana
O que hoje se chama de “engenharia” seria algo para rir e deixar passar, se não estivéssemos construindo ativamente o futuro em cima disso
Meu pai era engenheiro aeroespacial, e acho que ele se reviraria no túmulo ao ver o que chamam de engenharia no desenvolvimento de software moderno
Como isto é uma seção de comentários, qualquer um é livre para falar, mas, pessoalmente, só depois de 25 anos no setor é que passei a ignorar essas vozes tagarelas e, nas raras oportunidades em que dá, fazer o que me parece fazer sentido
Ainda mais quando se trata de um site pessoal, não é?
Aquela frase antiga do anúncio da Apple, “aos loucos”, agora também soa distante da verdade
Não é de surpreender, já que a internet virou isso e lugares que um dia foram startups agora são os maiores monstros corporativos do cenário
A citação de Theodore Roosevelt sobre o “homem na arena” anda muito certeira hoje em dia
Continue, OP, continue…
Meu site não é um site perfeitamente otimizado, é meu playground sagrado e singular
Tudo foi escrito por mim e evolui com o tempo
É claro que meu estilo às vezes incomoda as pessoas, e estou acostumado com esse tipo de crítica
Às vezes tomo decisões estranhas para moldar o conteúdo no formato de que gosto, mas acho que é exatamente isso que torna meu conteúdo adorável
Porque ele não é igual ao resto que existe por aí
Pode ter arestas, mas vai melhorando à medida que exploro um “formato pessoal” :)
Para mim, um site é como um projeto artístico de longo prazo
Ele deve representar seu autor e, no meu caso, meu site me representa sem pedir desculpas
Já que você mostrou o seu, vou mostrar o meu também
Meu site, meu motor de jogo e meu servidor web são um único binário
O código-fonte tem 1000 linhas de C, e o binário tem 164 KB
Não sei por que diabos é tão grande
Também incluí meu próprio servidor web
Servidores existentes acrescentam complexidade oculta demais
O resultado, um jogo de ficção interativa em alemão, pode ser visto aqui: http://vmd34232.contaboserver.net/
Sem rastreamento, sem anúncios, sem finalidade comercial
Você pode tentar compactar o executável com upx https://upx.github.io/
https://toldby.ai/
O meu não é um binário único; é asp.net
Concordo totalmente com todos os pontos levantados no texto, mas esse site é um exemplo meio ruim
Ele diz que o site é “um único binário”, mas a estratégia de deploy inclui compilação em vez de executar um artefato binário
Diz que não vai depender do github pages, mas depende de recursos externos do openlibrary.org
Diz que, ao fazer você mesmo, pode aproveitar padrões abertos, mas os arquivos
.htmldentro dethoughts/são estruturas de texto puro com uma extensão falsaQuando as pessoas escolhem esse caminho, normalmente tentam enfiar tudo no carregamento inicial da página, mas aqui há vários arquivos estáticos servidos dinamicamente
O código em Golang não faz cache de nenhuma resposta e também não guarda templates em memória
Há várias dependências no arquivo
go.mod, e todas parecem não ser usadasO mais importante é que não há discussão sobre quais vantagens técnicas o espírito do binário único tem em comparação com a infraestrutura moderna
Pessoalmente, acho uma boa ideia, mas este é um mau exemplo
É um binário único que funciona junto com o sistema de arquivos
Todo o conteúdo está no sistema de arquivos
O “binário único” é um servidor web leve em Golang que serve conteúdo a partir do sistema de arquivos
“Critérios muito altos e peculiares”, dizem, mas peculiar até é; só que o design do site resultante é tão péssimo que nem consegue exibir o texto corretamente ajustado à tela, então os critérios são, na verdade, muito baixos