Estou aprendendo o Docker e tenho dúvidas sobre quando e onde usar ADD
eVOLUME
. Aqui está o que eu acho que ambos fazem:
ADICIONAR
Copie os arquivos para a imagem no momento da construção. A imagem contém todos os arquivos para que você possa implantar com muita facilidade. Por outro lado, a necessidade de construir todas as vezes não parece uma boa ideia no desenvolvimento porque a construção requer que o desenvolvedor execute um comando para reconstruir o contêiner; além disso, construir o contêiner pode ser demorado.
VOLUME
Eu entendo que usando docker run -v
você pode montar uma pasta de host dentro do seu contêiner, desta forma, você pode facilmente modificar os arquivos e ver o aplicativo no seu contêiner reagir às mudanças. Parece ótimo em desenvolvimento, mas não tenho certeza de como implantar meus arquivos dessa maneira.
COPY
aADD
. Eles são quase iguais, masADD
têm algumas habilidades extras para escrever URLs e arquivos compactados que podem ser surpreendentes.Respostas:
ADICIONAR
A diferença fundamental entre esses dois é que
ADD
tudo o que você está adicionando, seja uma pasta ou apenas um arquivo, realmente faz parte da imagem . Qualquer pessoa que usar a imagem que você construiu depois terá acesso a tudo que você quiserADD
. Isso é verdadeiro mesmo se você removê-lo posteriormente, porque o Docker funciona em camadas e aADD
camada ainda existirá como parte da imagem. Para ser claro, você só precisa fazerADD
algo em tempo de construção e nunca maisADD
em tempo de execução.Alguns exemplos de casos em que você deseja usar
ADD
:ADD ./requirements.txt /requirements.txt
seguido porRUN pip install -r /requirements.txt
Você deseja usar o código do seu aplicativo como contexto no Dockerfile, por exemplo, se quiser definir o diretório do aplicativo como o diretório de trabalho na sua imagem e ter o comando padrão em um contêiner executado a partir da sua imagem realmente executar o seu aplicativo, você pode fazer:
ADD ./ /usr/local/git/my_app
WORKDIR /usr/local/git/my_app
CMD python ./main.py
VOLUME
O volume, por outro lado, permite que um contêiner executado a partir de sua imagem tenha acesso a algum caminho em qualquer máquina local em que o contêiner esteja sendo executado. Você não pode usar arquivos do seu
VOLUME
diretório no Dockerfile . Qualquer coisa em seu diretório de volume não estará acessível em tempo de compilação, mas estará acessível em tempo de execução .Alguns exemplos de casos em que você deseja usar
VOLUME
:/var/log/my_app
. Você deseja que esses logs estejam acessíveis na máquina host e não sejam excluídos quando o contêiner for removido. Você pode fazer isso criando um ponto de montagem em/var/log/my_app
adicionandoVOLUME /var/log/my_app
ao Dockerfile e, em seguida, executando o contêiner comdocker run -v /host/log/dir/my_app:/var/log/my_app some_repo/some_image:some_tag
VOLUME /etc/settings/my_app_settings
ao seu Dockerfile, executar seu contêiner comdocker run -v /host/settings/dir:/etc/settings/my_app_settings some_repo/some_image:some_tag
e certificar-se de que / host / settings / dir existe em todos os ambientes que você espera que seu aplicativo seja executado.fonte
docker run -v $HOST_PATH:$CONTAINER_PATH node:latest node $CONTAINER_PATH/app.js
.A
VOLUME
instrução cria um volume de dados em seu contêiner do Docker no tempo de execução. O diretório fornecido como um argumento paraVOLUME
é um diretório que ignora o Union File System e é usado principalmente para dados persistentes e compartilhados.Se você executar
docker inspect <your-container>
, verá naMounts
seção que há umSource
que representa o local do diretório no host e umDestination
que representa o local do diretório montado no contêiner. Por exemplo,Aqui estão três casos de uso para
docker run -v
:docker run -v /data
: Isso é análogo a especificar aVOLUME
instrução em seu Dockerfile.docker run -v $host_path:$container_path
: Isso permite que você monte a$host_path
partir de seu host$container_path
em seu contêiner durante o tempo de execução. No desenvolvimento, isso é útil para compartilhar o código-fonte em seu host com o contêiner. Na produção, isso pode ser usado para montar coisas como as informações de DNS do host (encontradas em/etc/resolv.conf
) ou segredos no contêiner. Por outro lado, você também pode usar essa técnica para gravar os logs do contêiner em pastas específicas no host. Ambos$host_path
e$container_path
devem ser caminhos absolutos.docker run -v my_volume:$container_path
: Isso cria um volume de dados em seu contêiner em$container_path
e nomeia-omy_volume
. É essencialmente o mesmo que criar e nomear um volume usandodocker volume create my_volume
. Nomear um volume como este é útil para um volume de dados de contêiner e um volume de armazenamento compartilhado usando um driver de armazenamento de vários hosts como o Flocker .Observe que a abordagem de montar uma pasta de host como um volume de dados não está disponível no Dockerfile. Para citar a documentação do docker ,
Agora, se você deseja copiar seus arquivos para contêineres em ambientes que não sejam de desenvolvimento, você pode usar as instruções
ADD
ouCOPY
em seu Dockerfile. Eles são o que eu geralmente uso para implantação de não desenvolvimento.fonte
ADD
instrução em seu Dockerfile, já que ela é executada apenas pelodocker build
comando. Isso é necessário quando outros constroem seu contêiner pela primeira vez e quando você está pronto para implantá-lo em outros ambientes de não desenvolvimento.-v
comando para desenvolvimento, e fazer com que outro arquivo docker criasse uma imagem que inclui os arquivosADD
para implantação?ADD
? Alguns segundos no total? Se você tiver dois arquivos Dockerfile e os compartilhar com outras pessoas (ou publicá-los no registro do docker ), qual é o padrão? Você terá alguma sobrecarga de manutenção extra para garantir que o Dockerfile padrão certo chegue aos usuários certos. Mas no final do dia, você decide o que funciona melhor para você. Pessoalmente, gosto de garantir que haja um e apenas um Dockerfile para construir meu contêiner.