Como copiar imagens do Docker de um host para outro sem usar um repositório

1375

Como transfiro uma imagem do Docker de uma máquina para outra sem usar um repositório, independentemente de privado ou público?

Crio minha própria imagem no VirtualBox e, quando termina, tento implantar em outras máquinas para ter um uso real.

Como é baseado em minha própria imagem (como o Red Hat Linux), não pode ser recriado a partir de um Dockerfile. Meu arquivo docker não é facilmente portátil.

Existem comandos simples que posso usar? Ou outra solução?

Larry Cai
fonte

Respostas:

2310

Você precisará salvar a imagem do Docker como um arquivo tar:

docker save -o <path for generated tar file> <image name>

Em seguida, copie sua imagem para um novo sistema com ferramentas regulares de transferência de arquivos, como cp, scpou rsync(preferencial para arquivos grandes). Depois disso, você precisará carregar a imagem no Docker:

docker load -i <path to image tar file>

PS: Você pode precisar de sudotodos os comandos.

EDIT: você deve adicionar o nome do arquivo (não apenas o diretório) com -o, por exemplo:

docker save -o c:/myfile.tar centos:16
Daiwei
fonte
27
Esta é a melhor resposta para imagens .
295 Andy
26
Além disso, é melhor usar repo:tagcomo referência de imagem do que image id. Se você usar image id, a imagem carregada não reterá a etiqueta (e você precisará executar outra etapa para marcar a imagem).
wisbucky
1
Usei o ID da imagem em vez do nome: tag Agora estou sentado aqui, carreguei a imagem e tenho um <nenhum> para REPOSITORY e TAG. Qual é a maneira correta de trazer o nome e a marca de volta? @wisbucky
Ulfhetnar
3
Para marcar, primeiro identifique o ID de IMAGEM usando docker imagese depois use docker tag DESIREDIMAGEID mycompany/myreponame. Se o ID da sua imagem for 591de551d6e4, você poderá abreviar o ID da imagem:docker tag 59 mycompany/myreponame
Junior Mayhé 15/08/1918
@AndiJay Veja Como copiar imagens do docker de um host para outro?
Duct_tape_coder 14/02/19
582

Transferindo uma imagem do Docker via SSH, compactando o conteúdo rapidamente:

docker save <image> | bzip2 | \
     ssh user@host 'bunzip2 | docker load'

Também é uma boa ideia colocar pvno meio do canal para ver como está a transferência:

docker save <image> | bzip2 | pv | \
     ssh user@host 'bunzip2 | docker load'

(Mais informações sobre pv: página inicial , página de manual ).

Kolypto
fonte
19
Ao usar a docker-machine, você pode docker $(docker-machine config mach1) save <image> | docker $(docker-machine config mach2) loadcopiar imagens entre as máquinas mach1 e mach2 .
matlehmann
5
O @manojlds eval $(docker-machine env dev)é bom para comunicação geral com um único host docker, mas não para copiar entre duas máquinas, pois isso envolve dois hosts / máquinas docker diferentes.
matlehmann
14
para fazer isso de forma inversa (remota para local):ssh target_server 'docker save image:latest | bzip2' | pv | bunzip2 | docker load
ThorSummoner 01/02
2
Existe alguma maneira de fazer isso quando o docker requer sudo na máquina de destino? Eu tentei (sem compressão) docker save my_img:v1 | ssh -t -t my_user@my_machine sudo docker load. Sem a opção "-t", o sudo reclama o sudo: desculpe, você deve ter um tty para executar o sudo ; com um "-t" é a mesma mensagem porque o ssh diz que o pseudo-terminal não será alocado porque stdin não é um terminal. e finalmente, com dois "-t" s, recebo o conteúdo do arquivo tar (ou seja, a imagem) no meu terminal. Alguma ideia?
Fome
1
@ JosefStark Eu precisava adicionar "Padrões: <nome de usuário alvo>! Requiretty" ao editar o arquivo sudoers para parar a mensagem "Desculpe" do sudo. Não sei quanta diferença isso faz, mas também coloco tudo após o usuário @ host entre aspas (então "[...] | ssh usuário @ host 'bunzip2 | sudo docker load'").
precisa
99

Para salvar uma imagem em qualquer caminho de arquivo ou local NFS compartilhado, consulte o exemplo a seguir.

Obtenha o ID da imagem fazendo:

sudo docker images

Digamos que você tenha uma imagem com o ID "dados da matriz".

Salve a imagem com o ID:

sudo docker save -o /home/matrix/matrix-data.tar matrix-data

Copie a imagem do caminho para qualquer host. Agora importe para a instalação local do Docker usando:

