Perco meus dados quando o contêiner sai

394

Apesar do tutorial interativo e das perguntas frequentes do Docker, perco meus dados quando o contêiner sai.

Instalei o Docker como descrito aqui: http://docs.docker.io/en/latest/installation/ubuntulinux sem nenhum problema no ubuntu 13.04.

Mas perde todos os dados quando sai.

iman@test:~$ sudo docker version
Client version: 0.6.4 
Go version (client): go1.1.2 
Git commit (client): 2f74b1c 
Server version: 0.6.4 
Git commit (server): 2f74b1c 
Go version (server): go1.1.2 
Last stable version: 0.6.4 


iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:05:47 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu apt-get install ping
Reading package lists... 
Building dependency tree... 
The following NEW packages will be installed: 
  iputils-ping 
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded. 
Need to get 56.1 kB of archives. 
After this operation, 143 kB of additional disk space will be used. 
Get:1 http://archive.ubuntu.com/ubuntu/ precise/main iputils-ping amd64 3:20101006-1ubuntu1 [56.1 kB] 
debconf: delaying package configuration, since apt-utils is not installed 
Fetched 56.1 kB in 0s (195 kB/s) 
Selecting previously unselected package iputils-ping. 
(Reading database ... 7545 files and directories currently installed.) 
Unpacking iputils-ping (from .../iputils-ping_3%3a20101006-1ubuntu1_amd64.deb) ... 
Setting up iputils-ping (3:20101006-1ubuntu1) ... 
iman@test:~$ sudo docker run ubuntu ping
2013/10/25 08:06:11 Unable to locate ping 
iman@test:~$ sudo docker run ubuntu touch /home/test
iman@test:~$ sudo docker run ubuntu ls /home/test
ls: cannot access /home/test: No such file or directory 

Também testei com sessões interativas com o mesmo resultado. Eu esqueci alguma coisa?

EDIT: IMPORTANTE PARA NOVOS USUÁRIOS DE DOCKER

Como @ mohammed-noureldin e outros disseram, na verdade, este NÃO é um contêiner saindo . Sempre que cria apenas um novo contêiner.

iman
fonte
10
Isso não pode ser chamado de " saída de contêiner ", você está apenas criando um novo contêiner, usar a palavra sair pode confundir muito (fiquei confuso por causa disso também).
Mohammed Noureldin
11
@MohammedNoureldin, você está certo, sair não está correto, mas é exatamente isso que você, eu e outros pensamos. Portanto, é uma palavra melhor em questão, sua edição faz da pergunta uma resposta! Os novos pesquisadores não encontrarão aqui!
Iman
No meu ponto de partida com o Docker, pensei que, por causa da SUA pergunta, acho que o endereço é simplesmente ERRADO. o novo título foi revisado e aceito, não entendo por que alguém deveria insistir em um título errado, é sua pergunta e sua decisão.
Mohammed Noureldin
3
Eu concordo com @MohammedNoureldin. A combinação do título específico, exemplo e resposta aceita não ajuda os futuros leitores e, principalmente, os iniciantes a entender Docker. Eu proporia manter o título e a pergunta original, já que os iniciantes definitivamente procurarão algo assim. Mas, por que você não adiciona algo que descreve seus conceitos errados no momento em que escreveu o post? Isso ajudará a esclarecer as coisas. Esta é a nossa cultura aqui na SO ... não é? :-)
tgogos 24/06
2
Eu tive esse problema ... toda vez que você sai, tem que iniciar seu contêiner, não executá-lo ... executar uma imagem novamente, criar um novo contêiner, isso ajudará o docker a iniciar o <ID do contêiner> o docker anexar o <ID do contêiner>
fatemeh

Respostas:

399

Você precisa confirmar as alterações feitas no contêiner e depois executá-lo. Tente o seguinte:

sudo docker pull ubuntu

sudo docker run ubuntu apt-get install -y ping

Em seguida, obtenha o ID do contêiner usando este comando:

sudo docker ps -l

Confirme as alterações no contêiner:

sudo docker commit <container_id> iman/ping 

Em seguida, execute o contêiner:

sudo docker run iman/ping ping www.google.com

Isso deve funcionar.

