Meu Blog // Arquivo Digital

Pensamentos, projetos e notas técnicas

Originalmente, a configuração do meu blog foi planejada como um projeto puramente IPv6 via WireGuard, já que tudo é operado em um servidor doméstico (aliás, você pode obter endereços IPv6 gratuitos em route64.org). Para aumentar a acessibilidade, adicionei agora um proxy IPv4 externo (obrigado @Larvitz).

No entanto, surgiram imediatamente problemas de SSL: como originalmente tanto o registro A quanto o AAAA passavam pelo proxy, a validação do Let's Encrypt no meu servidor falhou.

A Solução: O "Hack de IPv6"

A solução foi apontar explicitamente o registro AAAA diretamente para o IP do WireGuard do meu servidor, em vez de também encaminhá-lo pelo proxy.

  • Domínio: blog.burningboard.org
  • Registro A (Proxy): 194.28.98.217
  • Registro AAAA (Servidor): 2a11:6c7:f05:a8::2 (WireGuard)

Através deste registro AAAA direto para o meu IP do WireGuard, o Let’s Encrypt continua alcançando meu servidor diretamente via IPv6 (já que o registro AAAA é priorizado por padrão) e emite o certificado SSL. O tráfego IPv4 é repassado para mim de forma criptografada pelo proxy.

A Configuração Final

Para que a comunicação funcione sem problemas, tivemos que ajustar os servidores Caddy:

1. No meu servidor (NixOS, blog.nix)

Para que os IPs reais dos visitantes cheguem corretamente e não sejam sobrescritos pelo IP do proxy, este deve ser marcado como confiável:

services.caddy.globalConfig = ''
  servers {
      trusted_proxies static 2a06:9801:1c:1000::10
  }
'';

2. No proxy externo (Caddy)

Para que o proxy se comunique corretamente com o meu servidor via HTTPS, ele deve enviar o hostname (SNI):

reverse_proxy [https://[2a11:6c7:f05:a8::2]:443](https://[2a11:6c7:f05:a8::2]:443) {
    header_up Host {host}
    transport http {
        tls_server_name blog.burningboard.org
    }
}

O blog agora está acessível via IPv4 e IPv6, criptografado com segurança, e meu IP doméstico continua privado! 🚀

O mais importante primeiro: os habituais ficheiros Markdown continuam a ser a base – sou simplesmente um grande fã desta solução descomplicada. Mas, nos bastidores, muita coisa mudou:

Fiz alguns ajustes na configuração:

📂 Ficheiros MD: A estrutura do blog continua a ser simples, baseada em Markdown.

