Depois de avaliar as respostas e estudar o tópico, gostaria de resumir.
A maneira do Docker de atualizar contêineres parece ser o seguinte:
Os contêineres do aplicativo não devem armazenar dados do aplicativo . Dessa forma, você pode substituir o contêiner do aplicativo por sua versão mais recente a qualquer momento executando algo como isto:
docker pull mysql
docker stop my-mysql-container
docker rm my-mysql-container
docker run --name=my-mysql-container --restart=always \
-e MYSQL_ROOT_PASSWORD=mypwd -v /my/data/dir:/var/lib/mysql -d mysql
Você pode armazenar dados no host (no diretório montado como volume) ou em contêineres especiais somente de dados . Leia mais sobre isso
A atualização de aplicativos (por exemplo, com a atualização yum / apt-get) dentro de contêineres é considerada um antipadrão . Os contêineres de aplicativos devem ser imutáveis , o que garantirá um comportamento reprodutível. Algumas imagens oficiais de aplicativos (mysql: 5.6 em particular) nem foram projetadas para serem atualizadas automaticamente (o apt-get upgrade não funcionará).
Gostaria de agradecer a todos que deram suas respostas, para que pudéssemos ver todas as abordagens diferentes.
Yaroslav Stavnichiy
fonte
docker rename my-mysql-container trash-container
antes de criar o novo?Como não gosto de montar volumes como um link para um diretório host, criei um padrão para atualizar contêineres de docker com contêineres gerenciados por docker. A criação de um novo contêiner de docker
--volumes-from <container>
fornecerá ao novo contêiner com as imagens atualizadas propriedade compartilhada dos volumes gerenciados pelo docker.Ao não remover imediatamente o original
my_mysql_container
ainda, você poderá voltar ao contêiner em funcionamento conhecido se o contêiner atualizado não tiver os dados corretos ou falhar em um teste de sanidade.Nesse momento, normalmente executarei todos os scripts de backup que tenho para o contêiner para fornecer uma rede de segurança, caso algo dê errado
Agora você tem a oportunidade de garantir que os dados que você espera estar no novo contêiner estejam lá e executar uma verificação de integridade.
Os volumes da janela de encaixe permanecerão enquanto houver um contêiner em uso, para que você possa excluir o contêiner original com segurança. Depois que o contêiner original é removido, o novo contêiner pode assumir o nome do original para deixar tudo tão bonito quanto deveria.
Há duas vantagens principais em usar esse padrão para atualizar contêineres do docker. Em primeiro lugar, elimina a necessidade de montar volumes nos diretórios host, permitindo que os volumes sejam transferidos diretamente para um contêiner atualizado. Em segundo lugar, você nunca está em uma posição em que não haja um contêiner de estivador funcionando; portanto, se a atualização falhar, você poderá reverter facilmente para o funcionamento anterior girando o contêiner de docker original novamente.
fonte
./postgres-data/:/var/lib/postgres/data
- ou seja montada a dir acolhimento./postgres-data/
, dentro do meu recipiente PostgreSQL).Apenas por fornecer uma resposta mais geral (não específica do mysql) ...
Sincronize com o registro de imagem de serviço ( https://docs.docker.com/compose/compose-file/#image ):
Recrie o contêiner se o arquivo ou a imagem do docker-compose tiver sido alterada:
O gerenciamento de imagens de contêiner é um dos motivos para o uso do docker-compose (consulte https://docs.docker.com/compose/reference/up/ )
O aspecto de gerenciamento de dados também é coberto pelo docker-compose por meio de "volumes" externos montados (consulte https://docs.docker.com/compose/compose-file/#volumes ) ou contêiner de dados.
Isso deixa possíveis problemas de compatibilidade com versões anteriores e migração de dados, mas esses são problemas "aplicáveis", não específicos do Docker, que precisam ser verificados em relação às notas de versão e testes ...
fonte
Gostaria de acrescentar que, se você quiser executar esse processo automaticamente (faça o download, pare e reinicie um novo contêiner com as mesmas configurações descritas por @Yaroslav), poderá usar a WatchTower. Um programa que atualiza automaticamente seus contêineres quando eles são alterados https://github.com/v2tec/watchtower
fonte
Considere para estas respostas:
app_schema
app_db
root123
Como atualizar o MySQL ao armazenar dados de aplicativos dentro do contêiner
Isso é considerado uma prática ruim , porque se você perder o contêiner, os dados serão perdidos. Embora seja uma má prática, aqui está uma maneira possível de fazê-lo:
1) Faça um despejo de banco de dados como SQL:
2) Atualize a imagem:
3) Atualize o contêiner:
4) Restaure o dump do banco de dados:
Como atualizar o contêiner MySQL usando um volume externo
Usar um volume externo é uma maneira melhor de gerenciar dados e facilita a atualização do MySQL. Perder o contêiner não perderá nenhum dado. Você pode usar o docker-compose para facilitar o gerenciamento de aplicativos Docker com vários contêineres em um único host:
1) Crie o
docker-compose.yml
arquivo para gerenciar seus aplicativos:2) Atualize o MySQL (da mesma pasta que o
docker-compose.yml
arquivo):Nota: o último comando acima atualizará a imagem do MySQL, recriará e iniciará o contêiner com a nova imagem.
fonte
docker-compose
, isso funcionará? stackoverflow.com/a/31485685/65313volumes_from
A chave agora está obsoleta (mesmo removida na versão 3 do arquivo de composição) em favor da novavolumes
chave.docker pull image_uri:tag && docker restart container_running_that_image
trabalhou para mim. Não há necessidadedocker-compose pull && docker-compose up -d
.Resposta semelhante à acima
fonte
Aqui está o que parece usar
docker-compose
ao criar um personalizadoDockerfile
.docker build -t imagename:version .
Isso armazenará sua nova versão localmente.docker-compose down
docker-compose.yml
arquivo para refletir o novo nome de imagem que você definiu na etapa 1.docker-compose up -d
. Ele procurará localmente a imagem e usará a atualizada.-EDITAR-
Meus passos acima são mais detalhados do que precisam. Otimizei meu fluxo de trabalho incluindo o
build: .
parâmetro no meu arquivo de composição de encaixe. As etapas parecem agora:docker-compose build
docker-compose up -d
Eu não percebi na época, mas o docker-compose é inteligente o suficiente para simplesmente atualizar meu contêiner para a nova imagem com o comando one, em vez de precisar trazê-lo primeiro.
fonte
docker-compose up -d
sem precisar parar tudo primeiro.Se você não deseja usar o Docker Compose, posso recomendar o porttainer . Possui uma função de recriação que permite recriar um contêiner enquanto puxa a imagem mais recente.
fonte
Você precisa reconstruir todas as imagens e reiniciar todos os contêineres ou, de alguma forma, atualizar o software e reiniciar o banco de dados. Não há caminho de atualização, mas você mesmo projeta.
fonte
docker restart
comando, mas não tenho certeza de que ele captará alterações na imagem. E o que acontece com meus dados dentro de contêineres?Retirado de http://blog.stefanxo.com/2014/08/update-all-docker-images-at-once/
Você pode atualizar todas as suas imagens existentes usando o seguinte pipeline de comandos:
fonte
Verifique se você está usando volumes para todos os dados persistentes (configuração, logs ou dados do aplicativo) armazenados nos contêineres relacionados ao estado dos processos dentro desse contêiner. Atualize seu Dockerfile e reconstrua a imagem com as alterações desejadas e reinicie os contêineres com seus volumes montados no local apropriado.
fonte
Isso é algo com o qual também tenho lutado por minhas próprias imagens. Eu tenho um ambiente de servidor a partir do qual crio uma imagem do Docker. Quando atualizo o servidor, gostaria que todos os usuários que estão executando contêineres baseados na minha imagem do Docker pudessem atualizar para o servidor mais recente.
Idealmente, eu preferiria gerar uma nova versão da imagem do Docker e ter todos os contêineres baseados em uma versão anterior dessa imagem atualizados automaticamente para a nova imagem "no local". Mas esse mecanismo parece não existir.
Portanto, o próximo melhor design que consegui apresentar até agora é fornecer uma maneira de atualizar o contêiner - semelhante à maneira como um aplicativo de desktop verifica se há atualizações e depois se atualiza. No meu caso, isso provavelmente significará a elaboração de um script que envolva o Git pull de uma tag conhecida.
A imagem / contêiner não é realmente alterada, mas os "internos" desse contêiner são alterados. Você pode imaginar fazer o mesmo com o apt-get, yum ou o que for apropriado para o seu ambiente. Junto com isso, eu atualizaria a imagem myserver: latest no registro para que quaisquer novos contêineres fossem baseados na imagem mais recente.
Eu estaria interessado em saber se existe alguma arte anterior que resolva esse cenário.
fonte
Atualizar
Isso é principalmente para consultar o contêiner para não atualizar, pois a construção de imagens é o caminho a ser feito
Como tive o mesmo problema, criei docker-run , uma ferramenta de linha de comando muito simples que é executada dentro de um contêiner de docker para atualizar pacotes em outros contêineres em execução.
Ele usa docker-py para se comunicar com os contêineres do docker em execução e atualizar os pacotes ou executar qualquer comando único arbitrário
Exemplos:
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run exec
por padrão, isso executará o
date
comando em todos os contêineres em execução e retornará resultados, mas você pode emitir qualquer comando, por exemplodocker-run exec "uname -a"
Para atualizar pacotes (atualmente usando apenas o apt-get):
docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run update
Você pode criar um apelido e usá-lo como uma linha de comando regular, por exemplo
alias docker-run='docker run --rm -v /var/run/docker.sock:/tmp/docker.sock itech/docker-run'
fonte
apt update; apt upgrade
, a imagem aumentará.)