Unferth
fonte
9
Portanto, devo usar o commit após cada execução para preservar os dados.
Iman
5
A confirmação deve ser usada apenas quando você fizer ALTERAÇÕES no contêiner (como instalar novas ferramentas ou dados) para que essas alterações sejam salvas e na próxima vez em que você executar um novo contêiner nessa Imagem, ele começará a partir do ponto da última salva ou confirmar, preservando seus dados.
Unferth
7
@ Unferth e se eu quiser continuar fazendo alterações? Até agora, ele cria mais imagens <none>. Como continuo anexando o commit em cima de uma imagem existente?
Marconi
62
Confirmar alterações de forma incremental não é "o caminho do docker". Use um DOCKERFILE.
user2105103
23
Como você se comprometeria de dentro do contêiner? Considere o seguinte cenário: 1) Estou executando o contêiner assim: docker run -i -t myimage / bin / bash 2) Eu faço algumas alterações 3) Não consigo confirmar de dentro do contêiner; portanto, quando saio do contêiner, vai perder todos os meus dados, sem ter a chance de comprometer as minhas alterações anteriores
qgicup
374

Quando você usa docker runpara iniciar um contêiner, ele realmente cria um novo contêiner com base na imagem que você especificou.

Além das outras respostas úteis aqui, observe que você pode reiniciar um contêiner existente depois que ele sair e suas alterações ainda estiverem lá.

docker start f357e2faab77 # restart it in the background
docker attach f357e2faab77 # reattach the terminal & stdin
ZeissS
fonte
88
docker psmostra apenas a execução de contêineres de docker. docker ps -amostra também os que saíram - e que você pode continuar correndo. Uma confirmação é necessária apenas após cada execução, se você quiser fazer uma captura instantânea para uso futuro, caso contrário, o próprio contêiner permanecerá para você continuar usando.
user1278519
2
Pergunta, por favor, se eu baixar uma jenkinsjanela de encaixe do servidor e executá-la no meu host ci e executar alguns trabalhos que possuo, como resultado, o servidor jenkins anota alguns registros em disco. agora, se meu servidor (que hospedava minha janela de encaixe) for reiniciado e eu reiniciar minha janela de encaixe jenkins, isso significa que perdi todos os arquivos de log? se é assim, como posso usar o jenkinsdocker, por exemplo, para facilitar minha instalação de jenkins no CI?
Tg
2
@ Jas Se você se ater ao mesmo contêiner e não criar novos, não há problemas. Atualmente, o Docker possui políticas de reinicialização, para que você possa configurá-lo para reiniciar o mesmo contêiner na reinicialização da máquina. Também aconselho que você coloque seu jenkins em um volume para poder acessá-lo de fora (backups, etc.).
ZeissS 23/02
7
Aqui está uma maneira útil para copiar arquivos para fora do recipiente uma vez que você sair:docker cp $(docker ps -alq):/path/to/file .
Josh Habdas
3
você também pode iniciar e anexar um contêiner pelo nome. (eg docker run -it --name my_debian debiane depois docker start my_debian && docker attach my_debian)
Johnny Willer
128

Existem as seguintes maneiras de manter os dados do contêiner:

  1. Volumes do Docker

  2. Confirmação do Docker

    a) crie um container a partir da imagem do ubuntu e execute um terminal bash.

       $ docker run -i -t ubuntu:14.04 /bin/bash
    

    b) Dentro do terminal, instale o enrolamento

       # apt-get update
       # apt-get install curl
    

    c) Saia do terminal de contêineres

       # exit
    

    d) Anote o ID do seu contêiner executando o seguinte comando:

       $ docker ps -a
    

    e) salvar o container como nova imagem

       $ docker commit <container_id> new_image_name:tag_name(optional)
    

    f) verifique se você pode ver sua nova imagem com o curl instalado.

       $ docker images           
    
       $ docker run -it new_image_name:tag_name bash
          # which curl
            /usr/bin/curl
    
Kalyani Chaudhari
fonte
É necessário exitantes docker commit? Obrigado.
Abhishek Anand
2
@AbhishekAnand sim, porque com o docker runcomando você executa o bash no contêiner e fica lá devido às opções -ie -t(interativas com o TTY). No entanto, o Docker é executado em sua máquina, fora do contêiner, portanto, depois de fazer as alterações necessárias no contêiner a partir do interior, para retornar ao shell do sistema, você precisa exit(ou Ctrl + D) o shell do contêiner. Além disso, observe o #e $na resposta, que indicam as diferentes conchas os comandos são gravados.
Erik
Pergunta rápida: se eu não confirmar, perdi os dados. Está claro. Mas quando altero a configuração do nginx, por que ele permanece atualizado? (não é necessário confirmar) @Erik
grep
@grep, se você tiver um MWE claro e reproduzível, faça uma nova pergunta, se ainda não houver um sobre este caso de uso específico.
Erik
3. docker stopseguido por docker start.
carillonator
59

Além da resposta de Unferth , é recomendável criar um Dockerfile .