sudo docker load -i <path to copied image file>
Sohan
fonte
34

Primeiro salve a imagem do Docker em um arquivo zip:

docker save <docker image name> | gzip > <docker image name>.tar.gz

Em seguida, carregue a imagem exportada no Docker usando o comando abaixo:

zcat <docker image name>.tar.gz | docker load
Damodaran
fonte
11
Para carregar, docker load < my-image.tar.gzé suficiente. A imagem é descompactada automaticamente para gzip, bzip2 e xz.
Flux
32

Corre

docker images

para ver uma lista das imagens no host. Digamos que você tenha uma imagem chamada awesomesauce . No seu terminal, cdpara o diretório para o qual deseja exportar a imagem. Agora execute:

docker save awesomesauce:latest > awesomesauce.tar

Copie o arquivo tar para um pen drive ou qualquer outra coisa e depois copie-o para o novo computador host.

Agora, a partir do novo host, faça:

docker load < awesomesauce.tar

Agora vá tomar um café e leia o Hacker News ...

Neil Girardi
fonte
4
Vale a pena notar aqui que isso só funcionará se salvar e carregar forem executados no mesmo sistema operacional. Use docker save [image] -o file.tare docker load -i file.tarpara evitar isso!
Andreas Forslöw 11/06/19
docker save [image] -o file.tartambém parece ser muito mais rápido
ti7 25/02
19

Para uma exportação nivelada do sistema de arquivos de um contêiner, use;

docker export CONTAINER_ID > my_container.tar

Use cat my_container.tar | docker import -para importar a imagem.

Panagiotis Moustafellos
fonte
9
será que cat my_container.tar | docker import - my_container:new, se a importação de acordo localmente para cmd ajuda
Larry Cai
7
Isso é mais para fazer backup de um contêiner em execução do que para implantar uma imagem.
Kousha
15

Ao usar a docker-machine, você pode copiar imagens entre máquinas mach1e mach2com:

docker $(docker-machine config <mach1>) save <image> | docker $(docker-machine config <mach2>) load

E é claro que você também pode ficar pvno meio para obter um indicador de progresso:

docker $(docker-machine config <mach1>) save <image> | pv | docker $(docker-machine config <mach2>) load

Você também pode omitir uma das docker-machine configsubconchas, para usar o docker-host padrão atual.

docker save <image> | docker $(docker-machine config <mach>) load

copiar a imagem do docker-host atual para mach

ou

docker $(docker-machine config <mach>) save <image> | docker load

copiar machpara o docker-host atual.

Matlehmann
fonte
10

Suponho que você precise salvar o couchdb-cartridgeque possui um ID de imagem 7ebc8510bc2c:

stratos@Dev-PC:~$ docker images
REPOSITORY                             TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
couchdb-cartridge                      latest              7ebc8510bc2c        17 hours ago        1.102 GB
192.168.57.30:5042/couchdb-cartridge   latest              7ebc8510bc2c        17 hours ago        1.102 GB
ubuntu                                 14.04               53bf7a53e890        3 days ago          221.3 MB

Salve a imagem archiveName em um arquivo tar. Vou usar o /media/sf_docker_vm/para salvar a imagem.

stratos@Dev-PC:~$ docker save imageID > /media/sf_docker_vm/archiveName.tar

Copie o arquivo archiveName.tar à sua nova instância Docker usando qualquer método funciona em seu ambiente, por exemplo FTP, SCP, etc.

Execute o docker loadcomando em sua nova instância do Docker e especifique o local do arquivo tar da imagem.

stratos@Dev-PC:~$ docker load < /media/sf_docker_vm/archiveName.tar

Por fim, execute o docker imagescomando para verificar se a imagem está disponível agora.

stratos@Dev-PC:~$ docker images
REPOSITORY                             TAG        IMAGE ID         CREATED             VIRTUAL SIZE
couchdb-cartridge                      latest     7ebc8510bc2c     17 hours ago        1.102 GB
192.168.57.30:5042/couchdb-cartridge   latest     bc8510bc2c       17 hours ago        1.102 GB
ubuntu                                 14.04      4d2eab1c0b9a     3 days ago          221.3 MB

Por favor, encontre este post detalhado .

tk_
fonte
10

Para transferir imagens da instalação local do Docker para uma VM do minikube:

docker save <image> | (eval $(minikube docker-env) && docker load)
Bryan Larsen
fonte
10

docker-push-ssh é um utilitário de linha de comando que criei apenas para esse cenário.

Ele configura um registro Docker privado temporário no servidor, estabelece um encapsulamento SSH a partir do host local, empurra a imagem e depois limpa.

