Enquanto os contêineres são efêmeros, os dados do usuário precisam persistir. Um exemplo clássico, disso é quando tentamos executar imagens de contêiner de banco de dados. Se você destruir o contêiner de banco de dados, os dados também serão perdidos. O que queremos é uma situação em que a imagem do contêiner de, digamos, PostgreSQL, versão 9, pode ser substituída por uma imagem da versão 10 sem que tenhamos que perder dados. Esta é a maneira do Docker de atualizar o software, você não cai dentro do contêiner e atualiza pacotes usando um gerenciador de pacotes. Você substitui a imagem inteira do contêiner.
Vamos ver algumas armadilhas que você pode encontrar enquanto faz isso e como podemos tornar o processo muito mais suave e mais limpo do ponto de vista operacional.
Docker Volumes e PostgreSQL Comportamento padrão
Os volumes do Docker são a maneira recomendada de persistir dados. Estes são sistemas de arquivos gerenciados pelo daemon do docker e, na maioria das vezes, você deve criar um e montá -lo dentro do seu recipiente quando você o inicia. A imagem oficial do Postgres, no entanto, vem com um volume predefinido em sua descrição da imagem.
Isso significa que, quando você executa uma imagem PostGresql como um contêiner, ela cria um volume para si e armazena dados lá.
$ docker run -d - -name mydb postgresVocê pode listar os volumes existentes usando o comando ls volume do docker e pode inspecionar o contêiner do Docker MyDB para ver qual desses volumes está montado dentro do contêiner do banco de dados.
$ docker volume lsVocê notará que o volume tem um nome bastante hostil e é montado em /var/lib/postgreSql/dados.
Vamos remover este recipiente e o volume associado por enquanto:
$ docker rm -f mydbO mesmo acontece quando você cria um contêiner usando um arquivo simples do docker-composição. A seguir é um docker-composição.Arquivo YML colocado dentro de um diretório chamado PostGres.
Versão: '3'Você pode alimentá-lo com o Docker-Compose, abrindo um terminal no mesmo diretório em que este arquivo está e em execução:
$ Docker -Compõe Up -dIsso cria um contêiner e um volume muito parecido com o comando do Docker Run que vimos anteriormente. No entanto, ambos os métodos, um envolvendo Docker-Compose e outro cli do Docker têm um problema fatal e isso entra em jogo quando você precisa substituir a imagem antiga do Postgres por um novo.
Novos volumes toda vez
Se você remover a implantação acima, executando:
$ docker-compor para baixoO contêiner e a rede são removidos, mas o volume permanece e seus dados estão seguros nele. No entanto, da próxima vez que você corre:
$ Docker -Compõe Up -dA Compose criará um novo volume e montará que, em vez de usar o volume criado anteriormente. E como se lembra que o volume anterior foi destinado a este contêiner PostgreSQL em particular de qualquer maneira? Mas o usuário pobre que pode nem estar ciente do conceito de volumes ficará confuso se perguntando onde todos os dados se foram.
Volume definido pelo usuário
Para contornar esse problema, podemos usar as informações que reunimos anteriormente que nos mostraram que o volume está montado em /var/lib/postgreSql/dados. Dentro do contêiner, este diretório é onde o Postgres armazena todas as tabelas e bancos de dados relevantes.
Agora temos que definir um volume dentro do arquivo de composição e montá -lo neste ponto de montagem. É assim que o docker compor.YML seria como.
Versão: '3'A última linha "Driver: Local" é completamente opcional e é mencionada aqui apenas para mostrar que o “Chave de nível superior volumes" pode ter vários volumes definidos embaixo. DB-Data é um desses volumes que, por sua vez.
Sob o serviço MyDB, temos a chave dos volumes mais uma vez. Esse "Nível de serviço chave de volume ” É apenas uma lista de volumes definidos sob a tecla de volumes de nível superior que está sendo mapeada em pontos de montagem dentro dos contêineres
Quando você executa o comando Docker-Compompose Up -d na primeira vez com a definição de YML acima, ele criará um volume, não com uma string aleatória como nome, mas DB-Bata como seu nome. Em seguida, em diante, toda vez que você derruba o aplicativo (Docker-Compose para baixo) e depois execute novamente o Docker-Compomos Up -d Compose, tentará criar um volume chamado DB-Data, mas depois notaria que um volume com esse nome já existe. Em seguida, ele montará o mesmo volume de novo. Vamos reduzir o aplicativo por enquanto:
$ docker-compor para baixoUsando PostgreSQL
A imagem oficial do Postgres expõe a porta 5432 para nossa vantagem. Estritamente falando, isso não é necessário. Os bancos de dados são apenas um dos muitos serviços em uma rede de docker. Os outros serviços, como o Web Server, podem conversar com o banco de dados sem que nenhuma porta explícita seja publicada. Isso ocorre porque as redes de ponte definidas pelo usuário, como as que o Docker Compose cria para que seus aplicativos sejam executados, permita que os contêineres membros conversem livremente entre si. Portanto, se o servidor da web e o banco de dados estiverem na mesma rede de pontes, eles poderão conversar um com o outro, mesmo sem que nenhuma porta seja explicitamente aberta.
Os bancos de dados geralmente não são expostos ao mundo exterior, mas acessados por outros serviços. Portanto, publicar a porta Postgres não é algo que você costumava ver na produção.
No entanto, experimentaremos a aplicação de contêiner para ver se os dados realmente persistem para que possamos expor e publicar as portas por enquanto. Modifique o Docker-Compose.Arquivo YML com opção de portas adicionais.
Versão: '3'Agora, estamos prontos para interagir com a instância do PostGres usando o programa PGADmin Client. Você pode instalar este cliente em sua máquina local usando seu método preferido se seguir este link. Depois de instalar o cliente, você pode se conectar ao servidor de banco de dados, mas primeiro vamos iniciar o servidor de banco de dados.
$ Docker -Compõe Up -dDesta vez, as solicitações recebidas na porta do host Docker 5432 serão encaminhadas para a porta 5432 do contêiner de banco de dados, onde o servidor Postgres pode processar.
Conectando -se ao servidor
Inicie o cliente pgadmin e você pode acessá -lo através do seu navegador da web. No painel, você encontrará a opção chamada Adicione um novo servidor.
Dê um nome razoável, estamos indo com “Meu banco de dados ”:
E na guia Connections, insira o endereço em que o banco de dados está em execução:
O endereço pode ser localhost se você estiver executando o pgadmin e o recipiente do Postgres estão funcionando na mesma máquina. Se você estiver executando o recipiente do Postgres em um VPS remoto, por exemplo, o endereço IP desse VPS será necessário aqui. Em geral, chamamos isso de endereço do host do Docker, porque é aí que o Docker está executando.
Vamos deixar o campo de senha vazio e a porta padrão número 5432 também está bem. Salve as configurações do servidor e vamos criar um banco de dados lá.
Após uma conexão bem -sucedida, você pode ver todas as atividades internas:
No menu do navegador, podemos selecionar rapidamente Meu banco de dados servidor e com o botão direito do mouse no banco de dados e Crie um banco de dados.
Vamos criar rapidamente um banco de dados chamado Database de amostra.
Você não precisa criar mais nada aqui. Agora podemos fechar a janela e voltar ao terminal aberta no mesmo diretório em que nosso Docker-Compose.YML vive.
$ docker-compor para baixoO antigo recipiente já se foi e um novo tomou seu lugar. Você pode abrir o pgadmin novamente e terá que se reconectar com esse banco de dados (uma senha vazia faria) e dentro dele você descobrirá que tudo é como você deixou. Existe até um Database de amostra lá.
Queríamos escrever um arquivo do Docker-Compose que tornou o pós -gres atualizável. Se uma nova imagem do Postgres aparecer no Runngres 11, agora você pode puxar com confiança a nova imagem e executar uma atualização sem preocupações com o estado do aplicativo que está sendo perdido.
O comportamento padrão da imagem do Postgres, que deve criar um novo volume toda vez que um contêiner é criado não é uma escolha de design ruim. É implementado com os melhores interesses no coração.
Mas simplesmente adia um novo usuário que estaria coçando a cabeça se perguntando onde todos os dados estão se perdendo e por que existem tantos volumes deitados no host do Docker. Felizmente, isso não será mais um problema para os leitores.