Em um diretório vazio, crie um arquivo chamado "Dockerfile" com o seguinte conteúdo.

FROM ubuntu
RUN apt-get install ping
ENTRYPOINT ["ping"]

Crie uma imagem usando o Dockerfile . Vamos usar uma tag para não precisarmos lembrar o número da imagem hexadecimal.

$ docker build -t iman/ping .

E, em seguida, execute a imagem em um contêiner.

$ docker run iman/ping stackoverflow.com
saudação
fonte
11
Nunca ter que fazer isso manualmente mais de uma vez é exatamente o ponto de encaixe. Crie um arquivo docker, confirme e faça upload da imagem resultante. Puxe a imagem para frente.
precisa
11

Eu tenho uma resposta muito mais simples para sua pergunta, execute os dois comandos a seguir

sudo docker run -t -d ubuntu --name mycontainername /bin/bash
sudo docker ps -a

o comando ps -a acima retorna uma lista de todos os contêineres. Pegue o nome do container que referencia o nome da imagem - 'ubuntu'. O docker gera automaticamente nomes para os contêineres, por exemplo - 'lightlyxuyzx', se você não usar a opção --name.

As opções -t e -d são importantes, o contêiner criado é desanexado e pode ser recolocado conforme fornecido abaixo com a opção -t.

Com a opção --name, você pode nomear seu contêiner no meu caso 'mycontainername'.

sudo docker exec -ti mycontainername bash

e este comando acima ajuda a fazer login no contêiner com o bash shell. A partir deste ponto, todas as alterações feitas no contêiner são salvas automaticamente pela janela de encaixe. Por exemplo - apt-get install curldentro do contêiner É possível sair do contêiner sem problemas, a janela de encaixe salva automaticamente as alterações.

No próximo uso, tudo o que você precisa fazer é executar esses dois comandos toda vez que quiser trabalhar com esse contêiner.

Este comando Abaixo iniciará o contêiner parado:

sudo docker start mycontainername

sudo docker exec -ti mycontainername bash

Outro exemplo com portas e um espaço compartilhado dado abaixo:

docker run -t -d --name mycontainername -p 5000:5000 -v ~/PROJECTS/SPACE:/PROJECTSPACE 7efe2989e877 /bin/bash

No meu caso: 7efe2989e877 - é o imageid de um contêiner anterior em execução que eu obtive usando

docker ps -a

Magnus Melwin
fonte
4
Com o Docker 18.09.2 no Ubuntu 18.04, ele não funciona como está. Funciona se eu colocar a --nameopção e antes do nome da imagem, desta forma:docker run --name mycontainername -t -d ubuntu /bin/bash
Stéphane Gourichon 14/04/19
9

Você pode querer examinar os volumes da janela de encaixe se quiser persistir os dados em seu contêiner. Visite https://docs.docker.com/engine/tutorials/dockervolumes/ . A documentação da janela de encaixe é um ótimo ponto de partida

Kudzanayi Mutamba
fonte
3

Minha sugestão é gerenciar o docker, com o docker compor. É uma maneira fácil de gerenciar todos os contêineres do Docker para o seu projeto, você pode mapear as versões e vincular diferentes contêineres para trabalharem juntos.

Os documentos são muito simples de entender, melhores que os documentos do docker.

Documentos do Docker-Compose

Melhor

Cam T
fonte
3

Há realmente ótimas respostas acima para a pergunta feita. Pode não haver necessidade de outra resposta, mas ainda assim quero dar minha opinião pessoal sobre o assunto nas palavras mais simples possíveis.

Aqui estão alguns pontos sobre contêineres e imagens que nos ajudarão a concluir:

  • Uma imagem da janela de encaixe pode ser :
    1. criado a partir de um contêiner
    2. excluído
    3. usado para criar qualquer número de contêineres
  • Um contêiner de docker pode ser :
    1. criado a partir de uma imagem
    2. começado
    3. parado
    4. reiniciado
    5. excluído
    6. usado para criar qualquer número de imagens
  • Um comando docker run faz isso :
    1. Faz o download de uma imagem ou usa uma imagem em cache
    2. Cria um novo contêiner a partir dele
    3. Inicia o contêiner
  • Quando um Dockerfile é usado para criar uma imagem :
    1. Já é sabido que a imagem será usada para executar um contêiner de docker.
    2. Após emitir o comando docker build, o docker nos bastidores cria um contêiner em execução com um sistema de arquivos base e segue as etapas dentro do Dockerfile para configurar esse contêiner de acordo com a necessidade dos desenvolvedores.
    3. Depois que o contêiner for configurado com especificações do Dockerfile, ele será confirmado como uma imagem.
    4. A imagem está pronta para o rock and roll!

