Moby: apenas tempo de construção -v opção

Criado em 21 jun. 2015  ·  258Comentários  ·  Fonte: moby/moby

Conforme sugerido por @cpuguy83 em https://github.com/docker/docker/issues/3156
aqui está o caso de uso para uma opção -v flexível em tempo de compilação.

Ao construir uma imagem do Docker, preciso instalar um banco de dados e um aplicativo. Está tudo embrulhado em dois tarballs: 1 para o banco de dados e 1 para o aplicativo que precisa ser instalado nele (esquema, objetos, dados estáticos, credenciais etc.). A solução inteira é então executada por meio de um script de shell que lida com várias variáveis ​​de shell e ajusta as credenciais do sistema operacional e outras coisas de acordo.
Quando explodo o tarball acima (ou uso a diretiva Dockerfile ADD), a coisa toda incha até cerca de 1,5 GB (!). Não é o ideal como você pode imaginar.

Eu gostaria de ter esta diretiva '-v /distrib/ready2installApp:/distrib' ainda possível (como é hoje no Dockerfile)
mas

Gostaria de desassociar o processo de compilação declarativo (infraestrutura como código) do artefato implantável em tempo de execução do contêiner. Não quero ter que lidar com o peso morto de 1,5 GB que não preciso.

Podemos ter uma opção --unmount-volume que eu possa executar no final do Dockerfile?
ou
Dado como o Volume funciona agora em um Dockerfile, talvez precisemos de uma nova diretiva Dockerfile para um volume temporário que as pessoas usam durante a instalação? Acho que o exemplo Puppet fornecido por @fatherlinux estava em uma linha semelhante ...
ou
O que quer que vocês possam pensar.
O objetivo é evitar ter que carregar todo aquele peso morto que é inútil para um Aplicativo ou Serviço implantado. No entanto, esse peso morto é necessário @install-time. Nem todo mundo tem uma simples "instalação yum" dos repositórios oficiais. :)

Muito obrigado

arebuilder kinfeature

Comentários muito úteis

Eu tenho um caso de uso um pouco diferente para esse recurso - pacotes de cache que são baixados/atualizados pelo gerenciador de pacotes ASP.Net 5 . O gerenciador de pacotes gerencia sua própria pasta de cache, então eu só preciso de uma pasta que eu possa reutilizar entre as compilações.

Ou seja:

docker build -v /home/dokku/cache/dnx/packages:/opt/dnx/packages -t "dokku/aspnettest" .

Todos 258 comentários

Estou procurando uma solução semelhante.

Problema

Recentemente, a empresa em que trabalho habilitou o proxy Zscaler com inspeção SSL, o que implica ter certificados instalados e algumas variáveis ​​de ambiente definidas durante a compilação.

Uma solução temporária foi criar um novo Dockerfile com certificados e variáveis ​​de ambiente definidas. Mas isso não parece razoável, em uma visão de longo prazo.

Então, meu primeiro pensamento foi definir um proxy transparente com HTTP e HTTPS, mas novamente preciso passar um certificado durante a compilação.

O cenário ideal é com o mesmo Dockerfile, eu conseguiria construir minha imagem no meu laptop, em casa e na empresa.

Solução possível

# Enterprise
$ docker build -v /etc/ssl:/etc/ssl -t myimage .

# Home
$ docker build -t myimage .

Eu tenho um caso de uso um pouco diferente para esse recurso - pacotes de cache que são baixados/atualizados pelo gerenciador de pacotes ASP.Net 5 . O gerenciador de pacotes gerencia sua própria pasta de cache, então eu só preciso de uma pasta que eu possa reutilizar entre as compilações.

Ou seja:

docker build -v /home/dokku/cache/dnx/packages:/opt/dnx/packages -t "dokku/aspnettest" .

@yngndrw o que você propõe seria bom para mim também, ou seja, precisamos montar recursos extras em tempo de compilação que não seriam necessários em tempo de execução, pois foram instalados no contêiner.

FWIW Eu vi em algum lugar nestas páginas alguém dizendo algo ao longo da linha de (e espero estar parafraseando certo) "resolva seu problema de compilação em uma máquina host semelhante e instale o artefato implantável ou exe no contêiner".
Receio que não seja tão simples caras. Às vezes, preciso instalar em /usr/bin, mas também preciso editar algum arquivo de configuração. Eu verifico o sistema operacional em que estou executando, os parâmetros do kernel que preciso ajustar, os arquivos que preciso criar dependendo de variáveis ​​ou arquivos de compilação de manifesto. Existem muitas dependências que simplesmente não ficam satisfeitas com uma simples cópia de um produto compilado.

Reafirmo o que disse quando abro o problema: há uma diferença entre um arquivo de declaração de manifesto e seu processo e o tempo de execução de um artefato.
Se realmente acreditamos em infraestrutura como código e, além disso, em infraestrutura imutável, que o próprio Docker está promovendo ainda mais e eu gosto disso, então isso precisa ser seriamente considerado IMO (veja o inchaço no post 1 aqui)

Obrigado novamente

Outro caso de uso realmente interessante é a atualização de software. Há momentos, como com o FreeIPA, você deve realmente testar com uma cópia dos dados de produção para garantir que todos os diferentes componentes possam ser atualizados de forma limpa. Você ainda deseja fazer a atualização em um ambiente de "compilação". Você deseja que a cópia de produção dos dados resida em outro lugar para que, quando você mover as novas versões atualizadas dos contêineres para produção, elas possam acumular os dados exatos em que você fez a atualização.

Outro exemplo, seria o Satellite/Spacewalk que muda o esquema com frequência e até mudou os bancos de dados Oracle para Postgresql na versão 5.6 (IIRC).

Existem muitos, muitos cenários em que preciso temporariamente de acesso a dados enquanto faço uma atualização de software em uma compilação em contêiner, especialmente com serviços distribuídos/micro....

Essencialmente, agora sou forçado a fazer uma atualização manual executando um contêiner regular com uma montagem de ligação -v e, em seguida, fazendo um "commit do docker". Não consigo entender por que o mesmo recurso não estaria disponível com uma compilação automatizada do Dockerfile?

Apoiando @yngndrw apontando o cache: exatamente o mesmo raciocínio se aplica a muitos projetos populares como Maven, npm, apt, rpm -- permitir um cache compartilhado pode acelerar drasticamente as compilações, mas não deve chegar à imagem final.

Concordo com @stevenschlansker. Pode haver muitos requisitos para anexar volume de cache ou algum tipo de poucos gigabytes de dados, que devem apresentar (no estado analisado) na imagem final, mas não como dados brutos.

Também fui mordido pela resistência consistente em estender docker build para suportar os volumes que podem ser usados ​​por docker run . Eu não achei o mantra 'host-independent builds' muito convincente, pois parece apenas tornar o desenvolvimento e a iteração em imagens do Docker mais difíceis e demorados quando você precisa baixar novamente todo o repositório de pacotes toda vez que reconstruir uma imagem.

Meu caso de uso inicial foi o desejo de armazenar em cache os repositórios de pacotes do SO para acelerar a iteração de desenvolvimento. Uma solução alternativa que tenho usado com algum sucesso é semelhante à abordagem sugerida por @fatherlinux , que é simplesmente desistir de lutar com docker build e Dockerfile e começar do zero usando docker run em um script de shell padrão seguido por docker commit .

Como um experimento, estendi minha técnica para um substituto completo para docker build usando um pouco de script de shell POSIX: dockerize .

Se alguém quiser testar este script ou a abordagem geral, por favor, deixe-me saber se é interessante ou útil (ou se funciona para você). Para usar, coloque o script em algum lugar em seu PATH e adicione-o como um shebang para seu script de compilação (o #! ), então defina as variáveis ​​de ambiente relevantes antes de uma segunda linha shebang marcando o início do seu script de instalação do Docker.

As variáveis FROM , RUNDIR e VOLUME serão passadas automaticamente como argumentos para docker run .
As variáveis TAG , EXPOSE e WORKDIR serão passadas automaticamente como argumentos para docker commit .

Todas as outras variáveis ​​serão avaliadas no shell e passadas como argumentos de ambiente para docker run , tornando-as disponíveis em seu script de compilação.

Por exemplo, este script irá armazenar em cache e reutilizar pacotes Alpine Linux entre compilações (o VOLUME monta um diretório inicial para CACHE, que é então usado como um link simbólico para o cache do repositório de pacotes do SO no script de instalação):

#!/usr/bin/env dockerize
FROM=alpine
TAG=${TAG:-wjordan/my-image}
WORKDIR=/var/cache/dockerize
CACHE=/var/cache/docker
EXPOSE=3001
VOLUME="${HOME}/.docker-cache:${CACHE} ${PWD}:${WORKDIR}:ro /tmp"
#!/bin/sh
ln -s ${CACHE}/apk /var/cache/apk
ln -s ${CACHE}/apk /etc/apk/cache
set -e
apk --update add gcc g++ make libc-dev python
[...etc etc build...]

Então, depois de conhecer o contingente francês :) do Docker na MesoCon na semana passada (foi um prazer pessoal), fiquei sabendo que eles têm o mesmo problema internamente e eles desenvolveram um hack que copia para uma nova imagem slim o que eles precisam .
Eu diria que hacks não são bem-vindos no mundo corporativo ;) e essa solicitação deve ser tratada adequadamente.
Obrigado por ouvir galera...

Também sou a favor de adicionar o sinalizador -v em tempo de compilação para acelerar as compilações compartilhando um diretório de cache entre elas.

@yngndrw Não entendo por que você fechou dois problemas relacionados. Li sua edição nº 59 e não vejo como isso se relaciona com isso. Em alguns casos, os contêineres ficam super inchados quando não são necessários em tempo de execução. Por favor, leia o 1º post.
Espero não estar faltando nada aqui... pois foi um longo dia :-o

@zrml O problema https://github.com/aspnet/aspnet-docker/issues/59 estava relacionado ao cache interno por camada que o docker fornece durante uma compilação para todos os arquivos do docker, mas esse problema atual é sutilmente diferente, pois estamos falando sobre o uso de volumes de host para fornecer cache específico do dockerfile, que depende do dockerfile fazer uso especial do volume. Fechei o problema https://github.com/aspnet/aspnet-docker/issues/59 , pois não está especificamente relacionado ao projeto/repositório aspnet-docker.

O outro problema ao qual acho que você está se referindo é o problema https://github.com/progrium/dokku/issues/1231 , que dizia respeito aos processos Dokku desabilitando explicitamente o cache da camada docker integrado. Michael fez uma alteração no Dokku para permitir que esse comportamento fosse configurável e isso resolveu o problema em relação ao projeto/repositório Dokku, então esse problema também foi encerrado.

