FreeToGenerate.com

As mesmas duas linhas significam coisas diferentes num .dockerignore e num .gitignore. Aqui você vê os dois veredictos de uma vez. Nada é enviado.

Experimente:

Um padrão por linha. A cerquilha abre um comentário só quando está na primeira coluna, e o ponto de exclamação cria uma exceção a uma linha anterior.

Só importa para o git: um padrão terminado em barra vale apenas para diretórios. O Docker não tem esse padrão, porque a barra é apagada antes da comparação.

O que cada arquivo faria com este caminho

.dockerignore

É enviado ao builder

Decidido pela linha 2, !util/docker/webcasou com util/docker/web

.gitignore

Ignorado

Decidido pela linha 1, **casou com util

Estes dois arquivos discordam sobre este caminho. As mesmas linhas não significam a mesma coisa num .dockerignore e num .gitignore, e nada avisa: o build simplesmente envia mais, ou menos, do que você esperava.

Como cada linha foi lida

LinhaComo escritoDepois da limpezaComparado como
1****sufixo
2!util/docker/webutil/docker/webexceçãostring exata

Tudo roda no seu navegador. Nada do que você colar é enviado a lugar nenhum.

Também disponível em: English · Español · Français · العربية

Arquivo .dockerignore: gerador e verificador de caminhos

Escreva um .dockerignore, verifique qualquer caminho contra ele e veja lado a lado o que o git teria feito com o arquivo idêntico.

O que é um arquivo .dockerignore

O .dockerignore fica ao lado do seu Dockerfile e lista o que não deve ser enviado ao builder. Todo o contexto de build é empacotado e entregue antes de a primeira instrução rodar, então um node_modules esquecido ou um diretório .git custa tempo de upload em cada build, acaba dentro da imagem se algo o copiar, e quebra o cache de camadas silenciosamente, porque o contexto muda sempre que aqueles arquivos mudam.

Ele se parece exatamente com um .gitignore: um padrão por linha, uma cerquilha para comentários, um ponto de exclamação para abrir exceções. É aí que mora o problema. Os dois arquivos são processados por códigos completamente diferentes, e as mesmas linhas podem dar respostas opostas. Nada avisa, porque os dois arquivos são válidos nos dois lugares.

Esta página roda os dois motores ao mesmo tempo. Escreva o seu .dockerignore, informe um caminho, e ela mostra o que o comparador do Docker decide, o que as regras do git decidem, qual linha foi a responsável em cada caso e — a parte que explica tudo — com qual caminho cada um realmente casou.

Como usar

  1. Cole ou escreva o arquivo. Abaixo aparece cada linha com a forma que assume depois da limpeza e como será comparada: como string exata, prefixo, sufixo ou padrão. Os botões de exemplo carregam os quatro casos em que os dois arquivos divergem, mais um em que concordam.
  2. Informe um caminho. Relativo ao contexto de build e com barras normais. Marque a caixa se for uma pasta; isso só importa para as regras do git, e a ferramenta explica por quê.
  3. Leia os dois veredictos. Cada painel nomeia a linha que decidiu e o caminho com que ela casou. Quando divergem, é uma diferença real de comportamento e não um detalhe de exibição.

As quatro diferenças que pegam todo mundo

A primeira ninguém espera, e a própria bateria de testes do Docker a deixa registrada. Exclua tudo com asterisco duplo, reinclua um diretório com um ponto de exclamação, e um arquivo dentro desse diretório é enviado ao builder. Dê ao git as mesmas duas linhas e o arquivo continua ignorado, porque o git percorre o caminho de cima para baixo e nunca olha dentro de um diretório que já excluiu. O comparador do Docker continua avaliando padrões depois que um ancestral casa, então a exceção posterior ainda se aplica. As mesmas duas linhas, resultados opostos.

A segunda é a que mais custa tempo de build. Um padrão sem curinga é comparado ao caminho por igualdade de strings, e a cada diretório acima dele por vez; nada além disso. Então uma linha com node_modules exclui o que está na raiz do seu contexto e nenhum outro. A cópia aninhada dentro de um pacote é empacotada e enviada em todo build. Num .gitignore essa mesma linha casa em qualquer profundidade, que é exatamente por que o arquivo parece estar funcionando. Ponha dois asteriscos e uma barra na frente e o Docker alcança também as aninhadas.

A terceira é um caractere que desaparece. Todo padrão passa pela função de limpeza de caminhos do Go antes de ser usado, e essa função apaga a barra final. Então uma linha terminada em barra não fica restrita a diretórios aqui: é o mesmo padrão sem a barra, e vai casar igualmente com um arquivo de mesmo nome. No git, a barra final é justamente o que restringe um padrão aos diretórios.

A quarta é um caractere que não significa nada. A barra inicial é removida na leitura do arquivo, e os comentários do próprio código do Docker dizem que as duas grafias são equivalentes. No git, a barra inicial ancora o padrão ao diretório onde o arquivo está, e omiti-la é o que faz o padrão casar em qualquer profundidade. O mesmo caractere: decisivo de um lado, inerte do outro.

Limitações honestas

Isto compara, não constrói. Diz se um caminho seria enviado ao builder; não sabe se o arquivo existe, quanto o seu contexto realmente pesa nem o que o seu Dockerfile faz com nada disso. O Dockerfile e o próprio .dockerignore são sempre enviados, digam o que disserem os padrões, porque o builder precisa deles.

Os caminhos são tratados como separados por barras normais, que é com o que o builder de Linux trabalha. O comportamento reproduzido aqui é o do comparador do próprio Docker, e vale dizer com todas as letras: não existe especificação deste formato. O comparador é a definição, e a documentação não chega a descrevê-lo — os documentos citam uma função da biblioteca padrão do Go cujas regras de padrão não têm curinga recursivo algum, enquanto a implementação compila cada padrão para uma expressão regular e admite um. Vinte e três dos casos de teste da própria implementação de referência dependem desse comportamento.

Há uma regra que parece uma diferença e não é. O Docker passa os colchetes direto para uma expressão regular, então uma classe de caracteres é negada com um acento circunflexo em vez do ponto de exclamação que um glob de shell usaria; só que o git também aceita o circunflexo, de modo que as duas grafias se comportam igual dos dois lados. Está aqui porque é o óbvio de supor, e supor isso seria um erro.

Por fim, um comentário só conta como comentário quando a cerquilha é o primeiríssimo caractere da linha. Coloque um único espaço antes e ela deixa de ser comentário para virar um padrão que casa com um arquivo daquele nome. Essa ordem vem direto da implementação de referência, que procura a cerquilha antes de aparar os espaços.

Por que é grátis?

Comparar um caminho com uma lista de padrões são algumas centenas de linhas de manipulação de strings, e o seu navegador faz isso enquanto você digita. Nenhum servidor vê o seu arquivo, então não há nada a medir nem conta a criar.

Nada é enviado. O que você colar fica nesta aba.