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?

DenCowboy
fonte

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
larsks
fonte
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
True é explicado aqui stackoverflow.com/questions/29762231/…
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
headdab
fonte
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
Dmytro Melnychuk
fonte
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.

Namik Hajiyev
fonte