Possivelmente ainda há um problema relacionado ao Docker que está pendente (por exemplo, por que o Docker não estava manipulando o cache de camada interno como eu esperava no problema https://github.com/aspnet/aspnet-docker/issues/59), mas Eu não tive a chance de descobrir por que isso acontece e confirmar se ainda está acontecendo. Se ainda for um problema, um novo problema para este projeto/repositório deve ser levantado para ele, pois é diferente deste problema atual.

@yngndrw exatamente, então concordamos que isso é diferente e conhecido @docker.com, então estou reabrindo se você não se importa ... bem, não posso. Você se importa, por favor?
Eu gostaria de ver alguns comentários de nossos colegas em SF pelo menos antes de fecharmos

BTW, fui solicitado por @ cpuguy83 para abrir um caso de usuário e explicar tudo, do log # 3156

@zrml Não tenho certeza se sigo - É https://github.com/aspnet/aspnet-docker/issues/59 que você deseja reabrir? Não é um problema /aspnet/aspnet-docker, então não acho certo reabrir esse problema. Deve ser realmente um novo problema em /docker/docker, mas precisaria ser verificado e precisaria gerar etapas reproduzíveis primeiro.

não, não.. este #14080 que você fechou ontem.

Esta questão ainda está em aberto?

@yngndrw Acredito que interpretei mal o ícone vermelho "fechado". Desculpas.

Concordo sinceramente que o tempo de construção -v seria uma grande ajuda.

O cache de compilação é um caso de uso.

Outro caso de uso é usar chaves ssh em tempo de compilação para compilar a partir de repositórios privados sem que eles sejam armazenados na camada, eliminando a necessidade de hacks (embora bem projetados) como este: https://github.com/dockito/vault

Estou comentando aqui porque isso é um inferno no mundo corporativo.
Nós temos um proxy de interceptação SSL, enquanto eu posso direcionar o tráfego através dele, muitos projetos assumem que eles têm boas conexões SSL, então eles morrem horrivelmente.

Mesmo que minha máquina (e, portanto, o construtor do docker) confie no proxy, as imagens do docker não.
Pior ainda, a melhor prática agora é usar curl dentro do contêiner, então isso é doloroso, eu tenho que modificar Dockerfiles para torná-los ainda compilados. Eu poderia montar os certificados com uma opção -v e ficar feliz.

Dito isso. É menos culpa do docker, mais culpa dos gerenciadores de pacotes usando https quando deveriam estar usando um sistema semelhante ao funcionamento do apt-get. Como isso ainda é seguro e verificável, e também pode ser armazenado em cache por um proxy http.

@btrepp obrigado por outro bom caso de uso.

Posso pensar em outra situação.

Uma das coisas que eu gostaria de fazer com meus dockerfiles é não enviar as ferramentas de compilação com o arquivo docker "compilado". Não há motivo para um aplicativo C precisar do gcc, nem um aplicativo ruby ​​precisar do bundler na imagem, mas usando o docker build atualmente enquanto temos isso.

Uma ideia que tive é especificar um dockerfile, que executa vários comandos docker ao compilar dentro dele. Arquivos de encaixe pseudo-ish abaixo.

Arquivo do Docker que compila outros

FROM dockerbuilder
RUN docker build -t docker/builder myapp/builder/Dockerfile
RUN docker run -v /app:/app builder
RUN docker build -t btrepp/myapplication myapp/Dockerfile

arquivo de encaixe btrepp/myapplication

FROM debian:jessie+sayrubyruntime
ADD . /app //(this is code thats been build using the builder dockerfile
ENTRYPOINT ["rails s"]

Aqui temos um contêiner temporário que faz todo o gerenciamento de instalação/pacote do pacote e qualquer script de compilação, mas produz os arquivos que o contêiner de tempo de execução precisa.

O contêiner de tempo de execução apenas adiciona os resultados disso, o que significa que não deve precisar de muito mais do que ruby ​​instalado. No caso de, digamos, GCC ou ainda melhor, vinculado estaticamente, podemos não precisar de nada além dos arquivos principais do sistema operacional para executar.

Isso manteria as imagens do docker super leves.

O problema aqui é que o contêiner temporário do construtor desapareceria no final, o que significa que seria super caro sem a capacidade de carregar um tipo de cache, estaríamos pegando debian:jessie um monte de vezes.

Já vi pessoas com certas técnicas como essa, mas usando servidores http externos para adicionar os arquivos de compilação. Eu preferiria manter tudo sendo construído pelo docker. Embora haja possivelmente uma maneira de usar uma imagem do docker para fazer isso corretamente. Usando run e assim sendo capaz de montar volumes.

Aqui está outro exemplo. Digamos que eu queira construir um container para systemtap que tenha todos os símbolos de depuração para o kernel nele (que são Yuuuuge). Eu tenho que montar os /lib/modules subjacentes para que o comando yum saiba quais RPMs instalar.

Além disso, talvez eu prefira tê-los em algum lugar diferente da imagem de 1,5 GB (dos símbolos de depuração)

Fui escrever um Dockerfile, então percebi que era impossível :-(

docker run --privileged -v /lib/modules:/lib/modules --tty=true --interactive=true rhel7/rhel-tools /bin/bash
yum --enablerepo=rhel-7-server-debug-rpms install kernel-debuginfo-$(uname -r) kernel-devel-$(uname -r)
docker ps -a
CONTAINER ID        IMAGE                     COMMAND             CREATED             STATUS                        PORTS               NAMES
52dac30dc495        rhel7/rhel-tools:latest   "/bin/bash"         34 minutes ago      Exited (0) 15 minutes ago                         dreamy_thompson
docker commit dreamy_thompson stap:latest

https://access.redhat.com/solutions/1420883

Eu gostaria de repetir meu caso de uso aqui do #3949, pois esse bug foi fechado por outros motivos.

Eu realmente gostaria de fazer sandbox de software proprietário no docker. É ilegal para mim hospedá-lo em qualquer lugar, e o processo de download não é realisticamente (ou legalmente) capaz de ser automatizado. No total, os instaladores chegam a cerca de 22 GB (e estão ficando maiores a cada lançamento). Acho bobagem esperar que isso seja copiado para a imagem do docker em tempo de compilação.

Alguma novidade neste recurso necessário?
obrigada

_PESQUISA DE USUÁRIO_

_A melhor maneira de ser notificado quando houver alterações nesta discussão é clicando no botão Inscrever-se no canto superior direito._

As pessoas listadas abaixo apreciaram sua discussão significativa com um +1 aleatório:

@vad

+1 para este recurso!

Outro caso de uso é usar chaves ssh em tempo de compilação para compilar a partir de repositórios privados sem que eles sejam armazenados na camada, eliminando a necessidade de hacks (embora bem projetados) como este: https://github.com/dockito/vault

Este é o nosso caso de uso também (chaves ssh renderizadas usando tmpfs no host neste caso).

Outro caso de uso para isso é para um cache local do diretório node_modules em um servidor CI para reduzir os tempos de compilação.
npm install é muito lento e mesmo no "melhor" caso atual onde o package.json é ADD ed para a imagem, npm install é executado e só então são as fontes de projeto reais adicionadas e construídas em alterações para package.json todas as dependências precisam ser baixadas novamente.

Consulte npm/npm#8836 para um problema sobre isso no lado do Node/npm.

Problema relacionado ao aspnet-docker relacionado à restauração lenta de pacotes e ao tamanho da imagem resultante do armazenamento em cache dos pacotes atuais na camada. Seria muito melhor usar um volume montado para o cache do pacote.
https://github.com/aspnet/aspnet-docker/issues/123

Este não é um problema específico do idioma, afetará muitas pessoas, pois os gerenciadores de pacotes agora são um padrão aceito.

O OP acertou o problema na cabeça, pois "docker build -v" ajudaria muito a dissociar o processo de compilação do ambiente de tempo de execução.

Eu vi vários projetos que agora constroem "Mulberry harbours" que são usados ​​para construir o docker real que é então enviado/distribuído. Isso é excessivamente complexo tanto da perspectiva de administração quanto de recursos de computação, o que, por sua vez, se traduz em CI mais lento e testes de unidade e, em geral, em um fluxo de trabalho de desenvolvimento menos produtivo.

Eu estive pensando sobre isso, e a outra opção que posso pensar é a capacidade de marcar camadas como camadas "src".

Algo ao longo das linhas dessas camadas sendo acessível apenas durante uma compilação do docker, mas não puxado no arquivo de imagem resultante.

Dessa forma, o docker pode armazenar em cache camadas/imagens anteriores, artefatos de compilação temporários, mas eles não são necessários para utilizar a imagem final.

Por exemplo.

FROM ubuntu
RUN apt-get install gcc
ADDPRIVATE . /tmp/src <--these can be cached by docker locally
RUNPRIVATE make     <-- basically these layers become scoped to the current build process/dockerfile
RUN make install <--result of this layer is required.

É claro que isso significa que você precisaria saber o que está fazendo melhor, pois poderia muito bem deixar arquivos críticos de fora.

@yngndrw
Uma solução muito melhor para situações como netcore seria não usar HTTPS para gerenciamento de pacotes, então é trivial configurar iptables + squid para ter um proxy de cache transparente para compilações do docker. game, eles são terríveis para usar em ambientes corporativos devido à renúncia do SSL, enquanto coisas como apt-get funcionam perfeitamente bem e já podem ser armazenadas em cache com iptables + squid para docker.

Também posso ver uma desvantagem em usar volumes de tempo de compilação, os dockerfiles não serão tão reproduzíveis e exigirão configuração extra fora do docker build -t btrepp/myapp ., Também dificultará as compilações automatizadas no dockerhub.

@btrepp : gostei da sua sugestão. Eu poderia até viver para meus casos de uso com um diretório TMP codificado (eu sei que geralmente é uma coisa ruim) que o Docker nos fala para que eles saibam quando construir o artefato final de todas as camadas que eles podem esquecer/deixar de fora montado em /this_is_the_tmp_explosion_folder_that_will_be_removed_from_your_final_container_image
bastante fácil....

@btrepp Eu gosto bastante da sua ideia de camada de origem.

No entanto, em relação aos gerenciadores de pacotes que não usam SSL, eu teria que discordar.

Se você deseja armazenar em cache pacotes como esse, provavelmente deve usar um feed de pacote privado (local) que espelhe a fonte oficial. Reverter para HTTP parece uma má ideia para mim, especialmente porque muitos gerenciadores de pacotes não parecem assinar seus pacotes e, portanto, dependem de HTTPS.

Existe uma ferramenta gramatical/rocker que pode ser usada enquanto esse problema ainda não estiver corrigido.

@yngndrw

Meu ponto de ser o proxy local etc é um problema que foi resolvido há muito tempo. Os gerenciadores de pacotes precisam apenas de verificação, não precisam de privacidade. Usar https é uma maneira preguiçosa de fornecer verificação, mas vem com o anexo de privacidade.

Não há razão para "super_awesome_ruby_lib" precisar ser privado ao ser puxado via http(s). A melhor maneira seria que as gemas de rubi tivessem um chaveiro. Ou até mesmo uma chave pública conhecida, e para ela assinar pacotes. É mais ou menos assim que o apt-get funciona e permite que os proxies http padrão armazenem em cache as coisas.

Em relação a um feed de pacote privado local, o docker nem mesmo suporta isso. Não há maneira de desabilitar o feed padrão e ele _com razão_ o perde se o certificado https não estiver no repositório de certificados. Tenho certeza de que o docker sempre quer pelo menos verificar o feed principal ao extrair imagens também. Afaik, a implementação do rocket/rkt usaria assinatura + http para obter imagens de contêiner.

Se a principal motivação para os volumes de tempo de compilação é apenas o armazenamento em cache de pacotes, acho que a pressão deve ser colocada nos gerenciadores de pacotes para oferecer melhor suporte ao cache, em vez de comprometer parte da automação/pureza do docker atualmente.

Para ser claro, não estou defendendo que os gerenciadores de pacotes mudem para apenas usar http e descartar https. Eles precisam de verificação de pacotes para prevenir contra ataques man in the middle. O que eles não precisam é do aspecto de privacidade usando https como ofertas de "segurança pegando tudo".

Essa é uma visão muito estreita. Você está pedindo que todo o universo de gerenciadores de pacotes mude como eles se comportam para se adequar à prescrição do Docker de como eles pensam que os aplicativos serão construídos.

Há também uma tonelada de outros exemplos de por que isso é necessário neste tópico. Dizer "bem, você deveria apenas mudar a forma como todas as ferramentas que você usa para construir seus aplicativos funcionam" não afasta o problema, apenas afasta os usuários.

(Também discordo fortemente do anexo do Docker ao registro público - prefiro proibir o acesso ao registro público e permitir que apenas o nosso interno seja usado. Mas isso é um assunto completamente diferente.)

Para mim também preciso de docker build -v .

No nosso caso, queremos construir uma imagem que consiste em uma instalação pré-configurada do produto em questão, e o instalador tem mais de 2 GB . Não sendo capaz de montar um volume de host, não podemos construir a imagem com o instalador, embora já tenhamos baixado no sistema operacional host, para o qual podemos usar várias ferramentas/protocolos, digamos proxy com https cert/auth , ou talvez até bit torrent.

Como solução alternativa, temos que usar wget para baixar novamente o instalador durante docker build , que é um ambiente muito restrito, muito menos conveniente, mais demorado e propenso a erros.

Também devido à flexibilidade das opções de instalação/configuração do produto, faz muito mais sentido enviarmos as imagens com o produto pré-instalado, em vez de enviar uma imagem apenas com o instalador.

@thaJeztah alguma chance de isso acontecer?

Fwiw, esta é a única razão pela qual eu não (ou realmente, não posso) usar o docker

Nós carregamos um patch nas versões Red Hat do docker que incluem a opção -v. Mas a verdadeira solução para isso seria criar maneiras novas e diferentes de criar imagens de contêiner OCI além da compilação do docker.

@rhatdan RHEL ou Fedora?

Também implementamos a opção -v do docker build em nossa versão interna do docker em resin.io. Você pode encontrar o diff aqui https://github.com/resin-io/docker/commit/9d155107b06c7f96a8951cbbc18287eeab8f60cc

@rhatdan @petrosagg você pode criar um PR para isso?

@jeremyherbert o patch está no daemon docker que vem em todas as versões recentes do RHEL, CentOS e Fedora...

@graingert Nós o enviamos no passado e foi rejeitado.

@rhatdan você tem um link para isso?

@runcom Você tem o link?

@thaJeztah isso é algo que vocês teriam rejeitado?

Aqui está uma lista de problemas existentes que foram encerrados ou não foram respondidos:
https://github.com/docker/docker/issues/3949
https://github.com/docker/docker/issues/3156
https://github.com/docker/docker/issues/14251
https://github.com/docker/docker/issues/18603

Informações sobre os patches do Project Atomic usados ​​no RHEL/CentOS/Fedora podem ser encontrados em:
http://www.projectatomic.io/blog/2016/08/docker-patches/

@daveisfera parece que eles só adicionam volumes R e não volumes RW, então não funcionará para @yngndrw e meu caso de uso.

@graingert Por que você precisa de volumes RW? Eu entendo somente leitura como uma solução alternativa para determinados casos.

Testar migrações de esquema seria um bom motivo...

Em 01/11/2016 10:36, Brian Goff escreveu:

@graingert https://github.com/graingert Por que você precisa de volumes RW?
Eu entendo somente leitura como uma solução alternativa para determinados casos.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/docker/issues/14080#issuecomment -257582035,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AAHLZdp0D6fAtuNglajPBIwnpWGq3slOks5q5050gaJpZM4FIdOc.

Scott McCarty

escocês. [email protected]

http://crunchtools.com

@fatherlinux

@ cpuguy83 Outro caso de uso para RW seria ccache

@fatherlinux Não tenho certeza se sigo. Por que você precisaria de um volume para isso? Além disso, por que isso deve ser feito durante a fase de construção?

Eu tenho um caso de uso um pouco diferente para esse recurso - pacotes de cache que são baixados/atualizados pelo gerenciador de pacotes ASP.Net 5. O gerenciador de pacotes gerencia sua própria pasta de cache, então eu só preciso de uma pasta que eu possa reutilizar entre as compilações.

Eu ligaria mount por exemplo:

docker build -v /home/jenkins/pythonapp/cache/pip:/root/.cache/pip  -t pythonapp .
docker build -v /home/jenkins/scalaapp/cache/ivy2:/root/.ivy2  -t scalaapp .

Porque muitas vezes a migração do esquema deve ser feita quando
o software está instalado. Se você executar contêineres somente leitura, deverá
nunca instale software a não ser quando estiver no
fase de construção.....

Em 01/11/2016 10:42, Brian Goff escreveu:

@fatherlinux https://github.com/fatherlinux Não tenho certeza se sigo.
Por que você precisaria de um volume para isso? Também por que deve ser feito durante
a fase de construção?


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/docker/issues/14080#issuecomment -257583693,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AAHLZfhBG8RUWtqPD-6RaLC7uoCNc-3nks5q50_TgaJpZM4FIdOc.

Scott McCarty

escocês. [email protected]

http://crunchtools.com

@fatherlinux

Eu sei que o conteúdo desses diretórios não fará com que a compilação seja dependente do host (a falta dessas montagens fará com que a compilação funcione de qualquer maneira, apenas mais lenta)

O NFS resolveu isso há 30 anos ...

Em 01/11/2016 10:45, Thomas Grainger escreveu:

Eu sei que o conteúdo desses diretórios não interromperá a compilação
ser idempotente ou dependente do host (a falta dessas montagens causará
a compilação para funcionar de qualquer maneira)


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/docker/issues/14080#issuecomment -257584576,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AAHLZS75Vq0BSEvUjI2oXORsS0el2mwOks5q51CQgaJpZM4FIdOc.

Scott McCarty

escocês. [email protected]

http://crunchtools.com

@fatherlinux

O NFS resolveu isso há 30 anos ...

Não é um comentário útil

@graingert desculpe, isso saiu seriamente errado. Eu estava tentando responder rápido demais e não dei contexto suficiente. Falando sério, estamos analisando o NFS em combinação com o CRIO para resolver alguns desses tipos de problemas.

Tanto o registro de imagem quanto os bulds têm muitas qualidades em comum. O que você está falando é basicamente um problema de cache. O NFS e, particularmente, o armazenamento em cache integrado podem tornar as compilações independentes do host e lidar com todo o armazenamento em cache para você.

Portanto, mesmo com uma opção de tempo de compilação -v, uma compilação não precisa ser bloqueada para apenas um host. Pode não ser independente da escala da Internet, mas é suficiente para muitas pessoas que controlam seu ambiente de construção para um único site ou local.

@fatherlinux eu usaria o cache do gitlab ou travis para pegar o diretório de cache e fazer upload/download no S3

@graingert sim, mas isso só funciona em certos tipos de dados/aplicativos, também apenas no nível do bucket, não nos metadados posix e no nível do bloco. Para certos tipos de aplicativos front-end e middleware, não há problema. Para uma migração de esquema de banco de dados, você precisa testar com antecedência e ter o cache local para velocidade e normalmente precisa ser posix.

Imagine que eu tenha um cluster MySQL Galera com 1TB de dados e quero fazer um upgrade e eles estão todos em containers. Multi-nós em contêineres/orquestrados, o Galera fragmentado é realmente conveniente. Não quero ter que testar manualmente uma migração de esquema durante cada atualização.

Eu quero fazer um instantâneo do volume de dados (pv no mundo Kube), expô-lo a um servidor de compilação e testar a atualização e a migração do esquema. Se tudo der certo e os testes passarem, então construímos os containers de produção e deixamos a migração do esquema acontecer na produção....

@graingert desculpe, esqueci de adicionar e descartar o instantâneo que foi usado na execução de teste ... Não quero orquestrar um evento de compilação e teste separadamente, embora isso seja possível ...

@fatherlinux Acho que é um caso de uso ortogonal ...

@graingert não é um comentário útil. Ortogonal a quê? Ortogonal à solicitação de um -v durante a compilação, sobre o que entendi essa conversa?

Há alguns usos diferentes que vejo para esse sinalizador.

  • um cache, compartilhamento entre servidores de compilação do docker
  • uma palavra-chave do tipo ADD que se aplica apenas 'durante a compilação' de um único Dockerfile. Por exemplo, ADICIONE um arquivo enorme e exclua-o das imagens.
  • Uma palavra-chave do tipo ADD+RUN que ignora todas as saídas. Por exemplo, ADICIONE um arquivo enorme, execute uma etapa e ignore quaisquer alterações na imagem - ADICIONE + EXECUTAR em uma etapa e pule uma camada.

Os dois casos de uso posteriores podem ser resolvidos de forma mais limpa com duas novas palavras-chave.

BUILDCONSTFILE <path>

Executaria um COPY <path> antes de cada EXECUÇÃO e excluiria <path> da imagem depois.

TEST <cmd> WITH <paths>

Que COPIaria os caminhos, executaria o comando e, com o status de saída 0, continuaria a compilação a partir da imagem pai, caso contrário, interromperia a compilação

Pessoalmente acho que TEST ... WITH é melhor tratado em outra etapa de CI que testa seu contêiner como um todo

Deixe-me começar com isso: eu _acho_ que estou bem em adicionar --mount para construir ("-v" provavelmente não tanto). Não tenho 100% de certeza sobre a implementação, como o cache é tratado (ou não tratado), etc.

Para o projeto docker, o que fazemos é construir uma imagem do construtor.
Ele basicamente tem tudo o que precisamos, copia o código, mas na verdade não cria o docker.
Temos um Makefile que orquestra isso. Então make build constrói a imagem, make binary constrói o binário com build como uma dependência, etc.

Fazer um binário roda a imagem do build e faz o build, com isso podemos montar no que precisamos, incluindo caches de pacotes para builds incrementais.
A maior parte disso é bastante direta e facilmente orquestrada.
Portanto, certamente existem maneiras de lidar com esse caso hoje, apenas o docker sozinho não pode lidar com 100% dele (e isso não é necessariamente uma coisa ruim) e você terá que fazer isso funcionar com seu sistema de CI.

@ cpuguy83 Acho que isso resolveria a maioria dos meus casos de uso. Só para eu entender, você quer dizer --mount para significar somente leitura? e -v para leitura/gravação?

@ cpuguy83 também estamos construindo principalmente imagens "construtor" que IMHO está se tornando um padrão cada vez mais comum ...

serviços de enxame @fatherlinux e agora (para 1.13) docker run suporta --mount que é muito mais preciso e flexível: https://docs.docker.com/engine/reference/commandline/service_create/# /add -bind-mounts-or-volumes

Parece que os documentos estão faltando o terceiro tipo de montagem, tmpfs .

Ah, muito legal, obrigado...

Em 01/11/2016 14:20, Brian Goff escreveu:

@fatherlinux https://github.com/fatherlinux enxame serviços e agora
(para 1.13) |execução do docker| suporta |--mount| que é muito mais preciso
e flexível:
https://docs.docker.com/engine/reference/commandline/service_create/#/add -bind-mounts-or-volumes

Parece que os documentos estão faltando o terceiro tipo de montagem, |tmpfs|.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/docker/docker/issues/14080#issuecomment -257648598,
ou silenciar o thread
https://github.com/notifications/unsubscribe-auth/AAHLZXv_VBfVi4WUAjVijE-SKR0ErRC4ks5q54L2gaJpZM4FIdOc.

Scott McCarty

escocês. [email protected]

http://crunchtools.com

@fatherlinux

@cpuguy83 também estamos usando muito o padrão do construtor e temos uma necessidade de cache que não persiste na imagem e também sobrevive à invalidação da camada.

Construímos imagens Yocto e temos um cache de estado compartilhado no armazenamento NFS. Outro caso de uso é o cache npm para que você possa invalidar toda a camada RUN npm install , mas recalcular mais rapidamente devido aos pacotes armazenados em cache.

Como um possível compromisso com base na postagem de @graingert , não seria possível ter um hash opcional do seu arquivo enorme no dockerfile e, em seguida, o docker verifica isso ao executar a compilação? Não haveria problemas com compilações determinísticas então, e seria óbvio para a pessoa que constrói que eles não têm as dependências necessárias, em vez de simplesmente explodir com um erro estranho em algum momento. A mesma coisa vale para chaves ssh, etc, que precisariam ser distribuídas com o dockerfile de qualquer maneira.

Eu também acho que qualquer ideia que exija _copiar_ do arquivo enorme é menos do que ideal. Os tamanhos de arquivo que estou interessado em usar são da ordem de 10 a 40 GB e, mesmo com um bom ssd, é necessário copiar pelo menos um minuto ou dois. Este é o meu problema com a diretiva ADD já no docker; Não quero ADICIONAR 30 GB à minha imagem toda vez que ela for compilada e ter que lidar com todo esse espaço livre extra, além de precisar compactar imagens.

Isso não funcionaria para o que estamos usando. Temos um volume que contém caches sstate do sistema de compilação yocto que é RW montado em ligação na compilação porque qualquer falta de cache será calculada durante a compilação e salva em sstate para futuras. Nossos diretórios também estão em ~ 30 GB, portanto, mesmo o cálculo do hash demoraria um pouco.

Eu nunca entendi o conceito de construção determinista. Existem maneiras de dar um tiro no pé mesmo com a semântica de hoje. Por exemplo, você pode curl algo de um IP interno. De repente, esse Dockerfile não funciona em todos os lugares e depende do host. Mas há casos legítimos de por que você gostaria de fazer isso. Por exemplo, um cache HTTP local.

Portanto, como as compilações não são determinísticas de qualquer maneira, e como é possível emular o volume montado em ligação pela rede hoje, por que não fornecer uma maneira nativa de fazer isso com os avisos apropriados, se necessário?

@petrosagg @zrml @thaJeztah O que sabemos é:

  • Se vasculharmos o #7115 #3156, podemos encontrar uma longa lista de questões que têm muitos anos discutindo esse mesmo problema
  • A maioria foi fechada por motivos de reprodutibilidade (ou o antigo comentário Dockerfile syntax is frozen e, depois que a instrução HEALTHCHECK foi adicionada, o congelamento foi removido, mas os problemas permaneceram encerrados)
  • Esse problema impediu que muitas equipes tivessem uma boa usabilidade/produtividade de contêineres no desenvolvimento diário por muitos anos. Como @btrepp disse isso é o inferno
  • O pessoal do Docker está ciente desse problema, mas isso traria uma classe de Oh my docker build broken! problemas por causa do cache compartilhado, o que não é bom
  • Mas a mudança do cache de disco para o cache de rede não parece melhorar a confiabilidade da compilação de forma alguma, age apenas como um cache-over-http glorificado, e descobriu-se que isso piora as coisas (baixar a Internet para cada compilação, HTTPS, tamanho dos arquivos, thrashing de disco ao construir contêineres, cache de camada, orquestração de compilação complicada, etc.)

Dado tudo o que sabemos, acho que isso provavelmente será fechado como Dupe ou WontFix. Não parece importar quais casos de uso damos. Atualização: estou feliz por estar errado aqui. A proposta parece aberta :)

Nossa empresa mudou para um tempo de execução de contêiner agnóstico e em breve também terá que mudar para uma experiência de construção de imagem agnóstica. Mas este não será o lugar certo para discutir isso porque a negatividade não ajuda. Isso deveria ser um post separado.

@rdsub tem o cuidado de compartilhar o link quando terminar?

@rdsubhas esse é um bom resumo. Não parece que este tópico será fechado como dupe/wontfix já que @cpuguy83 acha que está ok em adicionar --mount durante a compilação que cobre a maioria dos casos de uso.

O que eu gostaria de saber é que a proposta atual:

  1. não altera a sintaxe do Dockerfile
  2. não torna as compilações mais dependentes do host do que elas são atualmente

Quais são os contra-argumentos que restam em relação à ideia? Se não houver, talvez devêssemos começar a discutir os detalhes de implementação do mecanismo --mount .

Para reforçar o argumento de que as compilações já são dependentes do host e não reproduzíveis, forneço uma lista de fragmentos do Dockerfile com esta propriedade:

# Install different software depending on the kernel version of the host
RUN wget http://example.com/$(uname -r)/some_resource
# example.intranet is only accessible from specific hosts
RUN wget http://example.intranet/some_resource
# get something from localhost
RUN wget http://localhost/some_resource
# gcc will enable optimizations supported by the host's CPU
RUN gcc -march=native .....
# node:latest changes as time goes by
FROM node
# ubuntu package lists change as time goes by
RUN apt-get update
# install different software depending on the docker storage driver
RUN if [ $(mount | head -n 1 | awk '{print $5}') == "zfs" ]; then .....; fi

Honestamente, se apenas adicionarmos --mount e deixarmos o usuário lidar com a invalidação de cache ( --no-cache ), acho que ficaremos bem. Podemos querer examinar o controle de cache mais refinado da CLI do que tudo ou nada, mas esse é um tópico separado.

Meu caso de uso

Estou enfrentando um problema semelhante há algum tempo, mas optei por aumentar o tamanho da imagem até que uma solução seja finalizada. Vou tentar descrever meu cenário aqui caso alguém encontre uma solução melhor.

Condições

  1. CircleCI tem as chaves ssh para baixar todas as dependências internas durante a compilação
  2. O GitHub hospeda dependências internas e outras podem ser baixadas de dentro da imagem durante a compilação

Opções

  1. Use --build-arg para passar um token durante a compilação (fortemente desencorajado). Esta é uma opção muito atraente e fácil, pois "simplesmente funciona" sem etapas adicionais.
  2. Baixe todas as dependências e adicione-as ao contexto de compilação. Infelizmente, ADD e COPY são executados em camadas separadas, então estou preso aos dados das camadas anteriores.

O tamanho de algumas das minhas imagens mais que dobrou em alguns casos, mas o tamanho geral é tolerável por enquanto. Eu acho que houve um PR (não consigo encontrá-lo) para remover argumentos de tempo de compilação do histórico de compilação, mas não era aceitável devido a preocupações de armazenamento em cache irrc.
Ficarei feliz em saber de quaisquer outras soluções alternativas sendo usadas por aí.

@misakwa , provavelmente daremos suporte a segredos na versão 1.14.

É muito emocionante ouvir @cpuguy83. Vou ficar de olho quando for lançado. Isso definitivamente simplificará alguns dos meus fluxos de trabalho.

provavelmente daremos suporte a segredos na versão 1.14.

Também funcionará para mapear o mapeamento em tempo de construção de outros tipos de volumes, como por exemplo yarn-cache ?

BTW, existe uma maneira interessante de criar imagens de produção usando o docker-compose, achei que funciona e é bastante eficaz:

Então você compôs o arquivo docker-compose.build.yml algo assim:

services: 
  my-app:
    image: mhart/alpine-node:7.1.0
    container_name: my-app-build-container # to have fixed name
    volumes:
    - ${YARN_CACHE}:/root/.cache/yarn # attach yarn cache from host
    - ${HOME}/.ssh:/.ssh:ro    # attach secrets
    - ./:/source
    environment: # set any vars you need
     TEST_VAR: "some value"    
    ports:
    - "3000"
    working_dir: /app/my-app # set needed correct working dir even if if doesn't exist in container while build type
    command: sh /source/my-app.docker.build.sh # build script

1) você constrói o container usando o docker compose:

$ docker-compose -f docker-compose.build.yml up --force-recreate my-app

ele cria contêiner e executa o script de compilação do shell my-app.docker.build.sh , eu não uso Dockerfile e faço tudo no script de compilação:

  • instale os pacotes de SO necessários
  • copie o código fonte necessário (da pasta /source mapeada)
  • instalar dependências
  • construir/compilar/testar se necessário
  • remova pacotes e coisas que não são necessárias para o env de destino funcionar (para reduzir o tamanho da imagem final)

Em seguida, você cria a imagem do contêiner, substituindo o CMD, que precisa ser executado no ambiente de destino:

docker commit -c "CMD npm run serve" my-app-build-container my-app-build-image:tag

Portanto, sua imagem está pronta, usou o cache de fio externo e as chaves secretas externas que estavam disponíveis apenas durante o tempo de compilação.

@whitecolor sim, isso funciona :) exceto por uma coisa: docker build é realmente eficaz no upload do contexto de construção. Infelizmente, os volumes de origem montados não funcionam com daemons do docker remotos (por exemplo, docker-machine na nuvem para laptops de baixa potência/largura de banda). Para isso, temos que fazer uma série complicada de comandos do docker docker run , docker cp , docker run , etc.

Realmente ajuda ter isso oficialmente como parte da compilação do docker e usar camadas e contexto de compilação 😄

@rdsubhas Sim, você está correto

@whitecolor Essa é uma solução realmente simples e eficaz. Acabei de reduzir uma compilação de 30 a 40 minutos em um projeto para cerca de 5 minutos. Estou ansioso para a possibilidade de ter um --mount on build feature, mas por enquanto esta solução realmente desbloqueia meu pipeline.

Este é um comentário que deixei para a edição #17745 que eu entendi que havia sido fechada, mas não estava marcada como duplicada. Parece que eu estava errado sobre esse último ponto: admito que estou acostumado a sistemas como o Bugzilla que marcam explicitamente algo como "DUPLICADO RESOLVIDO" e exibem isso na área de descrição superior de um bug. Não sou leitor de mentes. (Então, minhas desculpas @graingert , eu tinha pouca chance de saber, portanto, não há necessidade de gritar comigo em fonte 20pt - isso foi excessivo.)


No meu caso, onde isso seria útil seria em sistemas Debian: montando /var/cache/apt como um volume, então você não está baixando novamente os mesmos arquivos .deb repetidamente. (A cota de Internet verdadeiramente "ilimitada" simplesmente não existe, especialmente aqui na Austrália, e mesmo que existisse, há perda de tempo esperando o download.)

Ou outro cenário, você está fazendo uma compilação, mas também produz relatórios de teste, como listas de falhas e relatórios de cobertura de código que você não precisa enviar com a imagem, mas são artefatos úteis para ter por perto. Eles podem ser gravados em um volume quando um servidor CI for construir a imagem para o servidor CI coletar e hospedar.

Ou esta noite, estou fazendo algumas imagens baseadas no Gentoo para mim, gostaria de montar /usr/portage do host. Não é difícil para um Dockerfile perceber, "hey, /usr/portage (no container) está vazio, sem problemas, vou pegar isso" ao executar sem o volume montado, OU, ele apenas usa o volume como está, economizando tempo na busca de uma nova cópia.

Adicionar essas inteligências é uma instrução if trivial em um script de shell Bourne... SE a lógica subjacente para montar o volume estiver presente em primeiro lugar. Agora para minhas imagens do Gentoo, estou tendo que puxar /usr/portage toda vez que faço uma compilação (felizmente, o espelho está na minha LAN), o que significa que são alguns bons minutos para esperar que essa etapa seja concluída.

Então, muitas razões pelas quais esta é uma proposta que vale a pena, e duvido que as compilações aninhadas propostas em #7115 ajudem nas instâncias acima.


@whitecolor tem uma abordagem interessante, mas se fizer isso, também posso usar um Makefile completamente externo ao sistema Docker para obter a compilação.

@sjlongland eu não estava gritando com você, eu estava preenchendo um grande aviso de "DUPLICATA RESOLVIDA"

Estou usando docker e docker-compose para construir vários contêineres para nossa infraestrutura. Os contêineres são microsserviços, principalmente escritos em nodeJS, mas há um microsserviço escrito em Java, usando o framework maven.
Toda vez que reconstruímos o contêiner java, dezenas de dependências são baixadas do Maven; isso leva vários minutos. Em seguida, o código é compilado em cerca de 15 segundos.

Isso é muito feio e afeta bastante nossa estratégia de CI.

Nesse cenário, não importa realmente se o volume com as dependências de compilação está ausente ou vazio, porque nesse caso as dependências seriam baixadas. A reprodutibilidade não é afetada.

Eu entendo que existem preocupações de segurança, porque eu poderia adulterar as dependências e injetar código desagradável nelas; IMHO que poderia ser facilmente contornado ao não permitir que imagens compiladas com "volumes de compilação" fossem publicadas no docker-hub ou no docker-store.
Para explicar isso de maneira diferente, deve haver uma distinção de escopos entre o uso corporativo e o uso pessoal do docker.

