Moby: Solicitação de novo recurso: Desative seletivamente o cache para comandos RUN específicos no Dockerfile

Criado em 24 set. 2013  ·  245Comentários  ·  Fonte: moby/moby

ramificando a discussão de # 1384:

Eu entendo que -no-cache desabilitará o cache de todo o Dockerfile. Mas seria útil se eu pudesse desabilitar o cache para um comando RUN específico? Por exemplo, atualizar repositórios ou baixar um arquivo remoto ... etc. Do meu conhecimento, EXECUTAR agora o apt-get update se em cache não atualizaria o repositório? Isso fará com que os resultados sejam diferentes de uma VM?

Se desabilitar o armazenamento em cache para comandos específicos no Dockerfile for possível, os comandos subsequentes no arquivo não usarão o cache? Ou eles fariam algo um pouco mais inteligente - por exemplo, usar o cache se o comando anterior produzisse os mesmos resultados (camada fs) quando comparado a uma execução anterior?

arebuilder kinfeature

Comentários muito úteis

E sobre CACHE ON e CACHE OFF no Dockerfile? Cada instrução afetaria os comandos subsequentes.

Todos 245 comentários

Acho que a maneira de combater isso é pegar o ponto no Dockerfile que você deseja armazenar em cache e marcá-lo como uma imagem para usar no seu futuro FROM do Dockerfile, que pode então ser construído com -no-cache sem consequências, pois a imagem base não seria reconstruída.

Mas isso não limitaria a intercalação de comandos armazenados em cache e não armazenados em cache com facilidade?

Por exemplo, digamos que eu queira atualizar meus arquivos repo e wget de um servidor e realizar várias etapas entre - por exemplo, instalar o software do repo (que pode ter sido atualizado) - realizar operações no arquivo baixado (que pode ter mudado em o servidor) etc.

O que seria ideal é uma maneira de especificar o docker no Dockerfile para executar comandos específicos sem cache todas as vezes e a única reutilização da imagem anterior se não houver alteração (por exemplo, sem atualização no repo).

Não seria útil ter?

E sobre CACHE ON e CACHE OFF no Dockerfile? Cada instrução afetaria os comandos subsequentes.

Sim, estou usando comandos git clone no meu Dockerfile e se eu quiser clonar novamente com atualizações, preciso, tipo, adicionar um comentário no final da linha para acionar uma reconstrução a partir disso linha. Não devo precisar criar um novo contêiner de base para esta etapa.

Um ID de contêiner pode ser passado para 'docker build' como uma instrução "não armazenar em cache após este ID"? Semelhante à maneira como o 'docker build' armazena em cache todas as etapas até uma linha alterada em um Dockerfile?

Concordo que precisamos de um controle mais poderoso e refinado sobre o cache de compilação. Atualmente, não tenho certeza de como expor isso ao usuário.

Acho que isso ficará mais fácil com as próximas extensões de API, especificamente nomenclatura e introspecção.

Seria um ótimo recurso. Atualmente estou usando coisas bobas como RUN a=a some-command , então RUN a=b some-command para quebrar o cache

Obter melhor controle sobre o cache tornaria o uso do docker do CI muito mais feliz.

@shykes

Que tal mudar --no-cache de um bool para uma string e fazer com que seja usado um regex para onde no docker queremos estourar o cache?

docker build --no-cache "apt-get install" .

Eu concordo e sugeri exatamente esse recurso no IRC.

Exceto que eu acho que para preservar a compatibilidade reversa, devemos criar um novo sinalizador (digamos "--uncache") para que possamos manter --cached como um sinalizador bool (obsoleto) que resolve para "--uncache. *"

Na sexta-feira, 7 de fevereiro de 2014 às 9h17, Michael Crosby [email protected]
escreveu:

@shykes
Que tal mudar --no-cache de um bool para uma string e fazer com que seja usado um regex para onde no docker queremos estourar o cache?

docker build --no-cache "apt-get install" .

Responda a este e-mail diretamente ou visualize-o no GitHub:
https://github.com/dotcloud/docker/issues/1996#issuecomment -34474686

O que todo mundo pensa sobre isso? Alguém quer implementar o recurso?

Estou pronto para tentar implementar isso hoje, se ninguém mais começou?

Comecei a trabalhar nisso - queria validar se a abordagem parece boa.

  • O campo noCache de buildfile torna-se um *regexp.Regexp .

    • Um nil significa o que utilizeCache = true .

  • Passar uma string para docker build --no-cache agora envia uma string regex válida para o servidor.
  • Apenas chamar --no-cache resulta em um padrão de .*
  • O regex é então usado em um novo método buildfile.utilizeCache(cmd []string) bool para verificar os comandos que ignoram o cache

Uma coisa: pelo que posso ver, o pacote flag / mflag não suporta sinalizadores de string sem um valor, então vou precisar fazer alguns ajustes extras para oferecer suporte a --no-cache e --no-cache some-regex

Eu realmente acho que esta deveria ser uma nova bandeira separada. O comportamento e a sintaxe de --no-cache já estão bem definidos e usados ​​em muitos e muitos lugares por muitas pessoas diferentes. Eu votaria em --break-cache ou algo semelhante e faria --no-cache fazer exatamente o que faz hoje (já que esse é um comportamento muito útil que muitas pessoas confiam e ainda desejam).

De qualquer forma, IANTM (eu não sou o mantenedor), então esses são apenas meus pensamentos pessoais. :)

@tianon --no-cache é atualmente bool, então isso simplesmente estende o comportamento existente.

  • docker build --no-cache - mesmo comportamento de antes: ignora o cache
  • docker build --no-cache someRegex - ignora quaisquer RUN ou ADD comandos que correspondam a someRegex

Certo, está tudo bem. O problema é que --no-cache é um bool, então o comportamento existente é na verdade:

  • --no-cache=true - desabilitar explicitamente o cache
  • --no-cache=false - habilitar explicitamente o cache
  • --no-cache - abreviação para --no-cache=true

Eu também acho que estaríamos prestando um desserviço a nós mesmos ao criar strings regex especiais com letras maiúsculas e minúsculas "true" e "false" para resolver isso, já que isso criará um comportamento potencialmente surpreendente para nossos usuários no futuro. ("Quando eu uso --no-cache com uma regex de 'verdadeiro' ou 'falso', não funciona como deveria!")

@tianon sim, você está certo. Deu uma olhada rápida e as pessoas estão usando = true / false.

Feliz em modificar o PR para adicionar uma nova bandeira como você sugere, o que os mantenedores acham ( @crosbymichael , @shykes)? Isso também significaria que eu poderia remover o código adicionado ao mflag para permitir sinalizadores de string / bool.

+1 para abordagem @wagerlabs

@crosbymichael , @timruffles Não seria melhor se o autor do Dockerfile decidisse qual etapa de compilação deve ser armazenada em cache e qual não? A pessoa que cria o Dockerfile não é necessariamente a mesma que constrói a imagem. Mover a decisão para o comando docker build exige conhecimento detalhado da pessoa que deseja apenas usar um Dockerfile específico.

Considere um ambiente corporativo onde alguém deseja apenas reconstruir uma hierarquia de imagens existente para atualizar algumas dependências. A árvore Dockerfile existente pode ter sido criada anos atrás por outra pessoa.

+1 para abordagem @wagerlabs

+1 para a abordagem @wagerlabs , embora fosse ainda melhor se houvesse uma maneira de

CACHE [interval | OFF]
RUN apt-get update
CACHE ON

Agradeço que isso possa ir contra a ideia de contêineres não determinísticos; no entanto, é exatamente o tipo de coisa que você deseja fazer em um cenário de implantação contínua em que seu pipeline tem bons testes automatizados.

Como solução alternativa, estou atualmente gerando inibidores de cache no script que uso para executar a compilação do docker e adicionando-os ao dockerfile para forçar uma falha do cache

FROM ubuntu:13.10
ADD ./files/cachebusters/per-day /root/cachebuster
...
ADD ./files/cachebusters/per-build /root/cachebuster
RUN git clone [email protected]:cressie176/my-project.git /root/my-project

Estou procurando usar contêineres para integração contínua e a capacidade de definir tempos limite em elementos específicos no cache seria realmente valioso. Sem isso, não posso implantar. Forçar uma reconstrução completa sempre é muito lento.

Meu plano atual para contornar isso é injetar dinamicamente comandos como RUN echo 2014-04-17-00:15:00 com a linha gerada arredondada para os últimos 15 minutos para invalidar os elementos do cache quando o número arredondado aumentar. ala a cada 15 minutos. Isso funciona para mim porque tenho um script gerando o dockerfile todas as vezes, mas não funcionará sem esse script.

1 para o recurso.

Eu também quero votar neste recurso. O cache é irritante ao construir partes de um contêiner a partir de repositórios git que são atualizados apenas no branch master.
: +1:

@hiroprotagonist Ter um git pull em seu ENTRYPOINT pode ajudar?

@amarnus Eu resolvi de forma semelhante à ideia que @tfoote teve. Estou executando a compilação de um trabalho jenkins e em vez de executar o comando docker build diretamente, o trabalho inicia um skript de compilação que gera o Dockerfile a partir de um modelo e adiciona a linha 'RUN echo currentsMillies' acima dos comandos git. Graças ao sed e aos pipes, isso foi uma questão de minutos. De qualquer forma, ainda sou a favor desse recurso como parte do próprio Dockerfile.

Adicionando meu +1 para abordagem @wagerlabs . Também tendo esse problema com o CI. Estou simplesmente usando uma instrução RUN de eco dinâmico por enquanto, mas adoraria esse recurso.

+1 para CACHE ON / OFF. Meu caso de uso também é automação de CI.

+1, especialmente a capacidade de definir um intervalo de cache de comandos de execução como no exemplo de @cressie176

"Por exemplo, atualizando repositórios ou baixando um arquivo remoto"

+1

Se isso ajudar alguém, aqui está o trecho de código que estou usando na minha construção do Jenkins:

echo "Using build $BUILD_NUMBER for docker cachebusting"
sed -i s/cachebust_[0-9]*/cachebust_"$BUILD_NUMBER"/g Dockerfile

+1 para CACHE ON / OFF

Como uma possível alternativa para a abordagem CACHE ON / OFF, que tal uma palavra-chave extra como "SEMPRE". A palavra-chave seria usada em combinação com um comando existente (por exemplo, "SEMPRE EXECUTAR" ou "SEMPRE ADICIONE"). Por design, a palavra-chave "SEMPRE" não vai para o cache para concluir o comando adjacente. Porém, compara o resultado com o CACHE (implicitamente o cache para outras vezes que a mesma linha foi executada), vinculando à imagem em cache se o resultado do comando ALWAYS não for alterado.

Acredito que a necessidade subjacente é identificar "instruções não idempotentes" . O comando ALWAYS faz isso muito explicitamente. Minha impressão é que a abordagem CACHE ON / OFF poderia funcionar igualmente bem, mas também poderia exigir muitos blocos de troca de código (o que pode encorajar os usuários a bloquear mais linhas do que realmente necessário).

Eu também sou mais um prefixo para comandos, como ALWAYS ou CACHE 1 WEEK ADD ...

Então, eu estava lutando com esse problema por um tempo e só queria compartilhar meu trabalho, caso seja útil enquanto isso é resolvido. Eu realmente não queria adicionar nada fora do arquivo docker para a invocação de compilação ou alterar o arquivo todas as vezes. De qualquer forma, este é um exemplo bobo, mas usa o mecanismo de adição para invadir o cache e não requer nenhuma manipulação de arquivo.

From ubuntu:14.04

RUN apt-get -yqq update
RUN apt-get -yqq install git
RUN git clone https://github.com/coreos/fleet
ADD http://www.random.org/strings/?num=10&len=8&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new uuid
RUN cd fleet && git pull

Obviamente, você pode escolher seu próprio caso de uso e geração aleatória de rede. De qualquer forma, talvez ajude algumas pessoas.

Outro +1 para a abordagem @wagerlabs

Outro +1 para o recurso. Enquanto isso, usando a solução alternativa @cruisibesarescondev .

mais um +1 para a solicitação de recurso. E obrigado a @cruisibesarescondev pela solução alternativa

Outro +1 para o recurso.

Felicidades, @cruisibesarescondev pela solução alternativa.

Acho que a palavra-chave ALWAYS é uma boa abordagem, especialmente porque tem uma semântica clara e simples. Uma abordagem um pouco mais complicada seria adicionar um tempo mínimo (útil em coisas como uma buildfarm ou integração contínua). Para isso, eu proporia uma sintaxe "EVERY XXX" em que XXX é um tempo limite. E se já passou mais de XXX desde que o cache desse comando foi construído, ele deve executar o comando novamente. E verifique se a saída mudou. Se não houver alteração, reutilize o resultado armazenado em cache, observando a hora da última atualização. Isso significaria que EVERY 0 seria o mesmo que SEMPRE.

Para uma solução alternativa no momento, eu gerei meus Dockerfiles usando modelos empy em python e incorporo os seguintes snippets que funcionam como acima, exceto que não detecta o mesmo resultado em duas execuções sucessivas, mas força um retrigger a cada XXX segundos. No topo:

@{
import time
def cache_buster(seconds):
    ts = time.time()
    return ts - ts % seconds
}@

Onde eu quero forçar uma nova execução:

RUN echo @(cache_buster(60))

Que se parece com isso no Dockerfile

RUN echo 1407705360.0

Como você pode ver, ele é arredondado para os 60 segundos mais próximos, portanto, a cada 60 segundos passados, a próxima execução executará novamente todos os comandos seguintes.

1 para SEMPRE sintaxe. +.5 para CACHE ON / CACHE OFF.

1 para SEMPRE sintaxe.

Sim, SEMPRE a sintaxe parece muito intuitiva.

Não gosto de CACHE ON / OFF porque acho que as linhas devem ser "autocontidas" e adicionar blocos a Dockerfiles apresentaria muitos "problemas" (como ter que verificar "esta linha está coberta pelo cache?" Ao mesclar. .).

@kuon Acho que já existem vários comandos que afetam as instruções subsequentes, por exemplo, USER e WORKDIR

Sim, é verdade, mas não os uso pelo mesmo motivo. Eu sempre faço RUN cd ... && ou RUN su -c ...&& .

Eu prefiro uma notação de bloco:

CACHE OFF {
    RUN ...
}

Isso é mais explícito e evita que uma linha CACHE OFF inserida por engano (isso provocaria um erro de sintaxe).

Posso estar pensando demais, os Dockerfiles não são realmente executados na produção (apenas durante a construção da imagem), portanto, ter o cache desativado durante a construção não causará muito dano. Mas também acho que os Dockerfiles são realmente limitantes (ter que encadear todos os comandos com um && em um único RUN para evitar a criação de um zilhão de imagens, não sendo capaz de usar variáveis ​​...).

Talvez esse problema seja a oportunidade para um novo formato do Dockerfile.

Eu gostaria de voltar ao que acabei de dizer. Eu li o que @shykes disse em outra edição https://github.com/docker/docker/pull/2266 e também concordo com ele (o Dockerfile precisa ser um assembly realmente simples como a linguagem).

Eu disse que gostaria de variáveis ​​ou coisas assim, mas isso pode ser coberto por alguma outra linguagem, mas, neste caso, cada linha em um Dockerfile deve ser autocontida, por exemplo:

NOIMAGE ALWAYS RUN USER:jon  apt-get update

Que sempre executaria o comando (sem cache), mas também não criaria uma imagem e usaria o usuário jon.

Esse tipo de linha independente é muito mais fácil de gerar a partir de qualquer outro idioma. Se você tiver que se preocupar com o contexto (usuário, cache, diretório de trabalho), ele está mais sujeito a erros.

Pode ser RUN! para facilitar, por favor?

Alguma atualização de status sobre este?

Desativar seletivamente o cache seria muito útil. Eu pego arquivos de um repositório amazon s3 remoto por meio do comando awscli (do kit de ferramentas amazon AWS) e não tenho uma maneira fácil de invadir o cache por meio de um comando ADD (pelo menos não consigo pensar em uma maneira sem editar o Dockerfile para acioná-lo). Acredito que haja um caso forte para o controle ser devolvido ao usuário para eliminar seletivamente o cache ao usar RUN. Se alguém tiver alguma sugestão para mim, ficarei feliz em ouvir de você.

Queria melhorar um pouco esse problema, pois é algo de que temos uma grande necessidade.

Ainda convencido de que ALWAYS sintaxe é a ideal.

Que tal uma simples declaração BREAK .

@ cpuguy83 isso funcionaria também para meu caso de uso específico.

Não tenho certeza se é tecnicamente possível ter apenas um comando não armazenado em cache, mas o restante deles. Provavelmente não, já que o docker é baseado em diferenças incrementais.

Ter suporte para BREAK entretanto, me daria paridade de recursos com minha solução alternativa atual com base na sugestão de @CheRuisiBesares.

Em relação ao meu post anterior, seria realmente suficiente apenas estourar o cache daquele ponto no script em diante, o resto seria apenas devido ao design de script inteligente (e eu acredito que isso atenderia aos requisitos da maioria das pessoas). Isso é possível em vez de desativar seletivamente o bloqueio de cache?

@orrery Você provavelmente poderia "estourar" o cache adicionando COPY _antes_ dessa etapa de compilação. Se os arquivos copiados forem diferentes, todas as etapas posteriores não devem mais usar o cache (consulte esta seção ). Truque sujo, mas pode resolver seu caso.