🌍 Mais global do que nunca: O meu blog suporta agora traduções em 43 idiomas. Sim, incluindo Klingon! 🖖 (Qapla'!)

O plano era ter uma tradução em tempo real totalmente automática, baseada no reconhecimento de idioma do navegador. Spoiler: funcionou apenas parcialmente. Nota-se que a IA é impressionante, mas ainda não está exatamente "lá" onde gostaríamos.

A solução: agora traduzo simplesmente cada artigo antecipadamente para todos os idiomas definidos, o que também é muito melhor para os motores de busca (SEO). Caso a deteção automática falhe, podem definir manualmente o vosso idioma preferido através do ícone do globo, que será guardado de forma simples através de um cookie.

As traduções são agora realizadas com o Gemini 3 Flash, que apresenta resultados surpreendentemente bons. No entanto, é preciso estar atento à IA: na primeira execução em massa, as tags também foram traduzidas por engano, o que, obviamente, não estava planeado.

O código continua disponível (se estiverem interessados, basta enviarem-me uma mensagem) 👍 Mas tenham em atenção que o sistema agora necessita da sua própria chave de API do Gemini 🔑.

Decidi mudar meu blog do WriteFreely para uma solução própria: o MD-Blog (o MD, claro, significa Markdown). O gatilho foi uma atualização malsucedida do sistema antigo – mas, no fim, foi o impulso perfeito para simplificar tudo radicalmente e ganhar o controle total sobre o design.

O núcleo são arquivos Markdown simples na pasta data/, que são convertidos em HTML moderno em tempo de execução. O resultado é ultrarrápido, dispensa banco de dados e, graças ao meu próprio sistema de design (incluindo modo escuro), agora tem exatamente a aparência que eu imaginei. Até mesmo um moderno botão de compartilhamento do Mastodon já está integrado.

Se você tiver interesse no código ou na configuração enxuta, sinta-se à vontade para entrar em contato comigo pelo Mastodon!

Na verdade, a ideia por trás do #Winboat é excelente, mas a implementação parece ser um pouco instável no momento. Desde a instalação no início do ano, o sistema funcionou, mas hoje o software parou completamente de responder.

A imagem relatou subitamente memória RAM insuficiente. Tentei corrigir o problema manualmente, o que infelizmente tornou o sistema definitivamente inutilizável. Em vez de investir mais tempo na resolução de problemas, mudei diretamente para a imagem Windows do Dockurr – que, de qualquer forma, serve como base técnica para o Winboat.

Mensagem de erro

1. Preparação

Como utilizo o Podman, primeiro criei os diretórios necessários no meu sistema host. Dessa forma, a integridade dos dados é preservada caso o container precise ser recriado:

mkdir -p $HOME/Windows/System
mkdir -p $HOME/Windows/Shared

2. O comando de inicialização

Nota importante: Substitua os espaços reservados nas variáveis -e USERNAME e -e PASSWORD pelas suas credenciais pessoais.

podman run -d \
  --name windows \
  -p 8006:8006 \
  --device=/dev/kvm \
  --cap-add NET_ADMIN \
  -e RAM_SIZE="8G" \
  -e USERNAME="Carsten" \
  -e PASSWORD="1234" \
  -e LANGUAGE="German" \
  -v $HOME/Windows/System:/storage:Z \
  -v $HOME/Windows/Shared:/shared:Z \
  --stop-timeout 120 \
  dockurr/windows

Assim que o container estiver ativo, você poderá acessar a instância do Windows diretamente pelo seu navegador:

http://127.0.0.1:8006

Container em execução

3. Resumo

Só precisei executar o comando acima uma única vez. No uso diário, o ambiente Windows agora pode ser controlado de forma muito conveniente através destes comandos rápidos:

  • Iniciar: podman start windows
  • Parar: podman stop windows (ou desligar diretamente dentro do Windows)
  • Verificar status: podman ps -a

Links adicionais:

Instalei o meu próprio blog — principalmente para conhecer melhor o #NixOS. Surpreendentemente, tudo correu de forma bastante simples.

O WriteFreely é ideal para isso: minimalista, rápido de configurar e sem excessos. Perfeito para começar logo e aprender algo pelo caminho. A configuração é agradavelmente clara. Definir algumas opções, preparar o diretório, colocar um reverse proxy à frente — e já está.

Aqui está a minha configuração atual do NixOS para o efeito:

{ config, pkgs, ... }:

{
  services.writefreely = {
    enable = true;
    host = "blog.burningboard.org"; 
    settings = {
      server = {
        port = 8080;
        min_log_level = "debug";
      };
      app = {
        host = "https://blog.burningboard.org";
        single_user = true;
        landing = "/read";
        wf_modesty = true;
        federation = true;
        public_stats = true;
        theme = "write";
      };
    };
    stateDir = "/opt/writefreely";
  };

  # Correção para a geração de chaves ActivityPub: a federação requer openssl
  systemd.services.writefreely.path = [ pkgs.openssl ];

  # Criação automática do diretório de dados com as permissões corretas
  systemd.tmpfiles.rules = [
    "d /opt/writefreely 0700 writefreely writefreely -"
  ];

  services.caddy.virtualHosts."blog.burningboard.org".extraConfig = ''
    reverse_proxy 127.0.0.1:8080 {
      header_up Host {host}
      header_up X-Real-IP {remote_host}
      header_up X-Forwarded-For {remote_host}
      header_up X-Forwarded-Proto {scheme}
    }
  '';
}

No essencial, é isto. O NixOS torna realmente fácil configurar este tipo de serviços de forma limpa e mantê-los reproduzíveis.