Como fazer com que o docker-componha sempre recrie contêineres a partir de imagens novas?

198

Minhas imagens do docker são construídas em um servidor Jenkins CI e enviadas para o nosso Docker Registry privado. Meu objetivo é provisionar ambientes com docker-compose que sempre iniciam o estado originalmente criado das imagens.

Atualmente, estou usando o docker-compose 1.3.2 e 1.4.0 em máquinas diferentes, mas também usamos versões anteriores.

Eu sempre usei os docker-compose pull && docker-compose up -dcomandos para buscar as novas imagens do registro e iniciá-las. Acredito que meu comportamento preferido estava funcionando conforme o esperado até um certo ponto no tempo, mas desde então docker-compose upcomeçou a executar novamente os contêineres parados anteriormente, em vez de iniciar as imagens originalmente criadas todas as vezes.

Existe uma maneira de se livrar desse comportamento? Poderia ser aquele conectado ao arquivo de configuração docker-compose.yml para não depender de "não esquecer" algo na linha de comando a cada chamada?

ps. Além de encontrar uma maneira de alcançar meu objetivo, eu também gostaria de saber um pouco mais sobre o histórico desse comportamento. Penso que a ideia básica do Docker é construir uma infraestrutura imutável. O comportamento atual do docker-compor parece simplesmente entrar em conflito com essa abordagem .. ou eu perco alguns pontos aqui?

Kristof Jozsa
fonte

Respostas:

232

docker-compose up --force-recreateé uma opção, mas se você o estiver usando para o CI, eu começaria a compilação docker-compose rm -fpara parar e remover os contêineres e volumes (segui-lo com puxar e levantar).

Isto é o que eu uso:

docker-compose rm -f
docker-compose pull
docker-compose up --build -d
# Run some tests
./tests
docker-compose stop -t 1

A razão pela qual os contêineres são recriados é preservar quaisquer volumes de dados que possam ser usados ​​(e isso também torna upmuito mais rápido).

Se você faz CI, não quer isso; basta remover tudo para obter o que deseja.

Atualização: uso up --buildque foi adicionado em docker-compose1.7

dnephin
fonte
1
Sim, na verdade é isso que eu faço no CI também. Não sei por que eu não mencionou que ...
Adrian Mouat
@dnephin docker-compose run -dnão existe? Você quer dizer docker-compose up -dnão?
Guillaume Vincent
2
se você executar docker-compose pullantes docker-compose rm -fvocê pode economizar ainda mais tempo
stephanlindauer
2
Qual é a bandeira -d no final?
David J. Davis
3
"-d Modo
desanexado
135

A única solução que funcionou para mim foi este comando:

docker-compose build --no-cache

Isso extrairá automaticamente uma nova imagem do repositório e não usará a versão do cache que é pré-compilada com os parâmetros que você já usou antes.

davidbonachera
fonte
1
Além disso, no Windows 10, pode ajudar a definir o servidor DNS nas configurações de Automático para Fixo ou de Fixo para Automático.
Qräbnö 15/0418
2
Trabalhou para mim no OS X edifício com janela de encaixe-comopse versão 2.
RoboBear
1
Trabalhou na janela de encaixe OS X.
HelloWorld
55

Pela documentação oficial atual , existe um atalho que interrompe e remove contêineres, redes, volumes e imagens criados por up, se eles já foram parados ou parcialmente removidos e assim por diante, o procedimento também será feito:

docker-compose down

Então, se você tiver novas alterações em suas imagens ou arquivos Dockerfiles, use:

docker-compose build --no-cache

Finalmente:docker-compose up

Em um comando: docker-compose down && docker-compose build --no-cache && docker-compose up

Victor Timoftii
fonte
2
docker-compose build --no-cacheserá necessário apenas se houver alterações nos Dockerfiles.
Victor Timoftii
De fato, Victor. Obrigado! Eu pensei que também era necessário depois de atualizar um módulo / aplicativo que é executado quando o contêiner é iniciado. Para esses casos, antes da execução docker-compose up, é necessário recriar os serviços com docker-compose build.
Ivanleoncz 23/04/19
18

Você pode passar --force-recreatepara docker compose up, que deve usar recipientes novos.

Penso que o raciocínio por trás da reutilização de contêineres é preservar quaisquer alterações durante o desenvolvimento. Observe que o Compose faz algo semelhante aos volumes, que também persistirão entre a recreação do contêiner (um contêiner recriado será anexado aos volumes do seu antecessor). Isso pode ser útil, por exemplo, se você tiver um contêiner Redis usado como cache e não desejar perdê-lo toda vez que fizer uma pequena alteração. Outras vezes, é apenas confuso.

Não acredito que exista alguma maneira de forçar isso no arquivo de composição.

Indiscutivelmente, ele colide com princípios de infraestrutura imutáveis. O contra-argumento é provavelmente que você ainda não usa o Compose na produção. Além disso, não tenho certeza se concordo que infra-estrutura imutável é a idéia básica do Docker, embora seja certamente um bom caso de uso / ponto de venda.

Adrian Mouat
fonte
Obrigado pela resposta. Eu acho que seria realmente útil forçá-lo no nível de configuração, por exemplo. a aplicá-la para um recipiente de base de dados e desactivar recreação por defeito para os contentores de aplicações ..
Kristof Jozsa
8
--force-recreatenão trabalho para mim ... Imagem não é puxado mesmo que uma versão mais recente está lá fora ...
lisak
1
@lisak Eu nunca disse que puxou novas imagens. Não faz. Apenas inicia novos contêineres usando qualquer imagem disponível localmente. Você precisará executar o docker pull manualmente.
Adrian Mouat
2
docker-compose up --build

OU

docker-compose build --no-cache
flgn
fonte
1
Quando possível, faça um esforço para fornecer explicações adicionais em vez de apenas código. Essas respostas tendem a ser mais úteis, pois ajudam os membros da comunidade e, especialmente, os novos desenvolvedores a entender melhor o raciocínio da solução e podem ajudar a evitar a necessidade de abordar as perguntas de acompanhamento.
Rajan
-10
$docker-compose build

Se houver algo novo, ele será reconstruído.

Mathias Asberg
fonte