@stepps confira https://pypi.python.org/pypi/shipwright em vez de docker-compose

Eu tenho acompanhado este tópico por um tempo, procurando uma boa solução para mim. Para construir contêineres mínimos de maneira flexível com o mínimo de esforço, gosto muito de https://github.com/edannenberg/gentoo-bb de @edannenberg.

  • Ele separa as dependências de tempo de compilação das dependências de tempo de execução
  • As compilações são feitas em contêineres e são isoladas, limpas e repetíveis
  • Lida com dependências entre imagens e ordenação de compilação

É baseado no uso do portage e emerge do Gentoo, então @sjlongland você pode gostar dele para suas imagens baseadas no Gentoo. Arquivos dist e pacotes binários são armazenados em cache, portanto, não é necessário baixá-los ou compilá-los novamente, tornando as reconstruções rápidas. Possui ganchos para personalizar facilmente o processo de construção. Instalar software de terceiros é fácil, como usar o git para clonar um repositório e depois compilá-lo, mantendo apenas a compilação na imagem final. Ele modela o Dockerfile.

Um exemplo simples é para figlet é: -

build.conf:

IMAGE_PARENT="gentoobb/glibc"

Dockerfile.template:

FROM ${IMAGE_PARENT}
ADD rootfs.tar /
USER figlet
CMD ["gentoo-bb"]
ENTRYPOINT ["figlet"]

construir.sh

PACKAGES="app-misc/figlet"

configure_rootfs_build() {
        useradd figlet
}

Eu gosto da solução do @whitecolor , é simples usando apenas a tecnologia Docker e, em seguida, um script de shell simples ou qualquer outra coisa que você queira usar. Estou usando o gentoo-bb, pois é mais completo. O Shipwright fica bem com recursos mais focados no desenvolvedor, como lidar com ramificações. https://github.com/grammarly/rocker também parece interessante. Obrigado por compartilhar todos.

Apenas mais uma voz adicionada à pilha. Nosso ambiente de desenvolvimento muito complexo seria muito mais simples se pudéssemos montar volumes locais na compilação.

Uma solução alternativa é executar durante uma compilação um servidor http que exponha os arquivos locais e, em seguida, use curl/wget etc. para obter os arquivos na compilação do docker. Mas eu realmente gostaria que esses hacks fossem desnecessários.

Outro caso de uso .. Eu quero construir imagens docker para construir um sistema operacional proprietário que tem 10s de versões diferentes. A mídia de instalação é > 80 GB, portanto, não posso simplesmente copiar isso no ambiente de compilação do docker. Uma montagem de ligação seria muito mais preferível.

Outra: meu uso do projeto distribui Dockerfiles no repositório para compilar a partir de fontes no contêiner. Atualmente, extraímos outro clone do git no contêiner do github. Há clones rasos e tudo, mas ainda assim...

Então, acabei de testar [1] em um host de compilação rhel7, e a compilação da Red Hat do daemon docker tem a opção -v para compilação. Eu não testei no CentOS/Fedora, mas alguém poderia imaginar que o Fedora/CentOS provavelmente também tem. Vale a pena testar. Além disso, as assinaturas do RHEL Developer agora são gratuitas [2]:

@fatherlinux No Fedora, o `docker build -v' também está disponível.

@fatherlinux A versão do CentOS 7 o inclui.

+1 Acho que esse seria um recurso muito útil para adicionar ao docker oficial.

Acabei de atualizar no centos e no linuxmint (agora rodando 17.03.1-ce), estou faltando algo aqui? Não consigo ver a opção -v

Na hortelã

$ docker build --help

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --build-arg list             Set build-time variables (default [])
      --cache-from stringSlice     Images to consider as cache sources
      --cgroup-parent string       Optional parent cgroup for the container
      --compress                   Compress the build context using gzip
      --cpu-period int             Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust      Skip image verification (default true)
  -f, --file string                Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                   Always remove intermediate containers
      --help                       Print usage
      --isolation string           Container isolation technology
      --label list                 Set metadata for an image (default [])
  -m, --memory string              Memory limit
      --memory-swap string         Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string             Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                   Do not use cache when building the image
      --pull                       Always attempt to pull a newer version of the image
  -q, --quiet                      Suppress the build output and print image ID on success
      --rm                         Remove intermediate containers after a successful build (default true)
      --security-opt stringSlice   Security options
      --shm-size string            Size of /dev/shm, default value is 64MB
  -t, --tag list                   Name and optionally a tag in the 'name:tag' format (default [])
      --ulimit ulimit              Ulimit options (default [])
$ cat /etc/lsb-release 
DISTRIB_ID=LinuxMint
DISTRIB_RELEASE=18
DISTRIB_CODENAME=sarah
DISTRIB_DESCRIPTION="Linux Mint 18 Sarah"
$ docker version
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:45:26 2017
 OS/Arch:      linux/amd64

Server:
 Version:      17.03.1-ce
 API version:  1.27 (minimum version 1.12)
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Fri Mar 24 00:45:26 2017
 OS/Arch:      linux/amd64
 Experimental: false

No centos 7

# docker build --help

Usage:  docker build [OPTIONS] PATH | URL | -

Build an image from a Dockerfile

Options:
      --build-arg list             Set build-time variables (default [])
      --cache-from stringSlice     Images to consider as cache sources
      --cgroup-parent string       Optional parent cgroup for the container
      --compress                   Compress the build context using gzip
      --cpu-period int             Limit the CPU CFS (Completely Fair Scheduler) period
      --cpu-quota int              Limit the CPU CFS (Completely Fair Scheduler) quota
  -c, --cpu-shares int             CPU shares (relative weight)
      --cpuset-cpus string         CPUs in which to allow execution (0-3, 0,1)
      --cpuset-mems string         MEMs in which to allow execution (0-3, 0,1)
      --disable-content-trust      Skip image verification (default true)
  -f, --file string                Name of the Dockerfile (Default is 'PATH/Dockerfile')
      --force-rm                   Always remove intermediate containers
      --help                       Print usage
      --isolation string           Container isolation technology
      --label list                 Set metadata for an image (default [])
  -m, --memory string              Memory limit
      --memory-swap string         Swap limit equal to memory plus swap: '-1' to enable unlimited swap
      --network string             Set the networking mode for the RUN instructions during build (default "default")
      --no-cache                   Do not use cache when building the image
      --pull                       Always attempt to pull a newer version of the image
  -q, --quiet                      Suppress the build output and print image ID on success
      --rm                         Remove intermediate containers after a successful build (default true)
      --security-opt stringSlice   Security options
      --shm-size string            Size of /dev/shm, default value is 64MB
  -t, --tag list                   Name and optionally a tag in the 'name:tag' format (default [])
      --ulimit ulimit              Ulimit options (default [])
# docker version
Client:
 Version:      17.03.1-ce
 API version:  1.27
 Go version:   go1.7.5
 Git commit:   c6d412e
 Built:        Mon Mar 27 17:05:44 2017
 OS/Arch:      linux/amd64
# cat /etc/centos-release
CentOS Linux release 7.3.1611 (Core) 

@wilfriedroset No CentOS 7, os pacotes não oficiais do Docker fornecem a opção. Eu acho que faz parte do repositório EPEL.

obrigado @nathanjackson. Temos um ETA para este recurso na versão oficial?

@wilfriedroset AFAIK, NÃO HÁ ETA porque foi decidido (várias vezes) que esse recurso não DEVE estar no docker oficial para preservar a "portabilidade de compilação". também conhecido como permitir que seus Dockerfiles sejam executados em qualquer lugar, incluindo o serviço de compilação do Docker.

Na minha experiência, a portabilidade de construção limitada é o que os clientes realmente querem. Eles desejam configurar um ambiente/farm de compilação e garantem que as compilações sempre possam ser reconstruídas nesse ambiente. A opção -v build não impede isso de forma alguma.

Por exemplo, se você usar montagens NFS, apenas certifique-se de que todos os servidores de compilação tenham essa montagem em seus fstabs e a compilação será concluída sem problemas em qualquer lugar do farm.

No RHEL 7.3
````
[ root@rhel7 ~]# compilação do docker --help

Uso: docker build [OPÇÕES] PATH | URL | -

Construir uma imagem de um Dockerfile

Opções:
--build-arg value Definir variáveis ​​de tempo de compilação (padrão [])
--cgroup-parent string Cgroup pai opcional para o contêiner
--cpu-period int Limita o período de CPU CFS (Completely Fair Scheduler)
--cpu-quota int Limita a cota de CPU CFS (Completely Fair Scheduler)
-c, --cpu-shares int compartilhamentos de CPU (peso relativo)
--cpuset-cpus string CPUs para permitir a execução (0-3, 0,1)
--cpuset-mems string MEMs para permitir a execução (0-3, 0,1)
--disable-content-trust Ignorar verificação de imagem (padrão true)
-f, --file string Nome do Dockerfile (o padrão é 'PATH/Dockerfile')
--force-rm Sempre remova os recipientes intermediários
--help Uso de impressão
--isolation string Tecnologia de isolamento de contêiner
--label value Definir metadados para uma imagem (padrão [])
-m, --memory string Limite de memória
--memory-swap string Limite de troca igual a memória mais troca: '-1' para habilitar troca ilimitada
--no-cache Não usa cache ao construir a imagem
--pull Sempre tenta puxar uma versão mais recente da imagem
-q, --quiet Suprime a saída de compilação e imprime o ID da imagem em caso de sucesso
--rm Remove contêineres intermediários após uma compilação bem-sucedida (padrão true)
--shm-size string Tamanho de /dev/shm, o valor padrão é 64MB
-t, --tag value Nome e opcionalmente uma tag no formato ' name:tag ' (padrão [])
--ulimit valor Ulimit opções (padrão [])
-v, --volume value Definir montagens de ligação em tempo de construção (padrão [])
```

outro caso de uso em projetos de nó de construção de CI é compartilhar o cache yarn do CI ao construir todas as imagens.

+1 : instalar node_modules de novo e de novo é realmente terrível, especialmente para micro serviços nodejs
Estou tentando resolver esse problema com nfs , acho que "repetível" não é um bom motivo para não implementar esse recurso...

Parece que será ainda mais importante com #31257 e #32063 mesclados.

Dê uma olhada em #32507

@fatherlinux você poderia explicar como a portabilidade de compilação funciona quando você pode ter comandos COPY dentro do Dockerfile? Eu tenho um problema em que quero evitar o número de cópias de um arquivo grande (por motivos de complexidade de tempo) e estou procurando uma opção somente leitura em tempo de compilação para compartilhar o arquivo com o contêiner.

@arunmk @cpuguy83 exatamente. A ideia é que você realmente não queira COPIAR dados para o contêiner na compilação. Isso pode torná-lo muito grande. Queremos apenas os dados disponíveis no momento da compilação. Por cima, você pode fazer um -v bind mount na versão do Red Hat do docker daemon que permite que você tenha dados disponíveis, mas é somente leitura agora (queimou-me na semana passada).

Então, se você precisar hoje, confira o Fedora, CentOS ou RHEL e você pode montar em uma cópia somente leitura dos dados em tempo de compilação...

E, se você precisar de portabilidade em um farm de compilação, sugiro NFS ou algo assim....

Se você não se importa em copiá-lo, mas apenas em tê-lo na imagem final, você pode usar compilações de vários estágios para lidar com isso.

Um exemplo inventado:

FROM fatImage AS build
COPY bigData /data
RUN some_stoff /data

FROM tinyImage
COPY --from=build /data/result

Obrigado pelo esclarecimento @fatherlinux
@cpuguy83 obrigado pelo detalhe. Deixe-me adicionar mais detalhes ao meu problema que pode ser incomum: eu tenho um sistema de compilação que gera um arquivo de 3,3 GB. Isso é adicionado a um RPM que é construído dentro de um contêiner docker. Portanto, há duas cópias que são produzidas: uma do sistema de compilação para o contêiner do docker, uma do contêiner do docker para o RPM. Agora, não posso evitar a segunda cópia. Eu estava pensando em evitar a primeira cópia, mas parece que isso também não é possível, mesmo com as compilações de vários estágios.
Posso entender que, se o arquivo grande fosse usado repetidamente, a cópia em vários estágios reduziria o número de vezes que a cópia é executada para '1'. Eu usei uma vez e queria reduzir o número para '0'. Estou certo em entender que isso não será possível?

@arunmk Não importa o que terá que ser copiado para a instância de compilação do cliente.

@cpuguy83 obrigado pelo esclarecimento. Parece que eu tenho que assumir a sobrecarga por enquanto. Isso é ter atomicidade?

@fatherlinux

Eu tentei o que você disse, usando -v no RHEL7 para tentar montar um diretório somente leitura durante a compilação, mas recebo este erro:

Os volumes não têm suporte na compilação do docker. Por favor, use apenas montagens de ligação.

Isso funcionará apenas com o pacote docker do RHEL, não com o do Docker. O patch não foi aceito no upstream.

@fatherlinux

Eu tentei o que você disse, usando -v no RHEL7 para tentar montar um diretório somente leitura durante a compilação, mas recebo este erro:

Os volumes não têm suporte na compilação do docker. Por favor, use apenas montagens de ligação.

@fcntl

você precisa usar binds como o erro disse, você provavelmente usou -v /something em vez de /hostsomething:/containersomething

@thebigb e talvez outros, configuramos uma infraestrutura para poder usar o ccache durante as compilações do docker. nós o publicamos em https://github.com/WebHare/ccache-memcached-server se isso ajudar você, embora o ideal seja resolver esse problema provavelmente o tornaria obsoleto.

Eu estava prestes a adicionar, um caso de uso que eu realmente preciso disso é ccache. Eu gostaria de poder montar meu cache ccache durante uma compilação de imagem do docker - não há sentido em estar na própria imagem. @unilynx Vou dar uma olhada na sua solução alternativa - bom momento!

Juse outra voz.

Meu caso de uso: atualmente eu uso o comando MOUNT do rocker para compartilhar os diretórios /root/.cache e /var/cache/apk .

Por algum motivo, tenho acesso de rede muito (muito, muito) lento a pacotes apk e pacotes pip. Qualquer reconstrução tornará o processo incrivelmente demorado. Isso torna as coisas muito mais fáceis com este recurso MOUNT em tempo de construção.

@embray @roxma dê uma olhada em https://github.com/moby/moby/issues/32507 se isso resolver seu caso de uso; feedback bem-vindo

Com a introdução de compilações de vários estágios , acho que a necessidade de especificar uma montagem de volume para o cache local do Maven é crítica.

@gim913 Não é assim que você participa de nenhuma comunidade. Se você quiser contribuir, revise as propostas existentes vinculadas aqui para ver se alguma delas resolve seu caso de uso.

@ gim913 Neste estágio da integração do docker em várias distribuições, alterar ambientes (ou seja, descartar o docker completamente) parece muito mais perturbador do que alterar seu 'SO' (suponho que você queira mudar de uma distribuição Linux diferente para a versão RedHat que aparentemente inclui -v?)

Não seria mais fácil pegar a versão do docker da RedHat? Talvez alguém aqui possa indicar os patches/forks/commits relevantes para obter a opção '-v' na compilação.

@unilynx aqui vai

Eu estava olhando alguns exemplos que usaram wget e cheguei aqui... meu caso de uso é semelhante... eu quero descompactar um tarball grande e apenas executá-lo. Eu não quero sujar o arquivo docker com o tarball ou perder tempo fazendo um wget de um servidor web local. A montagem como você pode fazer com o docker compose parece uma coisa razoável de se fazer em tempo de compilação. Por favor, mescle a mudança de Puneeth se parecer ok :-)

