Hoje encontrei uma situação inesperada ao usar COPY para copiar uma pasta ao escrever um dockerfile. Registre o uso correto aqui.
Informações básicas
Hoje, quando copiei a pasta para a imagem através do dockerfile, descobri que o conteúdo da pasta foi copiado para ela.
O dockerfile é o seguinte:
1 2 3 4 5 |
FROM node:alpine WORKDIR /usr/src/app COPY dist node_modules package.json ./ EXPOSE 3000 CMD ["yarn", "start:prod"] |
Quero copiar as pastas dist e node_modules para a imagem, mas não quero usar vários COPYs para copiá-los separadamente, o que criará uma camada extra. Descobriu-se que as próprias pastas dist e node_modules não foram copiadas para a imagem, mas o conteúdo das pastas foi copiado para a imagem, respectivamente.
Depois de testar foi encontrado:
ADD
comando eCOPY
comando se comportam de forma consistente ao copiar arquivosCOPY/ADD
Se a origem do comando for uma pasta, o conteúdo da pasta será copiado em vez dele mesmo.- Usar
*
a correspondência de todos os arquivos também manterá a lógica acima se uma pasta for encontrada, ou seja, apenas o conteúdo será copiado
Esta lógica é muito estranha e inconsistente com as nossas expectativas gerais.
Descobri que alguém já havia feito uma pergunta semelhante há seis anos e parece que não há intenção de alterá-la.
Implementação
Aqui estão alguns métodos para sua referência.
Copie uma única pasta, especifique o diretório de destino
Um método é copiar uma pasta por vez e, em seguida, especificar o diretório específico na imagem ao COPIAR, por exemplo, altere o dockerfile acima para este:
1 2 3 4 5 6 7 |
FROM node:alpine WORKDIR /usr/src/app COPY dist ./dist COPY node_modules ./node_modules COPY package.json ./ EXPOSE 3000 CMD ["yarn", "start:prod"] |
Copie para outra pasta
O método de escrita acima é muito problemático e também aumentará o número de camadas. Aqui pensei num método disfarçado, que não é muito elegante.
Isso consiste em colocar todas as pastas que precisam ser copiadas em uma pasta unificada e, em seguida, copiar essa pasta no dockerfile e a estrutura de diretórios na pasta pode ser mantida.
1 |
mkdir dockerPackages && mv dist node_modules dockerPackages |
1 2 3 4 5 |
FROM node:alpine WORKDIR /usr/src/app COPY dockerPackages package.json ./ EXPOSE 3000 CMD ["yarn", "start:prod"] |
Utilizando arquivos .dockerignore
Nosso método de escrita acima é, na verdade, como realizar uma coisa, ou seja, copiar apenas parte do conteúdo para a imagem e depois ignorar o outro conteúdo. Desta forma, podemos usar .dockerignore
arquivos para implementá-lo de forma mais elegante. Ignore todos os arquivos primeiro e depois exclua os arquivos que precisamos copiar.
.dockerignore
:
1 2 3 4 |
* !dist !node_modules !package.json |
1 2 3 4 5 6 |
FROM node:alpine WORKDIR /usr/src/app COPY . ./ EXPOSE 3000 CMD ["fio", "start:prod"] |
referência:
Comando Dockerfile COPY para copiar a pasta | Basta se contentar com a situação