Conclusão :

Como podemos ver, um contêiner de docker é independente de uma imagem do docker.

Um contêiner pode ser reiniciado desde que o ID exclusivo desse contêiner [use docker ps --allpara obter o ID] .

Qualquer operação como criar um novo diretório, criar arquivos, instalar ferramentas etc. pode ser feita dentro do contêiner enquanto estiver em execução. Depois que o contêiner é parado, ele persiste em todas as alterações. Parar e reiniciar contêineres é como reiniciar um sistema de computador.

Um contêiner já criado está sempre disponível para reinicialização, mas quando emitimos um docker runcomando, um novo contêiner é criado a partir de uma imagem e, portanto, é como um novo sistema de computador. As alterações feitas dentro do contêiner antigo - como podemos entender agora - não estão disponíveis neste novo contêiner.

Uma nota final :

Eu acho que agora é óbvio porque os dados parecem estar perdidos, mas estão sempre lá ... mas em um contêiner [antigo] diferente. Portanto, tome nota da diferença em docker start& docker runcommand e nunca se confunda com elas.

kiran dahibhate
fonte
1

o problema semelhante (e de nenhuma maneira o Dockerfile poderia corrigi-lo) me levou a esta página.

estágio 0: para todos, esperando que o Dockerfile possa corrigi-lo: até que --dns e --dns-search apareçam no suporte ao Dockerfile - não há como integrar recursos baseados na intranet.

estágio 1: após criar a imagem usando o Dockerfile (a propósito, é uma falha grave que o Dockerfile deve estar na pasta atual ), ter uma imagem para implantar o que é baseado na intranet, executando o script de docker run. exemplo: docker run -d \ --dns=${DNSLOCAL} \ --dns=${DNSGLOBAL} \ --dns-search=intranet \ -t pack/bsp \ --name packbsp-cont \ bash -c " \ wget -r --no-parent http://intranet/intranet-content.tar.gz \ tar -xvf intranet-content.tar.gz \ sudo -u ${USERNAME} bash --norc"

estágio 2: aplicando o script de execução do docker no modo daemon, fornecendo registros DNS locais para poder baixar e implantar coisas locais.

ponto importante: o script de execução deve terminar com algo como /usr/bin/sudo -u ${USERNAME} bash --norcmanter o contêiner em execução, mesmo após a conclusão dos scripts de instalação.

não , não é possível executar o contêiner no modo interativo para toda a questão da automação, pois ele permanecerá dentro do prompt de comando interno até que CTRL-p CTRL-q seja pressionado.

não , se o bash de interação não for executado no final do script de instalação, o contêiner será encerrado imediatamente após o término da execução do script, perdendo todos os resultados da instalação.

estágio 3: o contêiner ainda está sendo executado em segundo plano, mas não está claro se o contêiner terminou o procedimento de instalação ou ainda não. usando o seguinte bloco para determinar a conclusão do procedimento de execução: while ! docker container top ${CONTNAME} | grep "00[[:space:]]\{12\}bash \--norc" - do echo "." sleep 5 done o script continuará apenas após a instalação concluída. e este é o momento certo para chamar: commit , fornecendo o ID do contêiner atual, bem como o nome da imagem de destino (pode ser o mesmo que no procedimento de compilação / execução , mas anexado à tag de propósitos de instalação local. exemplo:. docker commit containerID pack/bsp:toolchainedconsulte este link em como obter containerID adequado

estágio 4: o contêiner foi atualizado com as instalações locais e foi confirmado na imagem recém-atribuída (a tag com finalidades adicionada). agora é seguro parar o contêiner em execução. exemplo:docker stop packbsp-cont

stage5: a qualquer momento que o contêiner com instalações locais precisar ser executado, inicie-o com a imagem salva anteriormente. exemplo:docker run -d -t pack/bsp:toolchained

Oleg Kokorin
fonte
1

uma resposta brilhante aqui Como continuar uma janela de encaixe que sai do usuário kgs

docker start $(docker ps -a -q --filter "status=exited")
(or in this case just docker start $(docker ps -ql) 'cos you don't want to start all of them)

docker exec -it <container-id> /bin/bash

Essa segunda linha é crucial. Portanto, exec é usado no lugar da execução, e não em uma imagem, mas em um containerid. E você faz isso depois que o contêiner foi iniciado.

barlop
fonte
0

Nenhuma das respostas aborda o ponto dessa escolha de design. Eu acho que o docker funciona dessa maneira para evitar esses 2 erros:

  • Reinicialização repetida
  • Erro parcial
Minh Nghĩa
fonte