Eu pré-compilo rodas python e quero instalá-las no contêiner sem copiá-las e criar uma camada que realmente não preciso, ou tenho que tentar de alguma forma esmagar. Dia 1 e já estou procurando rocker 😢 😢 😢

Isso seria fácil de adicionar e extremamente útil (ou um comando de montagem, veja rocker novamente). Quanto tempo é gasto (na comunidade) criando scripts em torno deste ou de recursos semelhantes ausentes?

@awbacker A compilação multi-stag resolve isso muito bem, onde você pode fazer algo como

FROM something AS my_wheels
RUN compile_all_the_things

FROM something
COPY --from my_wheels /wherever
RUN do_stuff_with_wheels

A primeira parte só é executada se algo mudar. O cache para ele também pode ser compartilhado entre outros builds/dockerfiles.
Isso torna toda a construção independente.

Há também uma proposta que permitiria RUN --mount onde a especificação de montagem diria para montar uma coisa do destino de compilação my_wheels em vez de copiá-la.

Como para @kenyee , isso pode montar algo do contexto de compilação, que em 17.07-experimental é enviado apenas de forma incremental conforme necessário.

@ cpuguy83 Isso não funciona na prática - pelo menos para compilações Gradle Java. Eu tenho uma imagem base do Docker que tem os arquivos Gradle Jar pré-armazenados em cache, mas a compilação Gradle de sua fonte é o que aciona o download de todas as suas dependências no cache.

@cpuguy83 multi-stage não permite remover rodas copiadas da imagem resultante, é o que @awbacker está falando. Assim, o conteúdo na pasta /wherever será armazenado em cache e o tamanho da imagem será aumentado.

@BryanHunt Então parte do seu processo de construção é baixar os deps? Com certeza o Gradle deve fornecer uma maneira de armazenar em cache sem passar e realmente construir?

@ cpuguy83 Sim, os deps são baixados como parte da compilação. Basicamente o mesmo que Maven. Para referência: https://github.com/gradle/gradle/issues/1049

havia um PR para montagens de compilação em algum lugar?

@graingert aqui

👍 para isso. Na Lunar Way, queremos fazer o processo completo "build -> test -> build production image" em uma única compilação do Docker para remover dependências de compilação e teste do servidor CI. Com compilações de vários estágios, podemos fazer isso, mas não podemos obter os resultados do teste do contêiner intermediário no processo de compilação. Portanto, temos que fazer isso em duas etapas agora - com um Dockerfile separado para construir a imagem de teste, executá-la e só prosseguir para a etapa de construção da imagem do produto, se os testes forem bem-sucedidos.

Uma opção -v na compilação do docker nos permitiria armazenar os resultados do teste em uma pasta montada no servidor CI e remover a necessidade do processo atual de duas etapas.

@tbflw Por padrão, a compilação do Docker não remove contêineres intermediários após uma compilação malsucedida. Portanto, se um teste falhar, você poderá obter os resultados do teste.

Por favor , também precisamos muito, muito desse recurso! Recorrer a outras ferramentas como rocker ou forking docker com patches ad-hoc é muito mais feio do que quebrar a noção evangélica de "portabilidade de compilação".

@BryanHunt @stepps @yngndrw outros também @awhitford
Uma maneira de armazenar em cache as dependências de compilação é fazer com que sua compilação funcione como o exemplo de compilação de vários estágios na documentação ou o Dockerfile onbuild do python .
Aqui está um exemplo que fiz que parece funcionar para o maven. Vou copiar aqui.

FROM maven
WORKDIR /usr/src/app
# /root/.m2 is a volume :(
ENV MAVEN_OPTS=-Dmaven.repo.local=../m2repo/
COPY pom.xml .
# v2.8 doesn't work :(
RUN mvn -B -e -C -T 1C org.apache.maven.plugins:maven-dependency-plugin:3.0.2:go-offline
COPY . .
RUN mvn -B -e -o -T 1C verify