O benefício dessa abordagem docker save(no momento em que a maioria das respostas está sendo escrita neste método) é que apenas as novas camadas são enviadas ao servidor, resultando em um upload MUITO mais rápido.

Muitas vezes, usar um registro intermediário como o dockerhub é indesejável e complicado.

https://github.com/brthor/docker-push-ssh

Instalar:

pip install docker-push-ssh

Exemplo:

docker-push-ssh -i ~/my_ssh_key [email protected] my-docker-image

A maior ressalva é que você deve adicionar manualmente seu host local à insecure_registriesconfiguração do Docker . Execute a ferramenta uma vez e isso fornecerá um erro informativo:

Error Pushing Image: Ensure localhost:5000 is added to your insecure registries.
More Details (OS X): /programming/32808215/where-to-set-the-insecure-registry-flag-on-mac-os

Onde devo definir o sinalizador '--insecure-registry' no Mac OS?

Brthornbury
fonte
1
Editei sua resposta para deixar claro que o utilitário que você está recomendando foi criado por você. Veja esta página , em particular: "Publique respostas boas e relevantes e, se algumas (mas não todas) forem sobre o seu produto ou site, tudo bem. No entanto, você deve divulgar sua afiliação nas suas respostas".
Louis
8

Todas as outras respostas são muito úteis. Acabei de passar pelo mesmo problema e descobri uma maneira fácil docker machine scp.

Desde o Docker Machine v0.3.0, o scp foi introduzido para copiar arquivos de um computador Docker para outro. Isso é muito conveniente se você deseja copiar um arquivo do computador local para uma máquina Docker remota, como AWS EC2 ou Digital Ocean, porque a Docker Machine está cuidando das credenciais SSH para você.

  1. Salve suas imagens usando docker savecomo:

    docker save -o docker-images.tar app-web
    
  2. Copiar imagens usando o docker-machine scp

    docker-machine scp ./docker-images.tar remote-machine:/home/ubuntu
    

Suponha que sua máquina remota do Docker seja remote-machinee o diretório em que você deseja que o arquivo tar seja /home/ubuntu.

  1. Carregar a imagem do Docker

    docker-machine ssh remote-machine sudo docker load -i docker-images.tar
    
Peng
fonte
5
por que não apenas 'scp <source> <remote>'?
Tamas Kalman
3

Quero mover todas as imagens com tags.

```
OUT=$(docker images --format '{{.Repository}}:{{.Tag}}')
OUTPUT=($OUT)
docker save $(echo "${OUTPUT[*]}") -o /dir/images.tar
``` 

Explicação:

Primeiro OUTobtém todas as tags, mas separadas por novas linhas. Segundo OUTPUTobtém todas as tags em uma matriz. Terceiro, $(echo "${OUTPUT[*]}")coloca todas as tags para um único docker savecomando, para que todas as imagens estejam em um único tar.

Além disso, isso pode ser compactado usando o gzip. No destino, execute:

tar xvf images.tar.gz -O | docker load

-Oopção para tarcolocar o conteúdo em stdin que pode ser acessado docker load.

Vikram
fonte
2

Você pode usar sshfs:

$ sshfs user@ip:/<remote-path> <local-mount-path>
$ docker save <image-id> > <local-mount-path>/myImage.tar
Chu
fonte
1

Script para executar a função de salvar e carregar do Docker (testado e testado):

Docker Salvar:

#!/bin/bash

#files will be saved in the dir 'Docker_images'
mkdir Docker_images
cd Docker_images
directory=`pwd`
c=0
#save the image names in 'list.txt'
doc= docker images | awk '{print $1}' > list.txt
printf "START \n"
input="$directory/list.txt"
#Check and create the image tar for the docker images
while IFS= read -r line
do
     one=`echo $line | awk '{print $1}'`
     two=`echo $line | awk '{print $1}' | cut -c 1-3`
     if [ "$one" != "<none>" ]; then
             c=$((c+1))
             printf "\n $one \n $two \n"
             docker save -o $two$c'.tar' $one
             printf "Docker image number $c successfully converted:   $two$c \n \n"
     fi
done < "$input"

Carga do Docker:

#!/bin/bash

cd Docker_images/
directory=`pwd`
ls | grep tar > files.txt
c=0
printf "START \n"
input="$directory/files.txt"
while IFS= read -r line
do
     c=$((c+1))
     printf "$c) $line \n"
     docker load -i $line
     printf "$c) Successfully created the Docker image $line  \n \n"
done < "$input"
Syed Faraz Umar
fonte
0

Você pode usar uma linha com a DOCKER_HOSTvariável:

docker save app:1.0 | gzip | DOCKER_HOST=ssh://user@remotehost docker load
vitalets
fonte