- Reprodutibilidade bit por bit significa que, ao fazer o build a partir da mesma fonte, o resultado final será completamente idêntico até o nível de bytes, não importa quando, onde ou por quem o build seja feito
- Para isso, é preciso eliminar todos os elementos não determinísticos, como timestamps, cache e metadados que podem variar sutilmente conforme o ambiente de build
- Ao fazer o build direto da imagem Docker e comparar se o digest (hash) é o mesmo da imagem oficial distribuída, qualquer pessoa pode verificar de forma independente que a imagem publicada não foi adulterada: isso é importante do ponto de vista de segurança da cadeia de suprimentos
- A imagem Docker do Arch Linux agora é fornecida de forma reproduzível bit por bit, expandindo para o Docker o mesmo marco alcançado há alguns meses com a imagem WSL
- Essa imagem é distribuída com a tag dedicada
reproe, para garantir a reprodutibilidade, é necessário remover as chaves do pacman da imagem, então não é possível usarpacmanimediatamente- Até que uma solução adequada seja definida, essa limitação faz com que ela seja oferecida primeiro em uma tag separada
- Para instalar ou atualizar pacotes dentro do contêiner, primeiro é necessário recriar o keyring executando
pacman-key --init && pacman-key --populate archlinux- Isso pode ser feito de forma interativa na primeira execução ou em uma instrução
RUNdo Dockerfile que usa essa imagem como base - No Distrobox, isso pode ser tratado com um pre-init hook, como em
distrobox create -n arch-repro -i docker.io/archlinux/archlinux:repro --pre-init-hooks "pacman-key --init && pacman-key --populate archlinux"
- Isso pode ser feito de forma interativa na primeira execução ou em uma instrução
- A reprodutibilidade bit por bit da imagem é confirmada pela correspondência do digest entre builds e verificada com
podman inspect --format '{{.Digest}}' <image>e pela comparação comdiffoci - O método para reproduzir essa imagem Docker pode ser consultado em
REPRO.md
Implementação e ajustes
- O maior desafio foi construir de forma determinística o rootFS base da imagem Docker, e foi reutilizado o mesmo processo da imagem WSL, que compartilha o sistema de build do rootFS
- O commit relacionado da WSL pode ser visto aqui
- Entre os ajustes específicos para Docker, um deles foi definir
SOURCE_DATE_EPOCHe fazer com que o LABELorg.opencontainers.image.createddo Dockerfile também o seguisse - No estágio do Dockerfile, foi removido da imagem gerada o arquivo de cache auxiliar do
ldconfig,var/cache/ldconfig/aux-cache, que causava não determinismo - Ao usar
docker buildoupodman build, aplica-se a normalização de timestamps com as opções--source-date-epoch=$SOURCE_DATE_EPOCHe--rewrite-timestamp- Como exemplo, foi mostrado o problema de horários gravados de forma diferente entre
etc/,etc/ld.so.cache,etc/os-release,sys/,var/cache/,var/cache/ldconfig/,proc/,dev/
- Como exemplo, foi mostrado o problema de horários gravados de forma diferente entre
- O conjunto completo das mudanças relacionadas pode ser visto com mais detalhes no diff da merge request do repositório
archlinux-docker - Como próximo passo, está sendo considerada a criação de um rebuilder em servidor para a imagem Docker, a imagem WSL e futuras imagens reproduzíveis, com rebuilds automáticos periódicos, verificação de reprodutibilidade e publicação dos logs e resultados de build
1 comentários
Comentários do Hacker News
É bom ver esse tipo de confiança
Rodei Arch Linux no WSL 2 por quase 1 ano e foi excelente, depois usei Arch nativo por cerca de 5 meses e também fiquei muito satisfeito
Ainda uso Arch nativo até hoje, e testo meus dotfiles com uma imagem Docker do Arch em um sistema de arquivos limpo
Quando preciso de testes de ponta a ponta configurando até um ambiente de desktop completo, rodo Arch em uma VM
Tenho muitos problemas, mas pelo menos o Arch em si não é um deles
Eu estava procurando uma configuração de dotfiles nível enterprise com métricas do Prometheus e health probes, então isso me soou exatamente assim
Eu nunca tinha achado que precisava disso, mas assim que vi passei a precisar
Se sim, queria ouvir qual foi a sua impressão
Acho que todos os contêineres Docker deveriam ter sido assim desde o começo
Rodar
apt-get updatedurante a etapa de docker build é quase um antipadrãoJá usei e funcionou muito bem
Se você não atualiza, o contêiner acumula problemas de segurança conhecidos; se atualiza, a reprodutibilidade quebra
Reprodutibilidade é claramente algo legal e traz vantagens de segurança, mas quando um contêiner passa de um mês talvez já comece a parecer um antipadrão, e uma vida útil máxima medida em dias talvez seja mais apropriada
A ideia seria baixar código-fonte tagueado e compilar tudo manualmente com gcc?
Contêineres reproduzíveis são ótimos, mas nem sempre são necessários, e existem muitos casos em que faz todo sentido rodar
apt-getdentro do contêiner e não se preocupar com reprodutibilidadeClaro, ainda dá para buscar em archives
Imagens reproduzíveis muitas vezes parecem um recurso que só traz satisfação emocional no dia a dia, mas chega o dia em que isso se torna indispensável
Nós já tivemos duas imagens que deveriam ser idênticas produzindo uma diferença de 3 bytes no timestamp em máquinas diferentes, e por causa disso perdemos uma tarde inteira fazendo bisect na direção errada
Não foi algo glamouroso, mas foi uma vitória claramente valiosa
Acho que provavelmente dá para encaixar alguma coisa que anuncie para todo mundo que você usa Arch no pipeline de CI/CD
Junto com o fato de que você faz Crossfit, claro
Se você encontra uma pessoa vegana, praticante de CrossFit e usuária de Arch, o que ela vai te contar primeiro?
Dá para ver informações sobre Reproducible Builds aqui
https://reproducible-builds.org/
A comunidade relacionada de Bootstrappable Builds está aqui
https://bootstrappable.org/
Fico pensando se sistemas como Arch ou Alpine, que são sistemas operacionais mutáveis bem projetados, podem no longo prazo vencer algo como o NixOS
Scripts de instalação têm mais expressividade do que linguagens de configuração declarativa e, em geral, também não são mais verbosos
Você ganha uma linguagem de configuração declarativa e, ao mesmo tempo, uma linguagem de programação Turing-completa e agradável de usar
Li o texto e parece bem legal, mas fiquei com a impressão de que ele mistura Dockerfile e imagem docker como se fossem a mesma coisa
Talvez tivesse sido mais fácil construir diretamente o arquivo tar da imagem com algo como o nix em vez de usar Dockerfile; claro, seria algo mais de nicho, mas ainda assim pareceria mais limpo
Pequena observação: acho mais correto usar o termo OCI Image
Funciona perfeitamente no podman também
Tenho um respeito enorme pelas pessoas que de fato tornaram isso possível
O tempo e o esforço necessários para produzir uma manchete assim são muito maiores do que parece
Totalmente à parte, mas havia uma animação naquela página que fazia quase todos os elementos descerem cerca de 20 pixels por aproximadamente 1 segundo
Como o layout estava claramente chacoalhando diante dos meus olhos, achei que isso naturalmente detonaria o CLS, mas o CLS real era 0
Isso me fez pensar se CLS é uma métrica enganosa
O CLS lida com mudanças durante a renderização inicial, então mesmo que pareça um deslocamento de layout, não é o tipo de coisa que entra no CLS
É um movimento causado por CSS transition, uma mudança previsível, então não é contabilizado como layout shift