FROM openjdk
COPY --from=0 /usr/src/app/target/*.jar ./

Ele precisa ser configurado para baixar as dependências antes de copiar o restante da base de código. Certifique-se também de que o local em que seus artefatos são armazenados não esteja em um VOLUME .

@sixcorners Isso não funciona para Gradle

@BryanHunt Este Dockerfile ou essa abordagem não funciona para o gradle? cpuguy83 perguntou se havia uma maneira de baixar dependências sem realmente executar uma compilação. Você vinculou a uma tarefa de resolução de dependências. Você não poderia simplesmente adicionar o arquivo build.gradle e executar essa tarefa?

@sixcorners Quando você tem muitos módulos, você precisa replicar sua estrutura de diretórios junto com os arquivos de construção e os arquivos de propriedades. Suponho que poderia ser feito, mas vejo isso como muito propenso a erros.

O multistage do @sixcorners é um truque interessante e eu o vi usado para diferentes gerenciadores de pacotes (por exemplo, npm, composer).

Há um problema, porém, sempre que a lista de dependências é alterada COPY pom.xml na imagem do estágio 0 faz com que a camada seja descartada e, portanto, todo o cache desaparece. Isso significava que sempre que um desenvolvedor alterasse alguma coisa no pom (um comentário, uma dependência de 1kBytes) todo o cache precisava ser baixado novamente.

Para máquinas de CI construindo a imagem e depois executando os testes com dependências que continuam mudando, ou seja, milhares e milhares de pacotes que precisam ser baixados novamente (de um proxy ou de upstrea) e tornam a reconstrução bastante lenta. Um cache baseado em arquivo local montado como um volume é muito mais rápido.

Isso também é um problema quando os desenvolvedores iteram a construção de uma imagem, especialmente se estiverem em conexões lentas. Embora seja possível configurar uma instância local do Nexus e http_proxy para ela, isso tem outros efeitos colaterais (como canalizar qualquer solicitação http via Nexus).

Multistage é uma boa solução, mas não é o ideal.

Uma solução que estamos prestes a tentar é construir uma imagem construindo nossas bibliotecas compartilhadas e mantendo o cache de dependência. Essa imagem se tornaria nossa imagem de compilação para nossos aplicativos. Não é o ideal, mas achamos que vale a pena tentar.

Há um problema, porém, sempre que a lista de dependências é alterada, COPY pom.xml na imagem do estágio 0 faz com que a camada seja descartada e, portanto, todo o cache desaparece. Isso significava que sempre que um desenvolvedor alterasse alguma coisa no pom (um comentário, uma dependência de 1kBytes) todo o cache precisava ser baixado novamente.

@hashar note que o recurso COPY --from não está limitado a estágios de construção; da referência Dockerfile :

Opcionalmente COPY aceita um sinalizador --from=<name|index> que pode ser usado para definir o local de origem para um estágio de compilação anterior (criado com FROM .. AS <name> ) que será usado em vez de um contexto de compilação enviado pelo usuário. O sinalizador também aceita um índice numérico atribuído a todos os estágios de construção anteriores iniciados com a instrução FROM . _ Caso um estágio de construção com um nome especificado não possa ser encontrado, uma imagem com o mesmo nome é tentada em seu lugar. _

Isso permite que você _construa_ uma imagem para suas dependências, marque-a e use-a para copiar suas dependências. Por exemplo:

FROM maven
WORKDIR /usr/src/app
# /root/.m2 is a volume :(
ENV MAVEN_OPTS=-Dmaven.repo.local=../m2repo/
COPY pom.xml .
# v2.8 doesn't work :(
RUN mvn -B -e -C -T 1C org.apache.maven.plugins:maven-dependency-plugin:3.0.2:go-offline
COPY . .
RUN mvn -B -e -o -T 1C verify
docker build -t dependencies:1.0.0 .

E especifique usando a imagem dependencies:1.0.0 para suas dependências;

FROM openjdk
COPY --from=dependencies:1.0.0 /usr/src/app/target/*.jar ./

Ou (apenas um exemplo bem básico para testar);

$ mkdir example && cd example
$ touch dep-one.jar dep-two.jar dep-three.jar

$ docker build -t dependencies:1.0.0 . -f -<<'EOF'
FROM scratch
COPY . /usr/src/app/target/
EOF

$ docker build -t myimage -<<'EOF'
FROM busybox
RUN mkdir /foo
COPY --from=dependencies:1.0.0 /usr/src/app/target/*.jar /foo/
RUN ls -la /foo/
EOF

Na saída da compilação, você verá:

Step 4/4 : RUN ls -la /foo/
 ---> Running in 012a8dbef91d
total 8
drwxr-xr-x    1 root     root          4096 Oct  7 13:27 .
drwxr-xr-x    1 root     root          4096 Oct  7 13:27 ..
-rw-r--r--    1 root     root             0 Oct  7 13:26 dep-one.jar
-rw-r--r--    1 root     root             0 Oct  7 13:26 dep-three.jar
-rw-r--r--    1 root     root             0 Oct  7 13:26 dep-two.jar
 ---> 71fc7f4b8802

Não sei se alguém mencionou esse caso de uso ainda (pesquisei brevemente na página), mas montar um soquete de autenticação SSH no contêiner de compilação facilitaria muito a utilização de dependências implantadas por meio de repositórios git privados. Haveria menos necessidade de clichê dentro do Dockerfile em relação à cópia de chaves em estágios de compilação não finais, etc.

buildkit tem suporte nativo para git
https://github.com/moby/buildkit

Resolvendo.
Crie um script bash (~/bin/docker-compose ou similar):

#!/bin/bash

trap 'kill $(jobs -p)' EXIT
socat TCP-LISTEN:56789,reuseaddr,fork UNIX-CLIENT:${SSH_AUTH_SOCK} &

/usr/bin/docker-compose $@

E no Dockerfile usando socat:

...
ENV SSH_AUTH_SOCK /tmp/auth.sock
...
  && apk add --no-cache socat openssh \
  && /bin/sh -c "socat -v UNIX-LISTEN:${SSH_AUTH_SOCK},unlink-early,mode=777,fork TCP:172.22.1.11:56789 &> /dev/null &" \
  && bundle install \
...
or any other ssh commands will works

Então corra docker-compose build

Para jogar outro caso de uso na pilha. Eu uso o Docker para Windows para gerar um sistema de arquivos para construir o sistema linux embutido em um contêiner e gostaria de compartilhar isso com outros contêineres durante a etapa de compilação. Eu interajo com esse contêiner alterando a configuração e a reconstrução etc., portanto, executar a compilação em um Dockerfile e usar compilações de vários estágios não é uma boa opção, pois perderia compilações incrementais. Eu quero armazenar em cache meus artefatos de compilação anteriores, pois leva cerca de 1,5 horas para fazer uma compilação limpa. Devido à maneira como o Windows lida com links simbólicos, não posso fazer minha compilação em um volume montado em host, então uso volumes nomeados. Idealmente, gostaria de compartilhar esses volumes nomeados nas etapas de construção de minhas outras imagens; como no momento eu tenho que criar um tar da saída da compilação (cerca de 4gb) e fazer uma cópia do docker para disponibilizá-la no host do Windows para compilações subsequentes.

No caso de python, quando pip install package ele e suas dependências são baixados para uma pasta de cache e instalados em pacotes de site.
Como boa prática, usamos pip --no-cache-dir install package para não armazenar lixo/cache na camada atual. Mas, para melhor prática, é desejável colocar a pasta de cache fora do contexto de compilação. então o tempo de construção -v ajudará.
alguns usuários acima mencionados usam COPY . /somewhere/in/container/ , está tudo bem para o aplicativo ou arquivos do usuário, mas não para o cache. porque COPY cria mais uma camada como sua própria e remover caches em camadas posteriores não será útil. outro efeito colateral ruim é se o cache mudou quando usamos COPY o contexto mudou e as camadas seguintes serão invalidadas e forçadas a reconstruir.

@wtayyeb Se você tiver o Dockerfile que executa pip install ... somente quando o arquivo de requisitos é alterado, o tempo de compilação -v não parece tão importante, pois os requisitos não mudam com a mesma frequência que os aplicativos durante a compilação.

@wtayyeb Você pode usar o Dockerfile de vários estágios para ter o cache e uma imagem enxuta. Ou seja, use uma imagem do instalador para instalar o python em algum diretório e, em seguida, para sua imagem final, use COPY --from para transferir apenas os arquivos python necessários sem nenhum artefato de instalação ou até mesmo o próprio pip.

@manishtomar , obrigado, sim e não! No caso limpo, todas as dependências são baixadas novamente e compiladas e convertidas em rodas e armazenadas em cache, depois instaladas no ambiente de destino. Então, se alguém colocar requisitos lá, é um trabalho de uma vez. Mas se uma pequena dependência for atualizada, todas as dependências devem ser baixadas novamente, reconstruídas e re-circuladas e armazenadas em cache para serem utilizáveis.
Ao usar um CI para construir e testar suas bibliotecas e seus aplicativos em uma matriz de vários trabalhos, multiplique o trabalho acima pelo número de trabalhos simultâneos em seu servidor CI e obterá um aumento de espera para mais de 3s e uma média de carga acima de 15 mesmo com SSDs. (esses números são reais para 2 compilações simultâneas e aplicativos com ~ 20 dependências) Acho que o pip cache está fazendo isso da maneira certa, evitando baixar novamente, reconstruir e rodar novamente os pacotes prontos. e sem bind -v perdemos tempo e recursos do servidor.

@ibukanov , obrigado. Estou usando o Dockerfile de vários estágios para criar meus pacotes de aplicativos e usá-los posteriormente. Ajudaria se eu tivesse apenas um Dockerfile e quisesse compilá-lo várias vezes, mas e se houver vários Dockerfiles e cada um for compilado em uma versão python (2.7,3.6 por enquanto) e também tiver várias extensões c que precisam ser construído para a imagem base selecionada? e o parágrafo acima?

@thaJeztah Sua sugestão é ótima e nos poupará algum tempo, porém no caso de caches de compilação realmente não queremos ter que copiar nada da outra imagem.
Por que não podemos acessar outra imagem sem copiá-la?

@thedrow meu exemplo foi com os recursos que estão lá atualmente; dê uma olhada na proposta RUN --mount (https://github.com/moby/moby/issues/32507), que pode ser mais adequada ao seu caso de uso

Lendo o tópico acima, vejo um grande número de pessoas tentando encontrar kludges para corrigir uma lacuna de funcionalidade básica no processo de compilação do docker. Não vejo argumentos convincentes da base da portabilidade sem necessariamente confundir montagens de host com montagens de imagem - argumentos que são francamente enganosos e preguiçosos.

Eu também sou um usuário de contêiner gentoo e fui redirecionado de https://github.com/moby/moby/issues/3156 , que é um caso de uso completamente válido para essa funcionalidade ausente.

Tudo o que eu realmente quero é a capacidade de montar o conteúdo de outra imagem em tempo de construção para que eu não inche minhas imagens.

@kbaegis parece uma correspondência exata com o recurso proposto em https://github.com/moby/moby/issues/32507

Certo. Esse só foi um P3 não implementado no backlog por um ano em vez de 3 anos.

Parece que https://github.com/projectatomic/buildah vai realmente superar a compilação do docker muito rapidamente aqui para essa funcionalidade básica. Acho que vou mudar meu pipeline quando isso acontecer.

@kbaegis o que você veio aqui para adicionar a esta discussão? Você descreveu um caso de uso que corresponde _exatamente_ a uma proposta diferente;

Tudo o que eu realmente quero é a capacidade de montar o conteúdo de outra imagem em tempo de construção para que eu não inche minhas imagens.

É de código aberto, as coisas não surgem magicamente.

O que estou querendo adicionar à discussão?

Sucintamente que estou saindo deste conjunto de ferramentas. Tenho certeza de que é uma informação valiosa para a equipe de desenvolvimento, pois tenho certeza de que não estou sozinho lá.

A velocidade glacial e a baixa prioridade para dar suporte a este caso de uso (e qualquer solução confiável que forneça essa funcionalidade) me forçou a outras ferramentas e estou abandonando esse pipeline de compilação devido à falta de funcionalidade.

Eu tenho um caso de uso (rehash, tenho certeza) para adicionar. #32507 pode se adequar melhor a isso.

Estou construindo uma imagem docker para alguns pipelines de bioinformática. Algumas das ferramentas exigem que alguns bancos de dados estejam presentes antes de sua compilação/instalação (por favor, não pergunte, não é meu código ). Esses bancos de dados pesam um adorável mínimo de 30 GB.

Durante o tempo de execução, certamente pretendo que esses bancos de dados sejam montados -v volumes. Infelizmente, não posso fazer isso durante o processo de compilação sem "cozinhá-los", resultando em uma imagem de tamanho bastante obscena.

@draeath dê uma olhada no https://github.com/grammarly/rocker . Ele já suporta uma linda instrução MOUNT.

@draeath também, confira o Buildah, ele suporta montagens por padrão porque é configurado mais como uma ferramenta de programação. Também suporta montagens com um Dockerfile:

https://github.com/projectatomic/buildah

Obrigado @fatherlinux e @lig - isso me ajudará a concluir minha tarefa. Eu ainda acho que não deveria ter que sair do projeto para fazer isso, e ainda adoraria ver isso e #32507 implementados ;)

Eu vim aqui por meio de algumas pesquisas no Google para solicitar o mesmo recurso, volumes no tempo de 'construção do docker', não no tempo de 'execução do docker'.

Temos um sistema embarcado que contém uma CPU. O fabricante fornece ferramentas para compor uma imagem do sistema e, em seguida, transfere a imagem para a CPU. Esta ferramenta é de terceiros para mim e não posso alterá-la. Também é improvável que o fabricante o altere a meu pedido.

Eu quero construir uma imagem docker que faça uma primeira passagem "criar a imagem do firmware" e, em seguida, ser capaz de gerar contêineres que apenas enviam a imagem do firmware para os PCBs recém-saídos da linha. Um Dockerfile pode se parecer com:
----------[ Corte aqui ]----------
FROM base-image como construtor
COPIAR src src
EXECUTAR build-src

DA imagem base como pisca-pisca
COPY --from=builder build-artifacts
EXECUTAR cpu-build-and-flash --build-only
----------[ Corte aqui ]----------
Infelizmente, a etapa cpu-build-and-flash requer acesso ao dispositivo de destino via barramento USB, mesmo que não envie a imagem do firmware para o dispositivo. Portanto, preciso pegar o '-v /dev/usb/bus:/dev/usb/bus' do comando 'docker run' e tê-lo na compilação.

É claro que isso não é possível no momento.

A solução alternativa com a qual estou indo em frente é criar manualmente uma imagem intermitente por 'contêiner docker confirmando' um contêiner para uma imagem. Eu prefiro apenas montar o barramento USB no momento da compilação.

Atualização para quem estiver interessado: recentemente reconstruí todo o meu pipe com sucesso com o buildah. Atualmente, tenho os dois pipelines de compilação em execução em paralelo e o pipeline oci/buildah está gerando imagens menores (removendo especificamente /usr/portage no meu caso, mascarando-o com outra montagem).

E finalmente esse recurso está aqui: https://github.com/docker/docker-py/issues/1498

Mas eu quero volumes RW para um cache de compilação

No sábado, 28 de abril de 2018, 17:29 Коренберг Марк, [email protected] escreveu:

E finalmente este recurso está aqui: docker/docker-py#1498
https://github.com/docker/docker-py/issues/1498


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/14080#issuecomment-385188262 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/AAZQTJodLCCzyDdPFtNiIUZ_z85YvLWbks5ttJjagaJpZM4FIdOc
.

Também gostaria de ver esse recurso (com recursos de gravação) para que um arquivo de resultados de teste de unidade possa ser exportado durante o processo de compilação de vários estágios em um pipeline de CI. Para manter o espírito de portabilidade de compilação, se a opção -v não fosse fornecida, o arquivo seria simplesmente gravado internamente dentro da imagem de teste nesse estágio.

O objetivo ideal é compilar uma vez, testar uma vez e ainda ter o arquivo de resultados entregue ao sistema host, mesmo no caso (e especialmente no caso) de que os testes falhem, interrompendo a compilação.

Sim por favor. Dia todo.

Não é totalmente relevante, mas estamos migrando uma parte de nossa infraestrutura de implantação e precisávamos de uma maneira de copiar arquivos de uma imagem após a compilação. O seguinte fez o truque:

docker build -t x .
ID=$(docker create x)
docker cp $ID:/package.deb .
docker rm $ID

Ele já deveria ter sido adicionado quando o arquivo docker multiestágio foi introduzido. Eventualmente, todos enfrentarão esse problema assim que começarem a executar testes de unidade como um estágio no arquivo docker de vários estágios, especialmente no caso de pipelines de construção de CI. Também estamos enfrentando esse problema em que temos que publicar relatórios de teste de unidade no VSTS. Já aplicando a solução alternativa que @hoffa mencionou. Mas afinal é uma solução alternativa e tornar as coisas complicadas.

Devemos criar um problema diferente para pessoas que desejam/precisam de volumes de tempo de compilação para um cache de compilação?

@ajbouh Sim, provavelmente em https://github.com/moby/buildkit/issues

Consulte https://github.com/moby/moby/issues/32507#issuecomment -391685221

Em quarta-feira, 23 de maio de 2018, 19:22 Akihiro Suda [email protected] escreveu:

@ajbouh https://github.com/ajbouh Sim, provavelmente em
https://github.com/moby/buildkit/issues


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/14080#issuecomment-391566368 ou silenciar
o segmento
https://github.com/notifications/unsubscribe-auth/AAAcnSqNoVc4j34ElECy53gIfPecQFKfks5t1hlkgaJpZM4FIdOc
.

Embora você não possa adicionar volumes em tempo de compilação, você pode adicionar hosts, então agora eu construo todas as minhas imagens docker com algo como --add-host yum-mirror:$MIRROR_IP que serve um espelho yum que minhas imagens de compilação detectam por meio de um wrapper ao redor hum. Útil quando meu projeto muda de dependências muitas vezes ao dia e estou offline ou com uma conexão ruim (parte do projeto envolve atualizar e limpar seus muitos deps).

Acho a resistência do Docker em resolver esse problema irritante.

O suporte experimental para buildkit foi recentemente mesclado, com isso vem com uma opção para RUN --mount=<opts> <command> .

link para @cpuguy83 nota: https://github.com/moby/buildkit/pull/442

@glensc @cpuguy83 Quando podemos esperar um lançamento para esse recurso mesclado?

+1

RUN --mount não tem suporte a volume, então coisas como https://github.com/avsm/docker-ssh-agent-forward permanecem impossíveis em tempo de compilação, qual é a solução para isso?

docker build --secret está finalmente disponível no Docker 18.09 https://medium.com/@tonistiigi/build -secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066

Podemos encerrar este assunto?

--secret não é utilizável para o caso de uso de cache, pelo que posso dizer.

@AkihiroSuda RUN --mount em geral parece algo possivelmente adequado como solução para esse problema.

Sim, suponho que RUN --mount=type=cache (para volume de cache) e --mount=type=secret com docker build --secret (para volume secreto) quase cobrem o problema.

@AkihiroSuda então, seria bom ver um exemplo de trabalho resolvendo o problema original

@AkihiroSuda Do artigo (https://medium.com/@tonistiigi/build-secrets-and-ssh-forwarding-in-docker-18-09-ae8161d066) eu vi 2 casos de uso de montagem durante a compilação: Secret and SSH

[Segredo]

docker build --secret id=mysite.key,src=path/to/mysite.key .
RUN --mount=type=secret,id=mysite.key,required <command-to-run>

[SSH]

RUN --mount=type=ssh git clone [email protected]:myorg/myproject.git myproject

Existem 2 outros casos de uso (que me lembro) que não são explicados como usar no artigo nem nesta edição:

1) [Cache] RUN --mount=type=cache
2) Volumes em geral (por exemplo, para montar certificados SSL, ou no caso de grandes volumes que devem ser usados ​​durante a compilação, mas não incluídos na imagem gerada, e assim por diante...)

Quando o caso de uso estiver montando o espaço de trabalho yarn antes de executar webpack

Você pode fazer tudo isso..

RUN --mount=type=cache,from=<some image>,source=<path in from image>,target=<target>

Você também pode substituir from=<some image> por from=<some build stage>

Aqui está um exemplo inventado:

# syntax=docker/dockerfile:1.0.0-experimental
FROM busybox as hello
RUN  echo hello > /hello.txt

FROM scratch
RUN --mount=type=cache,from=busybox,source=/bin,target=/bin --mount=type=cache,from=hello,source=/hello.txt,target=/tmp/hello.txt echo /tmp/hello.txt

Concordo com @AkihiroSuda , isso deve lidar com todos os casos ... mas, por favor, informe-nos se isso não acontecer.

@AkihiroSuda @cpuguy83 : Infelizmente, a implementação atual (buildkit no docker 18.09) tem problemas com registros privados. A partir de agora, esses novos recursos não podem ser usados ​​se você precisar buscar suas imagens por meio de um registro privado. Veja meus testes em https://github.com/moby/moby/issues/38303.

Eu acho que isso também seria usado para artefatos do Jenkins, então, por exemplo, se estou criando uma imagem do Docker e compilando algo dentro, quero obter alguns artefatos, como dizer junit pytest output

Isso seria muito útil. Eu realmente preferiria não precisar adicionar --experimental para suportar RUN --mount=type=cache /user/.cache/pip pip install (para economizar toneladas de largura de banda de índice de pacotes).

buildah bud ( buildah build-using-dockerfile ) tem uma opção --volume / -v :
https://github.com/containers/buildah/blob/master/docs/buildah-bud.md

buildah pode executar compilações como não root sem um soquete docker.

Porque os downloads de pacotes da rede são mais reproduzíveis?

Não é necessário adicionar "--experimental", apenas "DOCKER_BUILDKIT=1" no cliente.

Sim, as compilações de rede são mais reproduzíveis porque o contexto está todo no Dockerfile. Se você precisar montar o contexto do host para fazer a compilação funcionar, é uma experiência ruim.

Observe que você também pode montar uma imagem no arquivo build.

Sim, as compilações de rede são mais reproduzíveis porque o contexto está todo no Dockerfile.

Certamente ter RUN apt-get update no Dockerfile garante que você tenha todas as etapas necessárias para construir a imagem. No entanto, não é reproduzível, pois o contexto adicional é baixado de terceiros. A única diferença com uma montagem é que todos os contextos externos são realmente definidos no Dockerfile.

Se você precisar montar o contexto do host para fazer a compilação funcionar, é uma experiência ruim.

Minha experiência ruim com a compilação do Docker é que nunca é reproduzível e definitivamente poderíamos nos beneficiar da montagem de um cache do host que, sem dúvida, aceleraria alguns casos de uso.

O que eu acabo fazendo eventualmente é ter uma construção de vários estágios. Uma imagem que obtém o contexto da rede, que atua como um instantâneo do contexto remoto. Em seguida, marque isso com alguma versão arbitrária, a data funciona bem. Por exemplo:

RUN apt-get update

docker build -t aptupdate-20190417

E na imagem real:

FROM aptupdate-20190417
FROM somebaseimage

COPY --from=aptupdate-20190417 /var/apt /var/apt

Repita com outro contexto remoto e você terá mais ou menos algo que é reproduzível.

Ou resumindo: um Dockerfile que depende de acesso à rede provavelmente não é reproduzível. Uma montagem pode torná-lo não reproduzível, mas ajudaria a tornar alguns casos de uso reproduzíveis. Mas acho que o ponto que o Dockerfile deve ter todas as etapas necessárias para realmente construir a imagem, embora na minha experiência a maioria escreva suas próprias ferramentas para instrumentar imagens de construção.

Quero dizer, RUN --mount=type=cache é exatamente para isso.
Ou você pode até montar a partir de outra imagem de um registro e ela será buscada.

Seus comandos apt podem ser reproduzidos (relativamente) fixando o que você deseja buscar.
Mas se você realmente deseja controlar todos os bits, por que está usando o apt em sua compilação? Armazenar isso em um host de compilação não é reproduzível e quebra facilmente de host para host.
Mantê-lo em um registro não é ruim, a não ser o potencial de falha de rede... o que é obviamente uma crítica justa.

-v docker build buildah e no fork do redhat foi explicitamente rejeitado aqui porque é muito amplo... .
Enquanto isso, o motivo pelo qual o RH o adicionou (ou mais precisamente porque eles decidiram trabalhar nele) foi poder montar as credenciais do RHEL no ambiente de compilação.

Sim, as compilações de rede são mais reproduzíveis porque o contexto está todo no Dockerfile. Se você precisar montar o contexto do host para fazer a compilação funcionar, é uma experiência ruim.

Eu discordo veementemente. A rede pode estar inativa ou comprometida; nesse caso, um cache local evita que toda a compilação falhe enquanto a Internet estiver inativa.

Eu poderia especificar volumes: uma vez no meu docker-compose.yml; mas precisa fazer DOCKER_BUILDKIT=1 e adicionar RUN --mount=type=cache em Dockerfiles gerenciados upstream? Por quê?

Com compilações de CI, estamos falando de uma quantidade não trivial de downloads desnecessários de dezenas a milhares de pacotes (dezenas ou centenas de vezes por dia) que podem ser armazenados em cache em uma montagem de volume (em uma compilação que é executada como não-raiz sem o capacidade de executar contêineres privilegiados com seus próprios volumes no host).

Os índices de pacotes são, em muitos casos, generosamente apoiados por doações. Desperdiçar esse dinheiro em largura de banda para satisfazer uma falsa ideia de reprodutibilidade baseada em uma falsa crença de que recursos remotos são um cache mais reproduzível de componentes de construção é terrivelmente frustrante.

Por favor, apenas adicione --volume para que meu docker-compose.yml funcione.

Por favor, apenas adicione --volume para que meu docker-compose.yml funcione.

Fazer o seu "docker-compose" funcionar é o contrário.
consumidores docker-compose este projeto, e não o contrário.

docker-compose interage com o socket docker. O docker-compose YAML é uma maneira consolidada de armazenar opções de contêiner (que podem ser convertidas em defs de pod k8s (que o podman suporta, até certo ponto)). Como devo especificar DOCKER_BUILDKIT=1 de forma reproduzível? Eu poderia especificar build_volumes: de forma reproduzível em um docker-compose.yml.

Quando eu -- no meu script de construção de CI que é executado n vezes por dia -- construo uma imagem, por exemplo, chamando docker-compose build (por exemplo, com ansible) ou packer (em vez de buildah e podman), eu tem alguns objetivos:

  • Economize recursos / Não desperdice recursos

    • Não baixe novamente o SO e os pacotes por idioma constantemente.

    • Salve os recursos de largura de banda da minha organização no índice de pacotes.

  • Garantir a disponibilidade

    • Deve / deve funcionar offline

    • Deve depender de quantos componentes forem necessários

  • Garanta a integridade da construção

    • Ser capaz de recriar a mesma imagem com os mesmos parâmetros

    • Isolar a variação / entregar compilações reproduzíveis

    • Não controlamos recursos remotos como índices de pacotes.

    • Não controlamos o caminho da rede



      • DNSSEC e DNS sobre HTTPS provavelmente não foram implementados corretamente



    • Podemos ser banidos e bastante limitados

    • Devemos usar somas de verificação assinadas para verificar recursos assinados



      • A autorização para acessar e assinar com chaves é delegada em algum lugar


      • As variáveis ​​ENVironment estão disponíveis para todos os processos no namespace do contêiner


      • As montagens de volume em tempo de compilação são uma maneira de compartilhar chaves necessárias apenas em tempo de compilação (sem vazá-las no cache de imagem)



  • Mantenha as compilações rápidas

    • Cache e memorizar operações frequentes.

    • Os caches adicionam pontos de falha, variação potencial e irreprodutibilidade de risco.



      • Cache de proxy HTTP(S!)


      • Cache de camada de aplicativo na rede


      • Cache do sistema de arquivos local



    • Implemente caches burros e laváveis ​​sem dependências externas



      • Cache do sistema de arquivos local



Se eu precisar liberar o volume do cache, posso liberar o volume do cache.

0. Status quo

RUN pip install app && rm -rf /root/.cache
  • Possível hoje
  • O(n_builds): uso de largura de banda
  • Não funcionará offline: Depende da rede
  • Reconstruções mais lentas

A. Cópias

COPY . /app/src/app
COPY .cache/pip /app/.cache/pip
RUN pip install /app/src/app \
    && rm -rf /app/.cache/pip
  • Possível hoje
  • ~O(1) largura de banda do índice do pacote
  • O(n): Em cada compilação (* ONBUILD )

    • Copia o cache

    • Desarquiva pacotes

    • Exclui o cache

  • Funciona off-line
  • Reconstruções mais lentas

B. Fork e modifique cada Dockerfile do upstream para adicionar RUN --mount=type=cache e definir uma variável de ambiente

# Fork by copying to modify every pip install line
RUN --mount=type=cache /app/.cache/pip pip install /app/src/pip
$ DOCKER_BUILDKIT=1 docker build . [...]
  • Possível hoje
  • Isso já introduz a irreprodutibilidade: há um parâmetro extra-Dockerfile, extra-docker-compose.yml que introduz variação na saída: a imagem construída nomeada.
  • Documentos: como liberar o cache --mount=type=cache (?)
  • ~O(1) largura de banda do índice do pacote
  • Funciona off-line
  • Reconstruções rápidas

C. Especifique um volume que é montado no momento da compilação

C.1. construir
$ buildah bud -v .cache/pip:/app/.cache.pip
  • Possível hoje
  • Também introduz a irreprodutibilidade
  • Documentos: como liberar o cache
  • ~O(1) largura de banda do índice do pacote
  • Funciona off-line
  • Reconstruções rápidas
C.2. docker (o que este problema está pedindo)
C.2.1 CLI da janela de encaixe
$ docker build -v .cache/pip:/app/.cache.pip
  • Não é possível hoje
  • Também introduz a irreprodutibilidade
  • Documentos: como liberar o cache
  • ~O(1) largura de banda do índice do pacote
  • Funcionaria off-line
  • Reconstruções rápidas
C.2.2 composição da janela de encaixe
services:
  app:
    image: imgname:latest
    build: .
    build_volumes:  # "build_volumes" ?
    - ./.cache/pip:/app/.cache/pip
$ docker-compose build
  • Não é possível hoje
  • Também introduz a irreprodutibilidade
  • Documentos: como liberar o cache
  • Exigiria uma revisão do esquema docker-compose
  • ~O(1) largura de banda do índice do pacote
  • Funcionaria off-line
  • Reconstruções rápidas

...

  • CÓPIA || REMOTE_FETCH || leitura()

    • Quais deles são mais reproduzíveis?

:point_up: Apenas um lembrete. Você pode fixar um arquivo baixado verificando sua soma de verificação. Alguns gerenciadores de pacotes, como o pip, também suportam isso.

@westturner Obrigado pela explicação detalhada.

Eu acho que o seguinte seria semelhante ao seu caso B, mas você poderia limpar o cache e acabaria como o seu caso C2 (o que você está pedindo, eu acho):

_docker-compose.yml:_

services:
  my-cache:
    build: ./my-cache
    image: local/my-cache

  my-image:
    build: ./my-image

_my-cache/Dockerfile:_

FROM python

RUN pip install app

_minha-imagem/arquivo Docker:_

FROM my-repo/my-image

RUN --mount=target=/export,type=bind,from=local/my-cache

RUN pip install /app/src/app

(https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md#run---mounttypecache)

Você pode construir a imagem de cache com:

docker-compose build my-cache

O comando RUN --mount=target=/export,type=bind,from=local/my-cache deve ser vinculado à imagem. Se você quiser atualizar o cache, poderá remover e reconstruir a imagem do cache.

Se isso ainda usa o cache em RUN --mount... você pode usar um arquivo .env com uma versão, inclua a versão em image: local/my-cache:$MY_VERSION e from=local/my-cache:$MY_VERSION (deve ser incluído como um argumento de construção).

Você pode incluir o serviço my-cache em outro arquivo docker-compose se não quiser que ele esteja no mesmo arquivo que seus serviços principais.

Você ainda precisaria usar DOCKER_BUILDKIT=1 (como no seu caso B, mas acho que isso não será necessário em versões futuras) e ainda não seria reproduzível (mas seu caso C2 também não).

Qual seria a penalidade que você vê se não for reproduzível? Se você colocar a imagem de cache local/my-cache no docker hub (com um nome de repositório diferente) ou em um registro privado e usar versões para cada compilação (que criará um cache diferente), com a mesma versão sempre a mesma cache, não o tornaria reproduzível ? Você nem precisaria incluir o serviço no arquivo docker-compose e chamar o comando build. (O Docker Hub deve ser acessado da rede, mas é o mesmo para suas outras imagens, suponho, e depois de baixar uma vez, não deve mais ser necessário, a menos que você gere uma nova versão com um novo cache)

IMPORTANTE: Eu não testei o código acima.

@Yajo O suporte à soma de verificação no pip foi originalmente implementado em 'peep' e depois mesclado no pip. Você pode adicionar hashes bons conhecidos como fragmentos de URL nas entradas do arquivo de requisitos do pip. (Há financiamento para melhorias de segurança no projeto PyPA este ano; o suporte do TUF (The Update Framework; assim como o Docker Notary) no PyPI está planejado para o final deste ano.) Inicializando corretamente pip e PyPI (com chaves e confiança) em imagens docker provavelmente será um tópico ainda este ano.
(editar; um pouco OT, mas para os interessados) https://discuss.python.org/t/pypi-security-work-multifactor-auth-progress-help-needed/1042/

@lucasbasquerotto Obrigado pela ajuda. Isso é significativamente mais complicado do que apenas especificar --volume no momento da compilação. Ou seja, parece exigir:

  • Especificando DOCKER_BUILDKIT=1 no shell shell docker build
  • Modificando qualquer/toda instrução RUN upstream do Dockerfile com (edit) RUN --mount=type=cache e args
  • Acesso de leitura/gravação em outra imagem? Mutabilidade! Ou o cache está congelado com versões provavelmente obsoletas?

Se eu puder COPIAR arquivos do host ou especificar parâmetros de tempo de compilação que não estão armazenados em outro lugar, não vejo como montar um volume em tempo de compilação é menos reproduzível?

CÓPIA || REMOTE_FETCH || leitura()

  • Quais deles são mais reproduzíveis?

@westturner

Especificando DOCKER_BUILDKIT=1 no ambiente do shell de compilação do docker

Se você usa docker-compose , como eu vi em seus outros posts, e se você está executando a partir de um container, como:

$ sudo curl -L --fail https://github.com/docker/compose/releases/download/1.24.0/run.sh -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

Então você pode editar o arquivo baixado em /usr/local/bin/docker-compose para usar essa variável env. Alterar de:

exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES -w "$(pwd)" $IMAGE "$@"

para

DOCKER_BUILDKIT=1
exec docker run --rm $DOCKER_RUN_OPTIONS $DOCKER_ADDR $COMPOSE_OPTIONS $VOLUMES -w "$(pwd)" --env DOCKER_BUILDKIT=$DOCKER_BUILDKIT $IMAGE "$@"

Esta é uma mudança muito fácil e transparente para quem executa o comando.

_(Se você não executar como um contêiner, o acima não se aplica)_

Modificando qualquer/toda instrução RUN upstream do Dockerfile com RUN --cache e args

No caso que expus, seria RUN --mount=type=bind... , mas de qualquer forma, ter que alterar o Dockerfile também é ruim IMO. Uma opção -v seria realmente muito melhor e mais transparente .

Acesso de leitura/gravação em outra imagem? Mutabilidade! Ou o cache está congelado com versões provavelmente obsoletas?

Quando você vincula a imagem, ela provavelmente cria um contêiner (ou qualquer que seja o nome, com um sistema de arquivos replicado), e as alterações feitas lá durante a construção não devem alterar a imagem original (não faria sentido). Portanto, se você compilar usando uma imagem de cache chamada my-repo/my-cache:my-version em uma compilação, na próxima compilação seria exatamente a mesma (imutabilidade). Se você quiser usar um cache mais atualizado, você pode criar uma nova imagem com uma nova versão e usá-la, como my-repo/my-cache:my-new-version .

Quais deles são mais reproduzíveis?

Considero reprodutível como algo que seria exatamente igual mesmo se você rodasse em outra máquina. Nesse sentido, se você enviar uma imagem para um registro docker (seguro e confiável) e nunca alterar essa imagem, eu a consideraria reproduzível (se você tiver dúvidas sobre a conexão com a Internet, poderá usar um registro privado e acessá-lo dentro de um VPN ou algo parecido (nunca usei um registro privado)).

Se o comando COPY estiver copiando o cache da sua máquina, não considero reproduzível porque se você executar pip install (ou apt-get , ou o que for) em outra máquina, em outro momento, você pode garantir que o conteúdo do cache será o mesmo? Talvez isso possa ser uma preocupação para você. Talvez não.

Por outro lado, se você possui arquivos que possui em algum lugar confiável que você "possui" (como um bucket do S3), baixe esses arquivos em sua máquina e copie esses arquivos com o comando COPY, então você pode reproduzi-los de outro máquina com os mesmos resultados (assumindo que os arquivos não foram alterados e a outra máquina é idêntica à anterior). Então, eu consideraria isso como sendo reproduzível. Depende de onde esses arquivos estão vindo e quanto controle você tem sobre eles.

Verdade seja dita, não considero nada 100% reprodutível em todos os casos (afinal, hardware pode falhar), mas quanto mais confiável, melhor. Quando me refiro a algum processo ser reproduzível, estou me referindo principalmente ao seu conteúdo e resultado serem os mesmos, e isso incluiria algo baixado da rede, supondo que o conteúdo não mude com o tempo (desconsidero a possibilidade de rede falha neste caso).

Há algum tipo de bug de rede do Docker que torna go mod download não confiável dentro de um contêiner também (pelo menos para aplicativos do nosso tamanho), então apenas executá-lo toda vez para baixar todos os meus GOPATH/pkg/mod novamente é não apenas um desperdício, mas quebrado. 🤷‍♀

Eu poderia evitar muitas cópias desnecessárias de arquivos se pudesse usar --volume !

@kevincantu RUN --mount=type=cache deve cobrir seu caso de uso

Isso requer pelo menos um download bem-sucedido de módulos de dentro de uma compilação do docker e, neste caso específico, ainda não vi isso ..

https://github.com/moby/moby/issues/14080#issuecomment -484314314 por @westurner é uma visão geral muito boa, mas não consegui fazer buildkit funcionar:

$ sudo docker -v
Docker version 19.03.1, build 74b1e89

$ sudo DOCKER_BUILDKIT=1 docker build .
Ä+Ü Building 0.1s (2/2) FINISHED                                                                                                                
 => ÄinternalÜ load build definition from Dockerfile                                                                                       0.0s
 => => transferring dockerfile: 407B                                                                                                       0.0s
 => ÄinternalÜ load .dockerignore                                                                                                          0.0s
 => => transferring context: 2B                                                                                                            0.0s
failed to create LLB definition: Dockerfile parse error line 8: Unknown flag: mount

Meu Dockerfile começa com # syntax=docker/dockerfile:experimental .

Eu realmente gostaria de usá-lo via docker-compose . Tentei ENV DOCKER_BUILDKIT 1 no Dockerfile e também passei de docker-compose.yml via ARG DOCKER_BUILDKIT mas é tudo a mesma coisa:

$ sudo docker-compose up --build
Building web
ERROR: Dockerfile parse error line 10: Unknown flag: mount

@lucasbasquerotto Como o que você propôs em https://github.com/moby/moby/issues/14080#issuecomment -484639378 seria traduzido para uma versão instalada do docker-compose?

Finalmente, nem tenho certeza se isso cobriria meu caso de uso, talvez alguns de vocês possam me dizer se devo prosseguir com isso. Eu quero usar um cache de tempo de compilação para desenvolvimento local que sobrevive entre as compilações para que, ao atualizar as dependências, apenas as novas tenham que ser baixadas. Então, eu adicionaria RUN --mount=type=cache,target=/deps ao Dockerfile e definiria o cache do gerenciador de dependências para /deps .

para docker compose veja https://github.com/docker/compose/pull/6865 , que estará em um próximo release candidate do compose

Eu tenho outro caso de uso... Eu quero construir containers para arm em um host x86_64 com binfmt configurado. Isso requer que eu tenha o emulador de cpu qemu estático específico da arquitetura em /usr/bin .

Minha solução atual é adicionar qemu-arm-static ao contêiner como arquivo como:

FROM arm32v7/alpine:3.10
COPY qemu-arm-static /usr/bin/qemu-arm-static
RUN apk update && apk upgrade
RUN apk add alpine-sdk cmake
...

A solução mais fácil seria montar meu arquivo apenas se necessário dentro do contêiner como:
docker build -v /usr/bin/qemu-arm-static:/usr/bin/qemu-arm-static -t test:arm32v7 .
Isso funciona muito bem para a execução do docker, mas sinto falta dessa funcionalidade para a construção de contêineres.

Existe outra solução como eu posso construir um contêiner de braço em hosts x86_64 ou podemos permitir volumes em tempo de construção para pelo menos este caso?

Os kernels mais recentes do @jneuhauser permitem que esses binários sejam carregados estaticamente, portanto, não há necessidade de configurá-los sempre. Você pode conseguir isso, por exemplo, executando a imagem linuxkit/binfmt no modo privilegiado uma vez após a inicialização.

os kernels mais recentes permitem que esses binários sejam carregados estaticamente, portanto, não há necessidade de configurá-los sempre.

@alehaa Você ainda não precisa do binário estático do emulador qemu dentro do contêiner?

@cybe Isso não é mais necessário, se o F -flag for usado (que é o que o pacote linuxkit/binfmt faz). Você pode encontrar mais informações sobre isso aqui .

Alguém poderia fornecer uma configuração de trabalho para experimentar o buildkit? Não consigo fazer funcionar no Ubuntu. Minha configuração é a seguinte:

cat /etc/docker/daemon.json

{
  "experimental": true
}

Dockerfile

# syntax=docker/dockerfile:experimental

FROM ruby:2.6.3

RUN --mount=type=cache,target=/bundle/vendor

sudo docker -v

Versão do Docker 19.03.1, compilação 74b1e89

DOCKER_BUILDKIT=1 sudo docker build .

Resposta de erro do daemon: linha de erro de análise do Dockerfile 12: sinalizador desconhecido: montagem

sudo não carrega env vars com ele, a menos que você diga com sudo -E ou declare a variável dentro do sudo.

Escrevi algumas palavras sobre esse recurso e criei alguns exemplos mínimos mostrando como armazenar em cache

Editado: veja abaixo

@cpuguy83 obrigado!

@thisismydesign desculpe estragar sua empolgação, mas você não pode --cache node_modules , ele não estará presente na imagem final, então seu aplicativo está quebrado.

@glensc Porra, você está certo .. existe uma maneira de tornar um cache de tempo de construção parte da imagem final?

Honestamente, pensei que isso seria considerado para um recurso anunciado como

permite que o contêiner de compilação armazene em cache diretórios para compiladores e gerenciadores de pacotes.

Você deve conseguir mapear ~/.npm em vez disso… https://docs.npmjs.com/files/folders.html#cache

@thisismydesign

Você pode usar outra imagem como cache, construindo-a em seu Dockerfile ou uma imagem literal armazenada em um registro em algum lugar e use COPY --from

FROM example/my_node_modules:latest AS node_modules

FROM nodejs AS build
COPY --from=/node_modules node_modules 
...

Este é apenas um exemplo, você pode usar isso para muitas coisas diferentes.

Ugh, eu odeio trazer isso à tona e me envolver aqui (também oi amigos)

mas temos um caso de uso para isso.


Existe um bom lugar onde eu possa me envolver ou uma chamada ou lista que eu possa participar para obter um resumo aqui?

Além disso, se precisarmos de alguém para colocar alguns recursos nisso, tenho 1 kris nova e uma pequena equipe que provavelmente posso persuadir a olhar para isso.

TLDR Posso codificar isso, por favor? Tem alguém com quem eu possa falar sobre isso?

_TLDR_ Posso codificar isso, por favor? Tem alguém com quem eu possa falar sobre isso?

Não posso falar pelo Docker, mas minha impressão é que eles não estão abertos para adicionar montagem de volume às compilações (e que provavelmente devem fechar esse problema)

Muitos dos casos de uso para buildtime -v agora são cobertos pelo buildkit. Pelo menos para mim resolveu.

Vou verificar o buildkit então - eu também tenho alguns hacky bash que fazem o trabalho se alguém estiver interessado.

obrigado @unilynx

+1 para @unilynx ao encerrar este problema, o buildkit resolveu os problemas de volume de tempo de compilação para mim também.

Aposto que se alguém soltasse alguns links e um exemplo, poderíamos convencer nossos amigos a pressionar o botão brilhante de fechar.


(Eu também me beneficiaria deles)

O caso de uso de cache não está resolvido para mim e muitos outros, pois os volumes de tempo de compilação com buildkit não estão presentes na imagem final.

Assim, consegui extrair todos os meus artefatos de construção do volume temporário usado em build e reconstruir a imagem novamente com o cache anterior usando este bash que mencionei acima.

Consegui reconstruir minha imagem em cima de si mesma, de modo que o sistema de arquivos de sobreposição pegasse apenas um pequeno delta.

Consegui até reutilizar o volume para outras imagens em tempo de compilação.


outras pessoas não são capazes de fazer isso?

(cache) montagens estão no front-end "experimental"; descrito em https://github.com/moby/buildkit/blob/master/frontend/dockerfile/docs/experimental.md (prestes a entrar em uma reunião, mas posso vincular exemplos mais estendidos)

obrigado @thaJeztah LMK se eu puder ajudar aqui de alguma forma :)

https://github.com/moby/moby/issues/14080#issuecomment -547662701

@thisismydesign desculpe estragar sua empolgação, mas você não pode --cache node_modules , ele não estará presente na imagem final, então seu aplicativo está quebrado.

@thaJeztah Não acredito que o problema acima esteja resolvido. Adoraria dar uma olhada em alguns exemplos onde é possível armazenar em cache, por exemplo npm install durante o tempo de compilação que também permitirá que a imagem resultante use a instalação em cache.

@kris-nova Eu não resolvi esse problema, mas, novamente, não estou procurando usar scripts bash. Talvez precisemos de um novo problema, mas esse é um caso de uso bastante comum em que o AFAIK ainda não foi resolvido.

@thaJeztah Aqui estão alguns exemplos usando montagens de cache mostrando como a imagem final não conterá a montagem e não abrange muitos casos de uso de cache em tempo de compilação:

Para npm: não se usaria as montagens de cache para o diretório de cache npm (consulte https://docs.npmjs.com/cli-commands/cache.html, geralmente ~/.npm )?

@ankon Isso pode funcionar, obrigado, vou tentar. Outro caso de uso sobre o qual não tenho certeza é o Bundler e o Ruby.

Então eu acho (ainda não testei) para o Bundler você pode pelo menos se livrar da dependência de rede usando um volume de compilação em $BUNDLE_PATH e depois durante a compilação

bundle install
bundle package
bundle install --standalone --local

Isso basicamente significa que você tem um diretório de instalação do pacote em cache, de lá você empacota gems em ./vendor/cache e reinstala em ./bundle . Mas isso não poupa o tempo de instalação e construção de gems, pode realmente tornar a etapa de construção mais longa.

Se você quiser salvar os dados armazenados em cache na imagem, copie-os na imagem do cache.

Obrigado, no entanto, ainda é mais uma solução alternativa porque

  • você tem que fazer uma cópia adicional
  • Suponho que você precise ter diretórios diferentes entre os ambientes de compilação e execução (você não pode usar o diretório onde montou um volume durante a compilação, certo?)

Não sei quanto esforço seria simplesmente ter uma opção nativa para montar o mesmo volume na imagem final, mas tenho certeza de que facilitaria o uso. Estes são apenas 2 exemplos de linguagens de script onde a maneira de usar esse cache não era óbvia para mim. Eu posso certamente imaginar que isso surgirá em diferentes contextos também.

@thisismydesign Parece que o que você quer é poder compartilhar um cache entre a compilação e a execução?

buildkit é uma solução apenas para linux, o que fazemos no Windows?

@thisismydesign Não sei por que você espera que uma montagem (cache) permaneça na imagem final. Eu não esperaria isso e não quero ter ~ 1 gb na minha imagem apenas por usar a montagem do cache de download.

buildkit é uma solução apenas para linux, o que fazemos no Windows?

Você pode usar o buildkit no Windows.

https://docs.docker.com/develop/develop-images/build_enhancements/

Você pode achar mais fácil definir a configuração do daemon por meio da interface do usuário do Docker para Windows em vez de definir a variável de ambiente antes de executar.

@nigelgbanks no topo do seu link:

Only supported for building Linux containers

Oh desculpe, eu apenas suponho que você estava construindo contêineres Linux no Windows.

@thisismydesign Parece que o que você quer é poder compartilhar um cache entre a compilação e a execução?

Isso resolveria meu caso de uso em torno do cache, sim.

Tornar isso mais fácil pode economizar milhões de downloads de pacotes em CI
constrói por ano.

Algum serviço de CI oferece suporte a recursos de buildkit experimentais ?

Em sáb, 13 de junho de 2020, 14h08, Csaba Apagyi [email protected] escreveu:

@thisismydesign https://github.com/thisismydesign Parece que
você quer é poder compartilhar um cache entre construir e executar?

Isso resolveria meu caso de uso em torno do cache, sim.


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/14080#issuecomment-643657987 ou
Cancelar subscrição
https://github.com/notifications/unsubscribe-auth/AAAMNS6IEQDCO5F3LNHJK5TRWO6AJANCNFSM4BJB2OOA
.

Algum serviço de CI oferece suporte a recursos de buildkit experimentais ?

Eles têm que apoiá-lo explicitamente? Estou usando o gitlab-ci com buildkit e simplesmente funciona. Afinal, é apenas uma maneira diferente de invocar 'docker build'.

Claro, a menos que você traga seus próprios runners para o gitlab, as chances de obter um cache durante a compilação são baixas de qualquer maneira.

Copiar de um estágio nomeado de uma compilação de vários estágios é outra solução

FROM golang:1.7.3 AS builder
COPY --from=builder

Mas a localidade da imagem do contêiner ainda é um problema sem solução para o agendamento de trabalhos de CI

Os executores precisariam ser mais aderentes e compartilhar imagens (intermediárias) em um sistema de arquivos comum para minimizar solicitações desnecessárias para repositórios de pacotes (perenemente subfinanciados).

Acabei de tentar buildkit , mas melhora apenas marginalmente meu fluxo de trabalho, que seria 100% ajudado pelo volume "real" ou montagens de ligação ao host.

Estou usando docker build para compilar versões antigas de glibc que devem fazer parte de novos contêineres de compilação fornecendo esses glibc s para compilar e vincular.

Agora o download repetido da fonte glibc é resolvido por uma montagem de ligação (de buildkit ), o arquivo pode ser somente leitura, sem problemas. Mas não tenho como acessar o diretório de compilação para análise após compilações com falha, pois o contêiner bombeia por erro. (Se eu reiniciá-lo para acessá-lo, ele reinicia a compilação, então isso não ajuda).

Além disso, não consigo ver por que eu deveria estar pulando em aros como construir um novo contêiner a partir de um antigo apenas para me livrar do meu diretório de compilação, onde se o diretório de compilação tivesse sido uma montagem em primeiro lugar, teria sido tão fácil. (Basta fazer make install após a compilação e eu tenho um contêiner limpo sem diretório de compilação e sem as fontes baixadas).

Então eu ainda acredito que esta é uma solicitação de recurso muito válida e facilitaria muito nossas vidas. Só porque um recurso pode ser abusado e pode quebrar outras funcionalidades se usado, não significa que deve ser evitado implementá-lo a todo custo. Basta considerá-lo um uso extra para uma ferramenta mais poderosa.

Mas não tenho como acessar o diretório de compilação para análise após compilações com falha

Parece uma solicitação de recurso para buildkit. Esta é definitivamente uma peça que faltava conhecida.

Pode-se fazer isso hoje tendo um alvo para buscar o "diretório de compilação". Você apenas executaria isso após uma execução com falha, tudo ainda deve ser armazenado em cache, só precisa da última etapa para obter os dados.
Entenda que isso é um pouco de solução alternativa, no entanto.

Além disso, não consigo ver por que deveria estar pulando em aros, como construir um novo contêiner a partir de um antigo apenas para me livrar do meu diretório de compilação

Você pode explicar mais o que você está querendo/esperando aqui?

Você pode explicar mais o que você está querendo/esperando aqui?

Nesse caso é só querer matar 2 coelhos com 1 cajadada:

  • tem uma maneira fácil de acessar resultados intermediários do host (aqui "construir análise de diretório")
  • certifique-se de que esse espaço de armazenamento não esteja poluindo a imagem recém-criada

Como isso, e todos os outros casos em que o contêiner de compilação (assim como a "construção do contêiner") precisa tornar a construção o mais simples possível, seria resolvido de maneira muito mais elegante apenas fornecendo a funcionalidade -v , eu tenho um dificuldade em entender a resistência para fornecer esse recurso. Além da funcionalidade "cache-aware" que buildkit aparentemente oferece, só posso vê-la como uma maneira complicada e complicada de alcançar exatamente essa funcionalidade, e apenas parcialmente. (E em muitos casos onde o cache é o objetivo principal, ele também seria resolvido por -v , ao custo de ter que bloquear o volume montado em um contêiner específico enquanto ele roda, mas o cache com buildkit tem as mesmas restrições.)

Você pode explicar mais o que você está querendo/esperando aqui?

Estou usando um processo de compilação de vários estágios, onde o próprio ambiente de compilação é conteinerizado e o resultado final é uma imagem contendo apenas o aplicativo e o ambiente de tempo de execução (sem as ferramentas de compilação).

O que eu gostaria é de alguma maneira para o contêiner de compilação do Docker provisório gerar arquivos de resultados de teste de unidade e cobertura de código para o sistema host nos eventos de uma compilação bem-sucedida e uma compilação com falha, sem ter que passá-los para a imagem de saída da compilação para extração (porque todo o processo de compilação é curto-circuitado se os testes de unidade não passarem na etapa anterior, portanto, não haverá uma imagem de saída nessa situação, e é aí que mais precisamos dos resultados do teste de unidade) . Imagino que se um volume de host puder ser montado no processo de compilação do Docker, os comandos de teste internos poderão direcionar sua saída para a pasta montada.

@mcattle
De fato, muito semelhante também a (uma das funcionalidades) que preciso.
Desde que mudei para buildah alguns dias atrás, consegui todas as funções que precisava e muito mais. Depurar meu contêiner de compilação teria sido totalmente impossível sem a possibilidade de inserir de forma flexível o contêiner de saída e os links para o host. Agora sou um campista feliz. (Sinto muito por atrapalhar a festa com um "concorrente", eu removeria com prazer este comentário se ofender, mas foi uma solução tão eficaz para os casos de uso apresentados neste tópico que achei que deveria mencioná-lo) .

Não há ofensa em dizer que outra ferramenta atende melhor às suas necessidades.

Se algo funciona para você, isso é maravilhoso.

As deficiências do construtor v1 no Docker e do construtor buildkit são muito bem compreendidas nesse contexto e estão procurando como resolvê-las, de preferência sem precisar recorrer a montagens de vinculação do cliente.
GitHub [email protected] escreveu:
“@mcattle
De fato, muito semelhante também a (uma das funcionalidades) que preciso.
Desde que me mudei para o buildah há alguns dias, consegui todas as funções que precisava e muito mais. Depurar meu contêiner de compilação teria sido totalmente impossível sem a possibilidade de inserir de forma flexível o contêiner de saída e os links para o host. Agora sou um campista feliz. (Sinto muito por atrapalhar a festa com um "concorrente", eu removeria com prazer este comentário se ofender, mas foi uma solução tão eficaz para os casos de uso apresentados neste tópico que achei que deveria mencioná-lo) .”


Você está recebendo isso porque foi mencionado.
Responda a este e-mail diretamente, visualize-o no GitHub ou cancele a inscrição.

sem ter que recorrer a montagens de ligação do cliente.

Aqui explico por que uma opção de tempo de construção -v não está recorrendo ou sacrificando a reprodutibilidade mais do que dependendo dos recursos de rede no momento da construção.

https://github.com/moby/moby/issues/14080#issuecomment -484314314 :

CÓPIA || REMOTE_FETCH || leitura()

  • Quais deles são mais reproduzíveis?

Eu estou indo com buildah para tempo de construção -v (e cgroupsv2) também.

@mcattle eu tive o mesmo requisito. Eu resolvi isso com rotulagem .

Eu estou indo com buildah para tempo de construção -v (e cgroupsv2) também.

Estou pensando seriamente em mudar do Ubuntu (que tem apenas docker) para o Fedora (que substituiu o docker por podman/buildah) em nosso servidor de compilação por causa do suporte "-v".

Por falar nisso. O Podman também suporta o modo sem raiz e, até agora, parecia totalmente compatível com o Docker (exceto pelas diferenças no impacto --user/USER e no cache de imagem, que vêm do uso do modo sem raiz em vez de executar como root como o daemon do Docker).

PS. enquanto o cgroups v2 é necessário para operação sem root, o suporte para isso é mais sobre o tempo de execução do contêiner do que o docker. Se você usar CRun em vez de RunC (como o Fedora faz), você terá suporte ao cgroups v2. O RunC tem algum suporte v2 e sem root no Git, mas tive alguns problemas ao testá-lo no Fedora (31) alguns meses atrás.

EDIT: O Ubuntu tem podman/buildah/etc no Groovy, mas não no último 20.04 LTS, acho que foi importado do Debian instável. Não foi portado para LTS, pelo menos ainda não. Considerando que está no Fedora desde 2018, eu acho.

@eero-t talvez você possa descrever seu caso de uso e o que está faltando nas opções que o BuildKit fornece atualmente que não é abordada para eles.

Esta página foi útil?
0 / 5 - 0 avaliações