Qual é a maneira certa de adicionar dados a um volume nomeado existente no Docker?


88

Eu estava usando o Docker da maneira antiga, com um contêiner de volume:

docker run -d --name jenkins-data jenkins:tag echo "data-only container for Jenkins"

Mas agora mudei para a nova forma criando um volume nomeado:

 docker volume create --name my-jenkins-volume 

Amarrei este novo volume a um novo recipiente Jenkins. A única coisa que deixei é uma pasta na qual tenho o /var/jenkins_homedo meu contêiner jenkins anterior. (usando docker cp) Agora, quero preencher meu novo volume nomeado com o conteúdo dessa pasta.

Posso apenas copiar o conteúdo dessa pasta para /var/lib/jenkins/volume/my-jenkins-volume/_data?

Respostas:


134

Certamente, você pode copiar os dados diretamente para o /var/lib/docker/volumes/my-jenkins-volume/_data, mas ao fazer isso você:

  • Contando com acesso físico ao host docker. Essa técnica não funcionará se você estiver interagindo com uma API docker remota.

  • Depender de um aspecto específico da implementação do volume poderia mudar no futuro, interrompendo todos os processos que você possui e que dependem dele.

Acho que é melhor você confiar nas coisas que pode realizar usando a API do Docker, por meio do cliente de linha de comando. A solução mais fácil é provavelmente usar um contêiner auxiliar, algo como:

docker run -v my-jenkins-volume:/data --name helper busybox true
docker cp . helper:/data
docker rm helper

3
Com relação ao segundo marcador, você pode executar docker volume inspect my-jenkins-volume --format '{{.Mountpoint}}'para obter sua localização física de forma programática. Ainda assim, não parece uma boa ideia.
— c24w

8
Este contêiner auxiliar nunca precisa realmente ser executado. Seria suficiente simplesmente criá-lo, executá-lo docker cpe removê-lo.
— Alex

Você não pode executar nesse contêiner para ver os resultados ou modificar os arquivos manualmente.
— CodeOrElse 01 de

3
Observe que a listagem /var/lib/docker/volumes/my-jenkins-volume/_dataao usar o Docker para Mac não funciona porque os arquivos são armazenados dentro da máquina virtual xhyve . Consulte forum.docker.com/t/var-lib-docker-does-not-exist-on-host/18314
— Ortomala Lokni

1
— Zuabi

32

Você pode reduzir a resposta aceita a uma linha usando, por exemplo,

docker run --rm -v `pwd`:/src -v my-jenkins-volume:/data busybox cp -r /src /data

1
estou me perguntando se a natureza transitória de / tmp pode representar um risco de o contêiner possivelmente deletar seus dados antes que o cp seja concluído? pathname.com/fhs/pub/fhs-2.3.html#TMPTEMPORARYFILES
— thurt

1
O link realmente não esclarece a vida útil dos arquivos em / tmp. Eu declara: "Os programas não devem presumir que quaisquer arquivos ou diretórios em / tmp sejam preservados entre as invocações do programa." o que implica que os arquivos sobreviveriam, mas isso é uma garantia. A opção -v para docker criará um diretório no contêiner se ele não existir, portanto, alterar / tmp / src para / src funcionará se você estiver preocupado com essa condição de corrida em potencial. Vou editar a resposta para refletir isso, já que não há nenhuma desvantagem.
— headdab de

3
não -v `pwd`:/srcsignifica que o comando está sendo executado no host? (Como o host pode mapear pwdse for uma máquina diferente, por exemplo? - não pode.) Se o comando docker não estiver sendo executado no host, isso não funciona. Eu acredito que é por isso que temos docker cp. Parece que não é "o caminho" para o docker - é apenas um caso especial que funciona apenas quando o comando docker está em execução no host. Eu compreendo corretamente?
— Wyck

Sim, acho que você está certo. pwddeve resolver para um arquivo na máquina host. Da documentação de montagem do docker: "No caso de montagens de ligação, o primeiro campo é o caminho para o arquivo ou diretório na máquina host."
— headdab de

1
Portanto, isso não funciona para copiar seus arquivos locais para o contêiner se estiver em um host remoto, pois você está montando, pwdque nem mesmo precisa existir no host remoto. Em vez disso, a solução de Dmytro Melnychuk (create + cp + rm) copia os locais para o contêiner, não importa onde esteja sendo executado.
— Xavi Montero

25

Você não precisa iniciar algum contêiner para adicionar dados a um volume nomeado já existente, apenas crie um contêiner e copie os dados nele:

docker container create --name temp -v my-jenkins-volume:/data busybox
docker cp . temp:/data
docker rm temp

2
Desde que o conteúdo do busybox não seja realmente necessário; você pode fazer isso com hello-worlde também funciona. busyboxé 1,22 MB. Em vez disso, hello-worldsão 13,3 kB. A questão é: da mesma forma que podemos fazer um Dockerfile DO zero, poderíamos fazer uma "criação de contêiner docker" com "nada" como a imagem, pois queremos apenas "montar" o volume e nunca iniciar o contêiner?
— Xavi Montero

1
+1 para esta solução acima dos votados, mas a sintaxe correta para docker cpédocker cp [OPTIONS] CONTAINER:SRC_PATH DEST_PATH
— Marco Dufal

3

Aqui estão as etapas para copiar o conteúdo de ~ / data para o volume do docker chamado my-vol

Etapa 1. Anexe o volume a um recipiente "temporário". Para que execute no terminal este comando:

docker run --rm -it --name alpine --mount type=volume,source=my-vol,target=/data alpine

Etapa 2. Copie o conteúdo de ~ / data em my-vol . Para isso, execute estes comandos na nova janela do terminal:

cd ~/data docker cp . alpine:/data

Isso copiará o conteúdo de ~ / data para o volume my-vol . Após a cópia, saia do contêiner temporário.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.