Uma chave para ALWAYS (ou conceitos semelhantes como EVERY # DAYS ) é a comparação do cache após o comando anexado. Para mim (e suponho que muitos outros), o objetivo não é invadir o cache por si só.

  • O objetivo é garantir que paremos de usar o cache se e quando o resultado do comando (ou seja, "atualizar para a versão mais recente") mudar.
  • Por outro lado, se o resultado corresponder a uma versão em cache, queremos aproveitar as vantagens do cache.

Isso aborda o comentário de @hellais, já que você pode tirar vantagem do cache para comandos subsequentes ... se e somente se a saída de ALWAYS corresponder a uma versão em cache (isso pode facilmente ser na maioria das vezes).

Naturalmente, a mesma lógica _pode_ ser incluída em um modelo CACHE ON / OFF. A comparação com o cache provavelmente será mais barata do que executar novamente todos os comandos subsequentes, mas ainda pode ser cara. Se um bloco CACHE ON / OFF encorajou um usuário a incluir comandos extras em um bloco OFF (algo que não pode acontecer com ALWAYS ), isso pode contribuir para diferenças significativas no desempenho.

Estou exatamente na mesma situação que @tfoote : estou usando o Docker para CI e preciso forçar a expiração do cache.

+1 para a sintaxe EVERY . A sintaxe ALWAYS também faria o trabalho.

@claytondaley, esse é um ótimo ponto. No entanto, ainda é importante ter a capacidade de desabilitar completamente o cache de um comando. Sempre haverá um estado oculto que é inerentemente invisível para o Docker. Por exemplo, a execução do comando pode mudar de estado em um servidor remoto.

@mkoval , você trouxe um bom ponto sobre _criar _ estados ocultos como um momento importante para usar ALWAYS , mas não acho que isso afete minha lógica em torno da retomada do cache. Para tornar o exemplo concreto (se algo trivial), um comando que atualiza um sistema de terceiros:

  • Cria um estado oculto (precisa ser executado ALWAYS ) e
  • Não muda o contêiner atual

Se o próximo comando não envolver um estado oculto (trivialmente, um comando mv no contêiner), o cache será 100% confiável. Mesmo contêiner, mesmo comando, sem dependência de informações ocultas.

Se o próximo comando (ou qualquer comando subsequente) envolver informações ocultas, ele deve usar a palavra-chave ALWAYS , apenas retomando o cache se o contêiner resultante corresponder ao cache.

@claytondaley sua solução me parece muito elegante e eficiente. Eu ficaria muito grato se isso fosse implementado. : +1:: polvo:

1 para este recurso usando SEMPRE e CADA X sintaxe sugerida. CACHE ON / OFF parece um pouco desajeitado para mim, mas eu usaria. Também gosto muito da sugestão de

1 para SEMPRE sintaxe. especialmente para códigos pull do repositório git.

+1 Para qualquer uma dessas soluções.

Estou um pouco confuso. Como o cache pode ser reativado depois de desativado? Depois de desativá-lo e fazer qualquer tipo de alteração no contêiner, reativar o cache basicamente descartaria quaisquer alterações feitas por esses comandos do Dockerfile executados enquanto o cache estava desativado? Achei que a razão pela qual poderíamos fazer o cache era porque sabíamos exatamente a lista completa dos comandos anteriores que foram executados e poderíamos garantir que o que estava no contêiner era exatamente o mesmo. Se você desligar o cache (e estou falando sobre o lado da pesquisa), isso não vai acabar com essa garantia? Ou se trata apenas de não preencher o cache?

Meu entendimento das sugestões é que você pode especificar "SEMPRE" como parte de um comando do Dockerfile para sempre executar a etapa novamente. Por exemplo, "EXECUTAR SEMPRE git clone https://example.com/myrepo.git " sempre será executado (assim, sempre clonando o repo). Então, o que @claytondaley está sugerindo é que, depois que esse comando for executado novamente, o Docker verificará as alterações no cache. Se a soma de verificação for a mesma (ou seja, se o repositório clonado não teve alterações, então a camada mais recente é idêntica à mesma camada no cache), podemos continuar com o cache ativado. Você está certo que, uma vez que o cache é invalidado, todas as etapas posteriores não podem usar o cache. Essas sugestões apenas permitem mais granularidade de controle sobre quando usar o cache e também são inteligentes ao retomar do cache sempre que possível.

@curtiszimmerman ... exatamente

@duglin ... A ideia pode ser mais óbvia se usarmos um proxy matemático. Cache (neste contexto) é apenas a memória do resultado de action B quando aplicado a state A portanto, você não precisa reprocessá-lo. Suponha que eu execute uma sequência de comandos:

  • comece com 6
  • SEMPRE execute * x onde o valor de x é baixado de um repositório git (e, portanto, pode mudar)
  • execute + 12

Na primeira vez que executo o comando, x é 8, então obtenho (e coloco em cache) a seguinte sequência:

  • 6
  • 48 (como resultado de * x aplicado a 6 )
  • 60 (como resultado de + 12 aplicado a 48 )

Se minha máquina atingir o estado 48 novamente (por qualquer sequência) ... e receber o comando + 12 , não tenho que fazer o processamento novamente. Meu cache sabe que o resultado desse comando é 60 .

A parte difícil é descobrir quando você está no mesmo estado ( 48 ) novamente.

  • Poderíamos teoricamente comparar a máquina após cada comando com todas as outras imagens em cache, mas isso consome muitos recursos e tem poucas chances de encontrar uma correspondência.
  • Minha proposta é manter as coisas simples. Cada vez que estamos em um estado (por exemplo, 6 ) e pressionamos um comando (por exemplo, * x ), comparamos o resultado com o cache da última vez (ou vezes) que estivemos no mesmo estado executando o mesmo comando. Se o estado da máquina após esse processo for o mesmo (por exemplo, ainda 48 ), retomamos o cache. Se o próximo comando ainda for + 12 , extraímos o resultado do cache em vez de processá-lo.

@claytondaley mas não entendo como você determina o estado atual. Como você disse, não estamos comparando todos os arquivos do contêiner. A maneira como o cache funciona agora é basicamente apenas strcmp o próximo comando que queremos executar em todos os contêineres filhos conhecidos do contêiner atual. No minuto em que você pula um contêiner no fluxo, não vejo como você pode assumir que seu contêiner atual é como qualquer outro contêiner em cache sem verificar todos os arquivos no sistema de arquivos. Mas talvez eu não groco o que você está fazendo.

Deixe-me reformulá-lo .... dado um contêiner aleatório (que é basicamente o que você tem se não estiver usando o cache), como você pode encontrar um contêiner no cache que corresponda a ele sem diferenciar todos os arquivos no recipiente?

@claytondaley @duglin Determinar se uma operação "sem cache" pode ser armazenada em cache devido a nenhuma alteração é um problema difícil, como você descreveu. É também mais agradável de ter do que estritamente necessário.

Pessoalmente, eu ficaria mais do que feliz se tudo o que eu tivesse fosse a capacidade de garantir que um comando sempre seja executado. Pegue um Dockerfile como:

RUN install_stuff_take_forever
RUN always_do_it   #will not run every time
RUN more_stuff

Atualmente, a linha always_do_it só será executada na primeira vez, a menos que eu edite o texto para forçar uma falha no cache. Acho que a maioria de nós ficaria feliz em aceitar que more_stuff às vezes será executado desnecessariamente (quando always_do_it não mudou, se em troca podemos manter o cache para install_stuff_take_forever .

RUN install_stuff_take_forever
NOCACHE
RUN always_do_it
RUN more_stuff

@pikeas Recebo totalmente um comando NOCACHE e isso é fácil de fazer. O que eu não recebo é um comando que o liga novamente sem diffing / hashing / qualquer que seja o sistema de arquivos inteiro.

Eu li a explicação da "camada" do Docker para significar que:

  • O Docker cria uma "camada" para cada comando.
  • Essa camada inclui apenas os arquivos alterados (ou possivelmente "salvos" alterados ou inalterados) por aquele comando.
  • O estado atual do sistema de arquivos é logicamente (se não operacionalmente) alcançado verificando cada camada em ordem até encontrar uma versão (atualizada mais recentemente) daquele arquivo específico.

Nesse caso, uma comparação de duas instâncias do mesmo comando é relativamente barata. Você só precisa comparar a camada superior (uma vez que todas as camadas subjacentes são compartilhadas). Existe uma lista específica de arquivos que foram alterados pelo comando. Apenas esses arquivos são incluídos na camada. Concedido ... você precisa comparar todos os arquivos nessa camada ... mas não o sistema de arquivos inteiro.

Também é possível (embora não seja exaustivo) comparar apenas a nova camada com a última vez em que o comando foi executado:

  • Na maioria dos casos (git pull ou atualização de software), a versão atual será (1) a mesma das últimas versões ou (2) uma nova versão ... mas nunca - pelo menos raramente - uma reversão para uma versão anterior versão.
  • Em casos raros (como atualizar para o dev-master e depois reverter para uma versão estável), é possível voltar para uma versão mais antiga. No entanto, eles são muito raros, de modo que a maioria das pessoas provavelmente ficaria melhor (freqüentemente) checando apenas a versão mais recente e reexecutando os comandos nas raras ocasiões em que fazem rollback.

Claro, você também pode fazer uma verificação hash em todas as versões anteriores ... seguida por uma verificação completa do arquivo ... para oferecer suporte completo sem sobrecarga.

se você olhar a parte inferior de https://github.com/docker/docker/pull/9934, verá uma discussão sobre opções de suporte para comandos Dockerfile. E se houvesse uma opção --no-cache disponível em todos (ou apenas RUN) que significasse "não use o cache" para este comando? por exemplo:
RUN --no-cache apt-get install -y minha-ferramenta-favorita
Isso então desabilitaria automaticamente o cache para os comandos restantes também (eu acho).
Isso resolveria o problema?

Entre "RUN ALWAYS" e "RUN --no-cache", que são semanticamente idênticos, eu pessoalmente prefiro a sintaxe mais natural "RUN ALWAYS". Eu concordo com o último comentário sobre esse PR: Eu acho que --option quebra a legibilidade e tornará os Dockerfiles feios. Além disso, acho que os comandos do Dockerfile precisarão ser muito distintos em relação aos comandos reais que os seguem. Imagine algo como "RUN --no-cache myapp --enable-cache" para um exemplo de sintaxe complicada que começaria a se expressar rapidamente com esse tipo de opção.

@curtiszimmerman, seu exemplo é muito claro para mim. --no-cache é para RUN enquanto --enable-cache é para myapp. O posicionamento é importante. Por exemplo, veja:
docker run -ti ubuntu ls -la
as pessoas entendem que -ti é para 'run' enquanto '-la' é para 'ls'. Esta é uma sintaxe com a qual as pessoas parecem se sentir confortáveis.
Um dos problemas com algo como EXECUTAR SEMPRE é a extensibilidade. Precisamos de uma sintaxe que funcione para todos os comandos do Dockerfile e suporte a passagem de valor. Por exemplo, as pessoas expressaram interesse em especificar o USUÁRIO para determinados comandos.
RUN USER = foo myapp
está tecnicamente configurando um env var USER como 'foo' dentro do shell do myapp. Portanto, somos ambíguos aqui.
Enquanto: RUN --user = foo myapp não tem esse problema.
É: RUN var = foo myapp
tentando definir e env var chamado 'var' ou um erro de digitação tentando obter alguma opção RUN?
IOW, as chances de sobreposição com um comando válido existente, IMO, são muito menores quando começamos as coisas com - do que apenas permitir uma palavra lá

Na verdade, defendo a sequência reversa, EVERY <options> COMMAND . Vários motivos:

  • No caso de "usuário" e "cache" (pelo menos), eles são realmente características do ambiente que podem envolver qualquer COMANDO (embora possam não afetar materialmente outros).
  • A sintaxe RUN ALWAYS significa alterar o interpretador de comandos RUN , o que parece desnecessário.
  • Este problema é ainda pior com RUN EVERY 5 days porque as opções anexadas a CADA criam ainda mais ambigüidade. EVERY 5 days RUN é claro sobre o comando que as opções afetam. Temos o mesmo problema com RUN USER usr vs. USER usr RUN . Contanto que (1) as palavras-chave do comando nunca sejam opções ou (2) haja uma maneira fácil de escapar delas, isso não é ambíguo.

Eu poderia embarcar prefixando os comandos com suas opções ( ALWAYS AS user RUN ... ). Estou realmente preocupado em usar longopts do estilo GNU para opções porque eles não são muito separados dos olhos velhos ou vidrados. Posso me imaginar olhando para um comando Dockerfile complexo depois de 20 horas me perguntando se o wtf está acontecendo. Mas eu prevejo - as opções vão acontecer de qualquer maneira.

Mas eu prevejo - as opções vão acontecer de qualquer maneira.

Nada está decidido ainda, pelo contrário; a sintaxe que @duglin está sugerindo é uma _proposta de contador_ para uma sintaxe que foi proposta / decidida anteriormente. Leia # 9934 para obter mais informações sobre isso.

Além disso, @duglin _não_ é a pessoa que toma essa decisão (pelo menos, não sozinha). Alguns dos pontos que você está levantando foram mencionados na outra discussão.

Compartilho sua preocupação com a legibilidade, mas também acho que as outras sintaxes propostas podem ter o mesmo problema se várias opções precisarem ser especificadas.

Este problema pode ser superado formatando o Dockerfile para facilitar a leitura. Acho que seria bom escrever mais alguns exemplos para testar / verificar se a legibilidade é uma preocupação quando formatado corretamente.

E, sim, sua opinião é bem-vinda.

Eu ainda estou muito -1 em deixar o próprio Dockerfile definir onde o cache
deve e não deve ser aplicado. Ainda estou para ver um bom exemplo de um
Dockerfile que não pôde ser reescrito para impedir o cache de maneira adequada e
naturalmente quando o recurso subjacente precisava ser atualizado.

Ter um sinalizador em "docker build" para interromper o cache em um local específico
seria muito mais flexível, IMO (e devolveria o controle do cache
nas mãos do operador do sistema que consegue gerenciar esse cache de qualquer maneira).

+1 no -1 de @tianon (então é -1!), E adicionar um sinalizador para quebrar na etapa N parece razoável. Considerando que, uma vez que o cache é quebrado, ele fica quebrado para o resto do Dockerfile de qualquer maneira, acho que isso faz sentido.

A principal necessidade para isso é porque o mecanismo de cache do docker está diretamente ligado ao armazenamento e transporte da imagem, o que torna o cache eficiente, mas com contrapartida de imagens significativamente maiores. Então, vamos consertar isso!

Sem dizer como me sinto sobre esse recurso - não tenho certeza ainda, para ser honesto - como vocês imaginam alguém dizendo (de "docker build") para parar na etapa N? Parece meio frágil quando hoje o passo N seria o passo N + 1 amanhã.
Parece que podemos precisar de uma maneira de adicionar um "rótulo" de algum tipo dentro do Dockerfile para que as pessoas possam fazer referência a esse rótulo a partir da linha de cmd de construção.
Se tivéssemos isso, não tenho certeza se vejo muita diferença entre isso e adicionar um comando "STOP-CACHING" que aparece no Dockerfile.
Qual é um bom exemplo de um cmd Dockerfile que invade o cache todas as vezes?

Bem, é por isso que foi originalmente discutido para torná-lo um
expressão regular baseada em conteúdo de linha, com a qual eu também estaria bem (especialmente porque
isso é muito mais fácil de fazer o script do que saber exatamente qual número da etapa você
não quero em cache - de jeito nenhum estou escrevendo uma cópia completa do atual
Analisador do Dockerfile no Bash, obrigado: D).

Tianon Gravi [email protected] escreveu:

Bem, é por isso que foi originalmente discutido para torná-lo um
expressão regular baseada em conteúdo de linha, com a qual eu também estaria bem (especialmente
Desde a
isso é muito mais fácil de fazer o script do que saber exatamente qual número da etapa
vocês
não quero em cache - de jeito nenhum estou escrevendo uma cópia completa do atual
Analisador do Dockerfile no Bash, obrigado: D).

Gostaria de reafirmar minha sugestão anterior, que SEMPRE / quebra de cache
"RUN" deve ser apenas "RUN!" para manter a estrutura de comando de 1 palavra (?).

Parece complicado ter que editar um Dockerfile (adicionando algo que é basicamente aleatório porque é um espaço reservado) para quebrar o cache em uma etapa específica. Eu usaria uma opção docker build CLI que sempre executa uma determinada etapa, mas concordo totalmente com @duglin que ter que rastrear o número de linha específico para alimentá-lo para o comando é complicado. Não quero ter que dar o passo extra de adicionar alguns caracteres aleatórios (!) A um Dockerfile imediatamente antes de meu git clone apenas para incitar o Docker a realmente clonar o repo em vez de trabalhar a partir do cache.

@curtiszimmerman Eu sugeri (!) porque indica algo semelhante a urgência em inglês. ("Você deve fazer isso!")

Acho que o Dockerfile é pelo menos um local apropriado para definir quais comandos não podem ser armazenados em cache. Ter que construir com "--no-cache = git" (eu percebo que isso não é algo que você sugeriu, mas você não sugeriu nada para eu citar / comparar) parece mais confuso.

Por que o foco em RUN? Por que não permitir que o cache seja interrompido por qualquer comando?
Parece adicionar um:
BUST-CACHE
tipo de comando Dockerfile seria muito mais flexível. E para realmente adicionar flexibilidade, pode opcionalmente permitir um sinalizador:
BUST-CACHE $ doit
onde só se aplica se $ doit for definido - então, se adicionarmos suporte para uma opção -e na construção (https://github.com/docker/docker/pull/9176), então as pessoas poderiam fazer:
docker build -e doit = ​​true ...

@zamabe Oh, eu usaria totalmente RUN! , desculpe. Aqui eu estava usando (!) Para dizer "Isso é incomum!" sobre a edição de um Dockerfile sempre que desejo quebrar o cache em uma etapa específica. Qualquer maneira de invadir o cache dentro de um Dockerfile antes de uma etapa específica seria útil (e para uma vitória extra, se a etapa após o comando de impedimento de cache for o mesmo resultado do que está no cache, seja inteligente o suficiente para continuar a partir do cache ) BUST-CACHE ou ALWAYS RUN (ou RUN ALWAYS ) ou RUN! ... Realmente, qualquer mecanismo que suporte este recurso, eu o usaria.

@duglin, desculpe? O título do bug diz RUN, o que é mais fácil de dar como exemplo.

@curtiszimmerman ah.

Como um aparte; Acho que a revalidação de cache (?) Está um pouco além da invalidação de cache que esse bug está procurando. Embora eu goste do que você está sugerindo, gostaria apenas de reordenar meu Dockerfile para colocar os comandos de impedimento de cache o mais próximo possível do fim. Isso nega os benefícios obtidos com um _possível_ acerto de cache, uma vez que você _sempre_ faz os cálculos / comparações necessários, o que provavelmente é uma penalidade mais pesada do que terminar a compilação do Dockerfile normalmente, já que as pessoas que usam o cachebusting estão provavelmente esperando / esperando uma falha de cache.

@zamabe aprovado . Eu sugiro que se a implementação for bastante trivial fazer isso, talvez um comando especial para continuar a partir do cache, que é separado do identificador de impedimento de cache. Algo como DISABLE-CACHE em um determinado ponto para desativar o cache todas as vezes, e se você tiver um caso de uso em que o resto do Dockerfile seria caro em comparação com a continuação do cache, algo como DISABLE-CACHE? seria continue a partir do cache, se possível. Isso não é uma sugestão, apenas uma demonstração para transmitir o que estou falando.

+1 para códigos pull do repo git

+1

Isso seria enorme! No momento, tenho parte da minha integração contínua escrevendo o hash git commit no Dockerfile (sobrescrevendo um espaço reservado) apenas para quebrar o cache para clones git.

Enviei este PR: https://github.com/docker/docker/pull/10682 para resolver esse problema.
Embora não ofereça suporte para ativar o cache novamente, não acho que isso seja possível hoje.

+1

Estou gerando um número aleatório no Dockerfile e ele é armazenado em cache ...
+1 para uma instrução NOCACHERUN

+1
Deve ser realmente útil para alguns RUN que precisamos fazer a cada vez, sem reconstruir tudo

Tenho notado que git clone atingirá o cache, mas go get -d não. alguma ideia por quê?

_Revisão coletiva com @ LK4D4 @calavera @jfrazelle @crosbymichael @tiborvass_

Fechando isso, pois não vemos muitos casos de uso no mundo real (consulte o # 10682 relacionado para obter mais detalhes).

1 para RUN. Seria bom.

+1

docker 1.9 apresenta variáveis ​​de tempo de construção; é possível (mal-) usá-los para forçar a quebra do cache; para obter mais informações, consulte https://github.com/docker/docker/issues/15182

Como isso ainda não é um recurso?

@ hacksaw6 Você pode dar uma olhada no que foi dito aqui: https://github.com/docker/docker/pull/10682

+1

+1

+1 como isso ainda nem é uma coisa !!! ???!

+1 Precisamos desse recurso para fornecer um controle mais granular para a construção.

+1

+1

+1

+1

+1 muito útil
(usando a solução alternativa @timruffles por enquanto)

+1

+1

+1

pode ser útil se as pessoas postarem seus casos de uso em vez de apenas +1 para que as pessoas possam ver por que esse é apenas um recurso necessário.

+1, cheguei aqui através do Google em busca de uma solução para um clone git em cache.

Meu caso de uso:
Eu tenho uma configuração docker, que durante sua compilação chamará via gradle um aplicativo de microsserviço excelente no modo de simulação. Isso resultará em que todas as bibliotecas java dependentes (de um repositório mvn remoto) serão baixadas no repositório docker mvn local. A simulação apenas executará o aplicativo e retornará imediatamente, mas garante que todas as dependências da biblioteca java sejam carregadas.
Durante a fase de execução do docker, o mesmo aplicativo será executado por meio do modo gradle --offline. Ou seja, o aplicativo de microsserviço será carregado apenas do diretório do repositório mvn local. nenhuma busca de biblioteca remota cara e demorada ocorrerá. Quando eu lançar uma nova versão de instantâneo dessa biblioteca, o docker não acionará uma busca remota durante uma compilação (ou seja, ele não chamará meu gradle dryrun cmd), a menos que eu modifique o diretório do docker.

Meu caso de uso: Buscar a versão mais recente de terceiros de uma biblioteca para usar em uma imagem. Estou usando o docker hub para isso e AFAIK, não vai armazenar nada em cache. Mas quem sabe quando isso pode mudar.
Se houvesse um sinalizador de comando como NOCACHE no docker, isso garantiria, independentemente de onde a imagem foi construída.

É pior depender de um "recurso" de sistema de compilação do que de uma versão mais recente, IMHO.

Que tal adicionar uma nova sintaxe: FORCE RUN git clone .... ?

No momento, estou usando RUN _=$(date) git clone ... para invalidar o cache.

@ c9s isso realmente funciona? Eu acho que não.

A variável de ambiente de configuração

@ c9s Não vejo como a configuração de env var poderia funcionar, já que isso é feito pelo shell do contêiner, não pelo processamento do Dockerfile. Quando tento RUN _=$(date) echo hi ele usa o cache na segunda compilação.

@duglin você está certo: | não invalida o cache

@ c9s tente isso ao invés

FROM foo
ARG CACHE_DATE=2016-01-01
RUN git clone ...
docker build --build-arg CACHE_DATE=$(date) ....

@thaJeztah Obrigado! funciona!

+1 clonagem git repos (caso de uso)

Tantos + 1s, se você puxar o repositório git em seu arquivo docker, o cache impede que suas imagens sejam compiladas. Torna meio difícil enviar compilações por meio de CI.

+1 clonagem de repositórios git (é muito chato que a imagem precise ser construída do zero cada vez que uma pequena edição é feita em um repositório git)

@Vingtoft Se você estiver atualizando os arquivos no repositório, seu cache será invalidado.

@itsprdp Eu não sabia disso, obrigado pelo esclarecimento.

@itsprdp acabei de testar. Quando estou atualizando o repo e criando a imagem, o Docker ainda está usando o cache.
Talvez eu esteja entendendo mal alguma coisa?

@itsprdp Isso não está correto em minha experiência. Fiz um novo commit em um repo para testar, e ao construir novamente, ele usa o mesmo cache.

Se eu alterar o arquivo docker anterior ao repo, é claro que o cache será interrompido; no entanto, a simples atualização de um repo não parece resolver esse problema.

@RyanHartje Desculpe a confusão. É suposto invalidar o cache se o repositório for atualizado e isso é algo a ser considerado pelos contribuidores.
O caso de uso esperado por @Vingtoft é armazenar em cache o repositório e apenas atualizar os arquivos alterados no repositório. Isso pode ser complicado de implementar.

@itsprdp Apenas atualizar os arquivos alterados em um repositório seria incrível, mas menos (ou devo dizer mais?) também funcionaria.
No meu caso de uso (e em muitos outros), o git pull real não leva muito tempo: é a construção de todo o resto que está matando o fluxo de desenvolvimento.

+1, cache usado durante o clone git :(

Uma solução integrada seria boa, mas enquanto isso você pode invadir o cache em uma instrução Dockerfile específica usando ARG .

No Dockerfile:

ARG CACHEBUST=1
RUN git clone https://github.com/octocat/Hello-World.git

Na linha de comando:

docker build -t your-image --build-arg CACHEBUST=$(date +%s) .

Definir CACHEBUST para a hora atual significa que ela sempre será única e as instruções após a declaração ARG no Dockerfile não serão armazenadas em cache. Observe que você também pode construir sem especificar o CACHEBUST build-arg, o que fará com que ele use o valor padrão 1 e preserve o cache. Isso pode ser usado para sempre verificar novas cópias de repositórios git, puxar as dependências SNAPSHOT mais recentes, etc.

Edit: O que, uh, é exatamente o que @thaJeztah disse. Vou deixar isso como uma descrição adicional de sua solução.

@ shane-axiom Que tal usar o hash do git commit como o valor de CACHEBUST ?

export CACHEBUST=`git ls-remote https://[email protected]/username/myRepo.git | grep refs/heads/develop | cut -f 1` && \
echo $CACHEBUST && \
docker build -t myDockerUser/myDockerImage \
   --build-arg blah=blue \
   --build-arg CACHEBUST=$CACHEBUST \
   .

Com base nas dicas de http://stackoverflow.com/questions/15677439/how-to-get-latest-git-commit-hash-command#answer -15679887

@pulkitsinghal Isso parece maravilhoso para repositórios git. Para outros usos (como puxar em dependências SNAPSHOT, etc), a abordagem de carimbo de data / hora sempre estourando funciona bem.

+1 para CACHE ON | FORA

+1

+1

Lembre-se da abordagem @CheRuisiBesares , você sempre pode usar ADD https://www.random.org/strings/?num=16&len=16&digits=on&upperalpha=on&loweralpha=on&unique=on&format=plain&rnd=new uuid como uma solução alternativa para problemas de cache.

Para postar um caso de uso adicional ....

COPY package.json /usr/src/
RUN npm install

Em nosso package.json geralmente apontaremos para uma tag master para algumas de nossas dependências github privadas. Isso significa que nunca obteremos o master mais recente, a menos que alteremos o arquivo package.json (normalmente apenas adicione - à descrição e remova-o durante o teste).

RUN NO CACHE para substituir RUN parece que seria uma boa solução.

+1

Eu tenho um problema semelhante para a instalação do npm que usa cache e não usa minha nova biblioteca publicada no npm.

Seria ótimo se eu pudesse desabilitar o cache por comando RUN no arquivo docker.

@brycereynolds @mmobini consulte https://github.com/docker/docker/issues/1996#issuecomment -172606763 para invadir manualmente o cache. No entanto, _não_ especificar uma versão específica dos pacotes que precisam ser instalados pode não ser a melhor prática, pois o resultado final do seu Dockerfile (e código-fonte) não é mais garantido como reproduzível (ou seja, ele é compilado com sucesso hoje, mas não amanhã, porque um dos pacotes foi atualizado). Posso ver que isso está "ok" durante o desenvolvimento, mas para produção (e compilações automatizadas no Docker Hub), a melhor abordagem é especificar explicitamente uma versão. Isso também permite que os usuários verifiquem os pacotes exatos que foram usados ​​para produzir a imagem.

Eu tenho um caso de uso em que não conseguir invalidar o cache está causando problemas. Estou executando aplicativos Dropwizard (Java REST Services construído com Maven) do Docker e um sistema automatizado está fazendo todas as construções e implantação de contêineres para mim. Incluo um Dockerfile em meu repo e ele faz o resto. O sistema executa uma versão de produção e uma ou mais versões de desenvolvimento do meu aplicativo. As compilações de desenvolvimento são onde estou tendo problemas.

Durante o desenvolvimento, algumas das dependências do projeto possuem SNAPSHOT em seus números de versão. Isso instrui o Maven que a versão está em desenvolvimento e deve trazer uma nova versão a cada compilação. Como resultado, uma estrutura de arquivo idêntica pode resultar em duas compilações distintas. Este é o comportamento desejado, uma vez que bugs podem ter sido corrigidos em uma dependência SNAPSHOT. Para oferecer suporte a isso, seria útil forçar o Docker a executar um comando específico, uma vez que não há como determinar o efeito do comando com base no estado atual do sistema de arquivos. A maioria dos projetos Java vai executar isso, uma vez que as dependências SNAPSHOT do estilo Maven são usadas por vários sistemas de construção diferentes.

@ctrimble Você pode usar --no-cache ou --build-arg para invalidar o cache.
Você pode minimizar o efeito de --no-cache tendo uma imagem de base com todos os comandos armazenáveis ​​em cache.

@ cpuguy83 obrigado pela resposta. Eu li o tópico e entendo as opções atuais. Abri um tíquete com o sistema de compilação que estou usando para fornecer um argumento de impedimento de cache. Produzir duas imagens distintas para um único aplicativo parece muito difícil para acelerar as compilações. Seria muito mais fácil ser capaz de especificar algo como:

  1. fazer coisas que podem ser armazenadas em cache se o sistema de arquivos for idêntico
  2. fazer algo que pode mudar o sistema de arquivos com base em quando ele é executado
  3. fazer mais algumas coisas que poderiam ser armazenadas em cache se a etapa anterior não alterasse o sistema de arquivos

Esse padrão aparecerá frequentemente em compilações de desenvolvimento. Seria bom ter uma semântica para isso no Dockerfile.

@ctrimble O rebatimento do cache em uma etapa fará com que o cache sempre seja interrompido em cada etapa subsequente.

@ cpuguy83 exatamente. A semântica do meu sistema de compilação é temporal para compilações de desenvolvimento. Tenho que selecionar compilações corretas sobre o cache. Eu realmente gostaria de obter os dois.

Houve uma discussão considerável aqui, desculpas se já foi sugerido, mas e se houvesse algo assim:

CHECK [FILE_PATH]

Tudo o que o docker faria é armazenar o MD5 (ou qualquer outro hash) do arquivo e, se ele mudar, todas as etapas subsequentes serão invalidadas.

Eu provavelmente estaria fazendo algo como:

CHECK Gemfile
CHECK package.json
CHECK composter.json
CHECK project.json

Também pode ser desejável habilitar uma verificação de que algum tempo decorre após um período de tempo. O parâmetro cache_valid_time Ansible para o plugin apt pode oferecer alguma inspiração: http://docs.ansible.com/ansible/apt_module.html

Para isso, a sintaxe seria:

EXPIRE 1234567 
RUN apt-get update
RUN bundle install

O Docker saberia o tempo da última execução e calcularia se o tempo passou com base no "agora".

@atrauzzi Acabamos de apoiar --squash na construção agora em 1.13 (experimental apenas por enquanto).

@ cpuguy83 Há algum documento ou explicação sobre --squash algum lugar que eu possa ler? No início, o nome não faz parecer que corresponda ao que estou pensando. Mas eu posso estar (e provavelmente estou) errado!

@atrauzzi sim, na referência de construção.

Basicamente, --squash preserva o cache da camada e cria uma segunda imagem que é como se tudo no Dockerfile acontecesse em uma única camada.

Não vejo por que seria necessário verificar se um cache de arquivo ainda é válido individualmente, ADD e COPY já fazem isso para tudo o que está sendo copiado.

@ cpuguy83 Bom argumento, nem pensei nisso e é claro que já estou usando.

E quanto à abordagem de carimbo de data / hora / duração? Isso é possível com o que já está disponível?

E quanto à abordagem de carimbo de data / hora / duração? Isso é possível com o que já está disponível?

Por meio de build-args;

ARG expire_after=never
RUN do some thing
docker build --build-arg expire_after=2016-12-01 -t foo .

mude o argumento de construção para estourar o cache

+1 para uma maneira mais limpa

+1 para uma maneira mais limpa

Também deve haver opções separadas para desativar a leitura do cache e para desativar a gravação nele. Por exemplo, você pode querer construir uma imagem nova do zero e ignorar todas as camadas armazenadas em cache, mas ainda assim gravar as novas camadas resultantes no cache.

+1

Posso sugerir passar o número da etapa para o comando de construção?

Algo assim:
docker build --step 5 .

Ele iria ignorar todos os caches após e incluindo a etapa 5 durante a construção.

+1
Por favor.

CACHE ON | OFF +1

O problema com esses comandos CACHE ON|OFF é que, seja qual for a etapa em que o cache é desativado, não há como armazenar outras etapas em cache. O único comando sensato seria ENDCACHE .

É uma ideia / ethos válido. O comando deve aglutinar todas as camadas não armazenadas em cache em uma única camada no ponto em que o cache é ligado novamente. Claro que você ainda pode argumentar a melhor nomenclatura / correção de semântica / sintaxe preferida do recurso.

+1

+1 o recurso obrigatório

Concordo para CACHE ON | OFF +1

1 seria incrível.

Eu realmente não entendi como o Docker armazena em cache as etapas anteriores e passei meio dia investigando por que meu sistema não está compilando corretamente. Era o cache do "clone git".

Adoraria ter a palavra-chave ALWAYS .

Como está fechado?

Qual é a melhor solução alternativa?

Tentei https://github.com/moby/moby/issues/1996#issuecomment -185872769 e funcionou
No Dockerfile:

ARG CACHEBUST=1
RUN git clone https://github.com/octocat/Hello-World.git

Na linha de comando:

docker build -t your-image --build-arg CACHEBUST=$(date +%s)

Por que não criar um novo comando semelhante a RUN, mas nunca armazena em cache RUNNC para RUN NO CACHE?

Posso confirmar, @habeebr (https://github.com/moby/moby/issues/1996#issuecomment-295683518) - Eu uso em combinação com https://github.com/moby/moby/issues/1996# issuecomment -191543335

+1

RUNNC é uma ótima ideia!

Por que esse problema foi encerrado? Entre a miríade de duplicatas que pedem essencialmente a mesma coisa e o longo histórico de comentários de mais de uma dessas duplicatas, _parece_ óbvio que há um interesse saudável em ver essa funcionalidade disponível.

Eu entendo que é difícil e talvez ninguém tenha sugerido uma solução suficientemente elegante que atenda à necessidade e seja limpa o suficiente para ser uma adição atraente do Docker ... mas isso não significa _que não há necessidade_.

O único outro argumento que ouvi a favor de encerrar isso é que existem outras maneiras de fazer isso ... mas esse argumento também não é aprovado. Criar várias imagens de base com o único propósito de contornar a falta de controle de cache é difícil de manejar, arquitetar uma invalidação por meio de um ARG é obtuso e não intuitivo. Imagino que os usuários queiram utilizar essas "soluções alternativas" tanto quanto os desenvolvedores do Docker desejam incorporar oficialmente um hack descuidado à ferramenta.

não é difícil: https://github.com/moby/moby/pull/10682
solução fácil, UX fácil. Apenas não há um consenso claro sobre se isso deve ser feito.

Wow apenas wow...

Eu já teria implementado apenas para não ter que ouvir sobre isso, muito menos que haja um consenso claro de que a base de usuários deseja. Não estive no lado do desenvolvedor em um projeto de código aberto tão grande, apenas em projetos muito menores, então talvez esteja faltando alguma coisa.

+1

+1 para segurança sensata e melhor desempenho

+1

+1

+1

+1

+1

+1

Vocês podem parar de enviar spam para o +1? Basta usar o recurso de reação para votar positivamente.

Alguma mudança?
Ainda não sei por que esse problema foi encerrado.
Na minha opinião, é um recurso obrigatório que lida perfeitamente com o pull de versão do repositório git remoto.

+1

+1

+1

+1

+1

+1

+1

+1

+1

+1

Por que fechar isso? Eu acho que é útil

+1

+1

+1

Atualmente, a maneira mais simples de desativar o cache de uma camada (e a seguinte):

Dockerfile

ARG CACHE_DATE
RUN wget https://raw.githubusercontent.com/want/lastest-file/master/install.sh -O - | bash

E quando você constrói a imagem, --build-arg precisa ser adicionado

docker build  --build-arg CACHE_DATE="$(date)"

Então o comando wget será executado toda vez que você construir a imagem, ao invés de usar um cache.

RUNNC ou CACHE OFF seria bom

entretanto, isso parece promissor:
http://dev.im-bot.com/docker-select-caching/

isso é:

screenshot 2018-05-26 19 03 09

vou manter a calma e me juntar ao rebanho:

+1

Sim, eu preciso de cache seletivo em comandos. Meu COPY falha 80% das vezes se eu alterar apenas uma palavra em um arquivo de configuração. Eu gostaria de nunca armazenar em cache meu COPY mas armazenar em cache todo o resto. Ter um CACHE ON e CACHE OFF seria ótimo.

RUN X
RUN X
CACHE OFF
COPY /config /etc/myapp/config
CACHE ON

@shadycuz Você nunca poderá "reativar" o cache após desativá-lo / invalidá-lo usando qualquer método. A construção não será capaz de verificar (em um período de tempo razoável com uma quantidade razoável de recursos) se a camada não armazenada em cache não alterou algo mais no sistema de arquivos que precisaria ser considerado nas camadas mais novas. Para minimizar o impacto de sempre precisar puxar um arquivo de configuração externo, você deve colocar sua diretiva COPY mais baixo possível no Dockerfile (para que o Docker possa usar o cache de compilação para o máximo de processo de construção possível antes que o cache seja invalidado).

Para invalidar o cache em um ponto específico do processo de construção, você pode consultar qualquer um dos outros comentários sobre o uso de --build-arg e ARG mencionados aqui anteriormente.

@shadycuz @curtiszimmerman Sim, podemos preservar apenas CACHE OFF mas não CACHE ON , porque as camadas a seguir precisam ser reconstruídas se uma camada anterior for alterada.

Eu concordo que CACHE ON não faz sentido do ponto de vista técnico. Isso ajuda a expressar a intenção de forma mais clara, quais camadas realmente devem ser invalidadas.

Uma solução mais flexível seria um comando semelhante a RUN que permitisse algum código de shell determinar se o cache deveria ser invalidado. Um código de saída 0 pode significar "usar cache" e 1 "invalidar cache". Se nenhum código de shell for fornecido, o padrão pode ser invalidar o cache a partir de agora. O comando pode ser denominado INVALIDATE, por exemplo.

por que isso foi fechado sem comentários?

Houve um comentário, mas está oculto pelo github
https://github.com/moby/moby/issues/1996#issuecomment -93592837

+1

Esse recurso seria um salva-vidas para mim agora.

+1

Fechando isso, pois não vemos muitos casos de uso do mundo real

212 comentários e contando, mas ainda nenhum caso de uso? Parece muito ignorante.

+1

+1

+1

+1

+1

o problema ainda está aqui e ainda precisa de uma solução. Existem muitos usos no mundo real ainda presentes.

+1

Suspeito que os desenvolvedores do Docker não tenham nenhum incentivo para implementar isso, para proteger sua infraestrutura de construção centralizada de ser DDsS por solicitações sem cache.

Também suspeito que uma infraestrutura paralela que facilite compilações sem cache seria interessante para usuários corporativos.

No geral, esse problema não é sobre um recurso de software, mas um problema de dimensionamento de serviço.

@jaromil Isso não é totalmente verdade, pois isso também não é possível em repositórios auto-hospedados.

Qual software existe para executar um repositório auto-hospedado? Eu realmente não sei a que você se refere.
Uma solução auto-hospedada simples poderia ser um cron clonando git repos e runnig docker build --no-cache - tenho certeza que esse problema não pode ocorrer em software de código aberto: qualquer um pode então modificar a linha de comando docker build.

@jaromil Não acho que seja esse o problema. Seria mais eficiente tê-lo para os projetos de código aberto do DockerHub (assim como os pagos, eles não cobram pelo número de compilações). Em um ambiente de CI / CD com compilações frequentes, isso fica ainda pior.

Contanto que você precise fazer isso (você está usando docker e git e não quer ter 5 contêineres executando volumes compartilhados), você deve reconstruir o contêiner e fazer upload sempre que carregar uma nova versão. Todo o contêiner.
Com um sinalizador sem cache no código, cada vez que você executa a construção, você apenas constrói e substitui aquela única camada em vez de todo o contêiner para atualizar a versão.

Sobre o representante de self-hosting, você ficaria surpreso. Eu entendo o comentário de @bluzi , não há impacto de ddos ​​se você se hospedar (ou usar aws ecr).

Ok, este é certamente um cenário mais complexo que eu estava imaginando. agora eu acho ... upload com uma espécie de hashes de camada única nocache ... push and override, o nome dele. Não tenho certeza

TLDR: Acho que algumas melhorias na documentação do Docker podem ajudar muito.

Acabei aqui depois de encontrar meus próprios problemas / confusão com o cache. Depois de ler todos os comentários aqui e em https://github.com/moby/moby/pull/10682, encontrei uma solução viável para meu caso de uso específico. No entanto, de alguma forma, ainda me sentia frustrado com a resposta de Docker a isso, e parece que muitos outros pensam da mesma forma.

Por quê? Depois de pensar sobre isso de vários ângulos diferentes, acho que o problema aqui é uma combinação de casos de uso vagos, argumentos excessivamente generalizados contra as mudanças propostas (que podem ser válidas, mas não abordam diretamente os casos de uso apresentados) e uma falta de documentação para recomendações do Docker para alguns casos de uso comuns. Talvez eu possa ajudar a esclarecer as coisas e identificar a documentação que poderia ser melhorada para ajudar nessa situação.

Lendo nas entrelinhas, parece-me que a maioria dos primeiros comentaristas sobre esta solicitação de recurso ficaria feliz com uma solução que usa argumentos adicionais para docker image build para desabilitar o cache em um ponto específico no Dockerfile. Parece que a solução atual do Docker para isso (descrita em https://github.com/moby/moby/issues/1996#issuecomment-172606763) deve ser suficiente na maioria desses casos, e parece que muitos usuários estão felizes com isso . (Se alguém tiver um caso de uso em que possa fornecer argumentos adicionais para docker image build mas esta solução ainda for inadequada, provavelmente ajudaria adicionar um comentário explicando por que isso é inadequado.)

Toda a frustração remanescente parece estar relacionada ao requisito de passar argumentos adicionais para docker image build para controlar o comportamento do cache. No entanto, os casos de uso relacionados a isso não foram descritos muito bem.

Lendo nas entrelinhas novamente, parece-me que todos esses casos de uso estão relacionados a serviços que executam docker image build em nome de um usuário ou relacionados a Dockerfiles que são distribuídos a outros usuários que executam docker image build eles próprios. (Se alguém tiver qualquer outro caso de uso em que passar argumentos adicionais para docker image build seja um problema, provavelmente ajudaria adicionar um comentário explicando seu caso de uso em detalhes.)

Em muitos desses casos, parece que o caso de uso não requer realmente a capacidade de desabilitar o cache em um ponto específico no Dockerfile (que era o ponto original desta solicitação de recurso). Em vez disso, parece que muitos usuários ficariam felizes com a capacidade de desativar o cache inteiramente de dentro do Dockerfile, sem usar o argumento "--no-cache" para docker image build e sem exigir modificações manuais no Dockerfile antes de cada Construir. (Ao descrever casos de uso, provavelmente ajudaria a mencionar se o cache parcial é realmente necessário ou se desabilitar o cache inteiramente seria suficiente para o seu caso de uso.)

Nos casos em que um serviço executa docker image build em nome do usuário, parece que o Docker espera que todos esses serviços desabilitem incondicionalmente o cache ou dêem ao usuário a opção de desabilitá-lo. De acordo com https://github.com/moby/moby/pull/10682#issuecomment-73777822, o Docker Hub desabilita incondicionalmente o cache. Se um serviço ainda não faz isso, o Docker https://github.com/moby/moby/pull/10682#issuecomment-159255451 sugeriu reclamar com o provedor de serviços sobre isso.

Esta me parece uma posição razoável para o Docker assumir em relação aos serviços que executam docker image build . No entanto, essa posição realmente precisa ser oficialmente documentada em um local visível para que tanto os provedores de serviços quanto os usuários saibam o que esperar. Não parece que esta posição ou o comportamento de cache do Docker Hub estejam atualmente documentados em qualquer lugar que não seja aqueles comentários improvisados ​​enterrados profundamente dentro daquela solicitação pull enorme / antiga / fechada, então não é surpresa que tanto os provedores de serviço quanto os usuários rotineiramente entenda errado. Talvez adicionar informações à referência docker build descrevendo a opinião do Docker sobre o uso de cache por serviços de compilação e adicionar informações à documentação de compilação automatizada do Docker Hub sobre o comportamento de cache do Docker Hub possa eliminar esse problema?

Para casos em que Dockerfiles são distribuídos para outros usuários que executam docker image build eles próprios, algumas pessoas argumentaram que o uso do comando docker build . simples (sem argumentos adicionais) é tão comum que seria irracional para os criadores do Dockerfile exigir que os usuários adicionem argumentos, enquanto outras pessoas (por exemplo: https://github.com/moby/moby/issues/1996#issuecomment-72238673 https://github.com/moby/moby/pull / 10682 # issuecomment-73820913 https://github.com/moby/moby/pull/10682#issuecomment-73992301) argumentaram que seria inadequado impedir incondicionalmente os usuários de usar o cache por substituições de cache de codificação permanente no Dockerfile. Na ausência de casos de uso detalhados / convincentes para isso, Docker tomou a decisão executiva de exigir argumentos de linha de comando adicionais para controlar o cache, o que parece ser a fonte de grande parte da frustração persistente. (Se alguém tiver um caso de uso atraente relacionado a isso, provavelmente ajudaria adicionar um comentário explicando-o em detalhes.)

No entanto, parece-me que o Docker pode deixar todos felizes simplesmente quebrando o hábito dos usuários de executar docker build . sem argumentos adicionais. O comportamento de cache e o argumento "--no-cache" não são mencionados em nenhum dos tutoriais relevantes do Docker (como este ou este
ou isso ). Além disso, embora a documentação docker build liste o argumento "--no-cache", ela não explica seu significado ou destaca o fato de que é importante em muitos casos de uso comuns. (Observe também que a documentação docker image build está vazia. Deve pelo menos fazer referência à documentação docker build .) Parece que apenas a referência do documentação de práticas recomendadas realmente descrevem o comportamento do cache e mencionam a função do argumento "--no-cache". No entanto, é provável que esses documentos sejam lidos apenas por gravadores avançados do Dockerfile. Portanto, não é surpresa que apenas usuários avançados estejam familiarizados com o argumento "--no-cache", e que a maioria dos usuários apenas executaria docker build . sem argumentos adicionais e ficaria confuso quando ele não se comportasse como eles ou o gravador do Dockerfile esperam / desejam. Talvez atualizar os tutoriais e a documentação docker build para mencionar o argumento "--no-cache" e sua importância possa eliminar este problema?

+1

+1

A ferramenta oficial bashbrew do docker não permite adicionar argumentos ao construir imagens, então a resposta "oficialmente suportada" não funciona.

+1

+1

O caso de uso que estou abordando agora é passar segredos transitórios e de curta duração como argumentos de construção para instalar pacotes privados. Isso quebra completamente o cache porque significa que toda vez que o segredo muda (basicamente cada construção), o cache é quebrado e os pacotes são reinstalados novamente, mesmo que a única mudança seja o segredo.

Eu tentei contornar isso consumindo o ARG em um script que é copiado antes de especificar o ARG, mas o Docker parece invalidar tudo depois que o ARG é declarado se a entrada ARG mudou.

O comportamento que eu gostaria de ver é ser capaz de sinalizar um ARG como sempre em cache, no Dockerfile ou na CLI ao chamar o build. Para casos de uso como segredos, geralmente é isso que você deseja; o conteúdo da lista de pacotes deve ditar quando o cache é invalidado, não o argumento passado para ARG.

Eu entendo a teoria de que essas seções podem ser puxadas para uma segunda imagem que é então usada como uma imagem de base, mas isso é um tanto estranho quando os pacotes são usados ​​por um projeto, como em um package.json, requirements.txt, Gemfile, etc. Essa imagem de base também seria continuamente reconstruída.

+1 para CACHE OFF desta diretiva de linha - estou esperando por isso há literalmente anos.

Tive que desabilitar o cache no docker hub / docker cloud e isso economizaria muito tempo e compilações se eu pudesse armazenar em cache a camada grande e, em seguida, apenas executar um comando de atualização nocache próximo ao final do dockerfile.

O comportamento que eu gostaria de ver é ser capaz de sinalizar um ARG como sempre em cache, no Dockerfile ou na CLI ao chamar o build. Para casos de uso como segredos, geralmente é isso que você deseja; o conteúdo da lista de pacotes deve ditar quando o cache é invalidado, não o argumento passado para ARG.

--build-arg PASSWORD=<wrong> poderia produzir um resultado diferente de --build-arg PASSWORD=<correct> , então não tenho certeza se apenas olhar o conteúdo da lista de pacotes funcionaria para isso. O construtor não pode antecipar por si mesmo que efeito a configuração / alteração de uma variável de ambiente teria nas etapas que são executadas ( make DEBUG=1 foo e make DEBUG=0 foo iguais?). A única exceção feita atualmente é para xx_PROXY variáveis ​​de ambiente, onde se presume que um proxy pode ser necessário para conexões de rede, mas mudar para um proxy diferente deve produzir o mesmo resultado. Portanto, para que isso funcione, seria necessária alguma forma de indicar uma variável de ambiente específica (/ build arg) a ser ignorada para o armazenamento em cache.

observe que o BuildKit agora tem suporte experimental para RUN --mount=type=secret e RUN --mount=type=ssh , o que pode ser útil para passar segredos / credenciais, mas ainda pode invalidar o cache se esses segredos mudarem (não tenho certeza; isso pode ser algo para traga o rastreador de problemas do buildkit https://github.com/moby/buildkit/issues).

Tive que desabilitar o cache no docker hub / docker cloud

O Docker Hub / Cloud realmente _utiliza_ o cache? Acho que nenhum cache é usado lá (como em; está usando ambientes de compilação efêmeros)

Lembro-me que o DockerHub não costumava usar o cache de compilação, mas estava olhando minhas compilações automatizadas no Docker Cloud pouco antes deste tíquete e há um controle deslizante Building Caching próximo ao controle deslizante Autobuild de cada branch agora, embora esteja desativado por padrão.

Não ouso habilitar o cache de construção porque etapas como git clone não obterão o download do repo mais recente, pois ele apenas compara a string de diretiva que não muda. Explicando esse problema para um colega que tem sido um espinho em nosso lado por anos, ele ficou surpreso, pois parece ser uma grande imperfeição para muitos casos de uso.

Eu preferiria muito mais que o git clone && make build fosse armazenado em cache e, em seguida, apenas fazer um NO CACHE em um passo git pull && make build para obter apenas uma atualização de código muito menor + dependências ainda não instaladas como as últimas camada, dessa forma armazenando em cache de forma eficiente a maior parte da imagem, não apenas para compilações, mas mais importante para todos os clientes que agora devem baixar novamente e substituir centenas de MB de camadas a cada vez, o que é extremamente ineficiente.

O tamanho é porque muitos dos projetos têm um grande número de dependências, por exemplo. pacotes de sistema + módulos Perl CPAN + módulos Python PyPI etc.

Mesmo usando o Alpine não é muito menor, uma vez que você adiciona as dependências do pacote do sistema e as dependências do CPAN e PyPI, já que eu uso o Alpine há anos para tentar ver se eu poderia criar imagens menores, mas uma vez que você tem muitas dependências, não faz muita diferença se a base começar menor, já que adicionar pacotes de sistema adiciona a maior parte de volta.

Armazenar em cache as camadas anteriores que incluem todos os pacotes do sistema + módulos CPAN + PyPI significaria que muito pouco deve acabar mudando na última camada de atualizações, já que não atualizarei os módulos instalados em funcionamento na maioria dos casos (usei scripts de minhas ferramentas bash utilitário submódulo repo para instalar apenas pacotes que ainda não estão instalados para evitar a instalação de atualizações desnecessárias sem bugfix)

Eu estava tentando usar um truque como mudar o ARG por um tempo (uma ideia que tive ao pesquisar em blogs como http://dev.im-bot.com/docker-select-caching/):

No Dockerfile:

ARG NOCACHE=0

Em seguida, execute o docker build assim:

docker build --build-arg NOCACHE=$(date +%s) ...

mas não acho que isso seja possível no Docker Cloud.

Existem variáveis ​​de ambiente, mas não parece possível usar conteúdos dinâmicos como epoch acima (ou pelo menos não documentado que pude encontrar), e com variáveis ​​de ambiente, não tenho certeza se isso invalidaria o cache para essa linha de diretiva em diante.

@thaJeztah Sim, esse tipo de comportamento pode facilmente ter consequências negativas se for mal interpretado ou abusado, mas resolveria muito bem certos casos de uso.

--build-arg PASSWORD=<wrong> poderia produzir um resultado diferente de --build-arg PASSWORD=<correct> , então não tenho certeza se apenas olhar o conteúdo da lista de pacotes funcionaria para isso

Embora você esteja certo de que isso produziria resultados diferentes, se a lista de pacotes não mudou, eu realmente não me importo se a senha está certa ou errada; os pacotes já estão na imagem anterior, então o usuário que o executa já tem acesso (ou seja, não é uma preocupação de segurança), e se a senha estava errada anteriormente, eu esperaria que o autor do Dockerfile ficasse com a responsabilidade de falhar na instalação se for necessário, o que significa que você ainda terá a chance de instalar os pacotes corretamente após corrigir a senha.

Sim, eu estava imaginando algo como docker build --force-cache-build-arg SECRET=supersecret . Isso é muito desajeitado, tenho certeza que alguém poderia inventar algo melhor.

@HariSekhon Parece que seu caso de uso é na verdade o oposto do meu, certo? Você quer força falta seletivamente o cache, ao invés da força seletivamente acertar o cache?

Adicionar isso funcionou para mim:

ADD http://date.jsontest.com/ /tmp/bustcache

mas esse site está fora do ar agora. Isso deve funcionar

ADD http://api.geonames.org/timezoneJSON?formatted=true&lat=47.01&lng=10.2&username=demo&style=full /tmp/bustcache

@itdependsnetworks

Perfeito, é uma boa solução alternativa e o site está de volta agora. Também é útil registrar a data de construção da imagem.

Eu tentei isso e outros arquivos especiais semelhantes deveriam mudar a cada vez

COPY /dev/random ...

mas isso não funcionou, embora RUN ls -l -R /etc mostrasse que esses arquivos estavam presentes, mas eles nem sempre foram encontrados. Suspeito que haja alguma proteção contra o uso de arquivos especiais.

Agora penso mais sobre isso no DockerHub / Docker Cloud, você provavelmente também poderia usar um gancho de pré-criação para gerar um arquivo contendo um carimbo de data e, em seguida, COPIAR isso para a imagem antes da camada que deseja armazenar em cache, obtendo um resultado semelhante, embora o ADD mostrado acima, eu acho que é mais portátil para docker local e compilações em nuvem.

Precisamos encontrar um site de impressão de data mais confiável para essa solução alternativa de quebra de cache - ambos os itens acima parecem ser demos / têm cotas e, portanto, não são confiáveis ​​e quebram compilações aleatoriamente.

O primeiro quebra sua cota diária o tempo todo e o segundo agora está dando esse erro

{"status": {
  "message": "the daily limit of 20000 credits for demo has been exceeded. Please use an application specific account. Do not use the demo account for your application.",
  "value": 18
}}

Eu acho que seria ótimo ter uma instrução que eu pudesse colocar em um arquivo docker que rodasse em cada construção e se a saída for diferente da última construção, as camadas subsequentes serão reconstruídas.

O uso de exemplo seria:

FROM something
... 
CACHE_BUST git ls-remote my-git-repo HEAD
RUN git clone --depth=1 my-git-repo ...
...
CMD ["my-cmd"]

O comando na instrução CACHE_BUST acima produzirá o SHA do HEAD do repo especificado, dessa forma meu dockerfile pode saber se deve clonar ou não com base nas alterações no repo.

Todos os meus casos de uso aqui estão relacionados a camadas não determinísticas relacionadas à rede, conforme visto acima. Atualmente, posso usar ARG para todas as minhas necessidades aqui, mas isso significa que muitas vezes preciso de um script de construção que use um dockerfile, quando seria bom ter apenas o próprio dockerfile para manter. (além de algumas ferramentas não permitem argumentos)

Meu fluxo de trabalho atual seria assim:

ARG SHA_TO_BUILD
RUN echo SHA_TO_BUILD
RUN git clone ...
...everything else reliant on that clone
$> ./build-my-image.sh $(get-latest-sha)

Acho que ativar e desativar o cache para cada comando é uma má ideia, os arquivos devem ser escritos de forma que, se uma camada precisar ser reconstruída, o resto também. Mas acho que seria bom forçar uma reconstrução em um determinado ponto do arquivo.

um recurso tão bom, por que ainda está pendente?

Outro caso de uso é quando o conteúdo de um arquivo muda, mas o Dockerfile não.

Por exemplo, se eu tiver um COPY file.txt . e modificar file.txt Docker ainda usará a versão antiga em cache.

Se o Docker realizasse uma soma de verificação dos arquivos, ele copiava e usava na próxima vez para determinar se deveria usar a camada em cache que resolveria o problema.

A partir de agora, sou forçado a usar --no-cache e isso baixa e executa muito mais do que o necessário (desperdiçando tempo e largura de banda).

@brennancheung se for esse o caso, é um bug. Sinta-se à vontade para abrir um problema separado com etapas reproduzíveis.

Acho que o ponto principal em que @brennancheung
https://github.com/brennancheung está dizendo é, por exemplo, quando você está
carregando um arquivo de configurações (ou algo semelhante). Você não precisa
reinstalar todo o aplicativo, basta atualizar esses arquivos e os comandos
associado a ele, execute o docker e voila, o sistema está configurado.
Claro, muitas vezes você pode simplesmente colocar o arquivo de configuração próximo ao final do
sua pilha, mas nem sempre é o caso.

Am Mi., 20. März 2019 um 00:10 Uhr schrieb Tibor Vass <
notificaçõ[email protected]>:

@brennancheung https://github.com/brennancheung se for esse o caso,
é um bug. Sinta-se à vontade para abrir um problema separado com etapas reproduzíveis.

-
Você está recebendo isto porque comentou.
Responda a este e-mail diretamente, visualize-o no GitHub
https://github.com/moby/moby/issues/1996#issuecomment-474666893 ou mudo
o segmento
https://github.com/notifications/unsubscribe-auth/ALBon0edO9m5BU3C5Ik2i__9eogZc1Jiks5vYaaNgaJpZM4BB_sR
.

-
Thiago Rodrigues

Tentei https://github.com/moby/moby/issues/1996#issuecomment -185872769

Mas isso só afeta o cache durante / após o primeiro uso e não apenas em sua definição.

https://docs.docker.com/engine/reference/builder/#impact -on-build-caching

Se um Dockerfile define uma variável ARG cujo valor é diferente de uma compilação anterior, ocorre uma “falha de cache” em seu primeiro uso, não em sua definição.

@samstav "primeiro uso" existe o primeiro RUN após o ARG (se esse ARG estiver com um estágio de construção), então:

ARG FOO=bar

FROM something
RUN echo "this won't be affected if the value of FOO changes"
ARG FOO
RUN echo "this step will be executed again if the value of FOO changes"

FROM something-else
RUN echo "this won't be affected because this stage doesn't use the FOO build-arg"

O acima depende um pouco se você estiver usando o construtor de próxima geração (BuildKit), então com DOCKER_BUILDKIT=1 habilitado, porque o BuildKit pode pular os estágios de construção se eles não forem necessários para o estágio final (ou pular os estágios de construção se eles podem ser totalmente armazenados em cache)

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