Como fazer o Docker Compose esperar por contêineres de dependência

0
24


O Docker Compose permite iniciar vários contêineres executando um único comando. Isso simplifica a criação de serviços complexos compostos por vários componentes independentes.

No entanto, isso nem sempre é bom o suficiente. Alguns de seus contêineres podem ter dependências entre si, o que interrompe o aplicativo se não puderem ser atendidos. Neste guia, mostraremos como você pode configurar seus serviços do Compose para acomodar essas dependências, possibilitando iniciar os contêineres em ordem.

O básico

O Docker Compose suporta um depends_on campo em docker.compose.yml Os serviços de arquivos podem incluir os nomes de seus irmãos em depends_on. Isso impede que o contêiner seja iniciado até que os serviços dos quais ele depende estejam ativos.

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
  web-app:
    image: example.com/web-app:latest
    depends_on:
      - api
  db:
    image: mysql:8.0

Neste exemplo, o depends_on campos fazem com que os serviços sejam iniciados na seguinte ordem:

As dependências de cada serviço são resolvidas recursivamente. O serviço que define cada depends_on O campo começa por último, no final da string. Quando um serviço depende de vários outros contêineres, eles serão iniciados na ordem em que aparecem no depends_on campo.

A cadeia de serviços é usada ao contrário ao parar uma pilha com docker-compose stop. Com o exemplo acima, o web-app o recipiente será removido primeiro, depois api S db. Isso impede que solicitações ao web-app o contêiner falha quando você inicia uma operação de desmontagem.

aguardando a preparação

O valor padrão depends_on a configuração apenas espera pelos contêineres dependentes começo. No exemplo acima, o Compose pode criar o api recipiente assim que db está em execução, mesmo que o servidor de banco de dados dentro do contêiner não esteja pronto para receber conexões. Isso significa depends_on raramente é suficiente por si só.

Você pode combinar a função com verificações de integridade para impedir que os contêineres sejam iniciados até que suas dependências estejam realmente prontas. Para usar esse recurso, aninhe um condition campo baixo depends_on com service_healthy como seu valor:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
    healthcheck:
      test: curl --fail http://127.0.0.1 || exit 1
      interval: 10s
      retries: 5
      start_period: 5s
      timeout: 10s
  web-app:
    image: example.com/web-app:latest
    depends_on:
      api:
        condition: service_healthy
  db:
    image: mysql:8.0

Agora ele api O contêiner tem um comando de verificação de integridade anexado a ele. a web-app é indicado que o serviço não inicia até api foi criado com um resultado de verificação de integridade bem-sucedido. Isso acontecerá quando a API começar a responder às solicitações e o curl o comando sai com um código de status de zero.

Aguardando uma saída bem-sucedida do contêiner

Em alguns casos, sua dependência pode ser um wrapper único que você deseja executar até a conclusão. Você pode esperar esse tipo de dependência definindo o condition campo para service_completed_successfully. Isso é útil quando você tem um script de configuração de primeira execução em outro contêiner.

services:
  app:
    image: example.com/app:latest
    depends_on:
      config_builder:
        condition: service_completed_successfully
    volumes:
      - config:/opt/app/config
  config_builder:
    image: example.com/config_builder:latest
    env:
      - EXAMPLE_KEY
      - ANOTHER_KEY
    volumes:
      - config:/output
volumes:
  config:

Este exemplo mostra como uma imagem dependente pode executar um comando que grava um arquivo de configuração em um volume compartilhado por app. Depois de escrever os dados, o config_builder o contêiner para com um código de saída zero. O Compose inicia automaticamente o app serviço desde que sua condição de dependência tenha sido cumprida.

Em algumas situações depends_on com um condition pode ainda não ser suficiente para se adequar ao seu caso de uso. Você pode adicionar ferramentas externas para implementar manualmente verificações de estado e manipular links entre contêineres.

Wait-for-It é um script utilitário que envolve outro processo. Executará o comando que você especificar depois que uma determinada condição for atendida. Isso pode ser usado para definir procedimentos de verificação de integridade independentes do suporte interno do Docker.

Aqui está como usar healthcheck para aguardar que uma porta de contêiner vinculada seja acessível:

services:
  api:
    image: example.com/api:latest
    depends_on:
      - db
  web-app:
    image: example.com/web-app:latest
    depends_on:
      - api
    command: ["./wait-for-it.sh", "api:8080", "--", "node", "app.js"]
  db:
    image: mysql:8.0

Aqui fizemos novamente o Docker Compose apenas esperar o api recipiente para começo. a web-app serviço aceita a responsabilidade de verificar se api é saudável. Ele usa o script Wait-for-It para detectar quando o contêiner está acessível na porta 8080. Wait-for-It iniciará o comando real do contêiner do aplicativo da Web, definido como node app.js.

Essa abordagem é melhor reservada para situações específicas em que você não pode configurar o controle com estado adequado com o Docker. Pode ser necessário ao usar uma imagem de terceiros que não pode ser configurada para executar um comando de verificação de integridade. Wait-for-It fornece uma maneira de detectar se uma porta está servindo tráfego como uma substituição stand-in. Embora não seja infalível, muitas vezes é um bom indicador da salubridade de um recipiente.

Resumo

Por padrão, o Docker Compose inicia todos os serviços em sua pilha simultaneamente. Isso geralmente é indesejável quando as ligações entre serviços criam relacionamentos de dependência pai-filho.

a depends_on O campo permite definir uma sequência de inicialização para seus serviços. O Compose criará cada novo contêiner em ordem, garantindo que o contêiner anterior tenha sido iniciado antes que o próximo contêiner seja adicionado.

Você pode aguardar a saída do contêiner anterior ou relatar uma verificação de status positiva adicionando um condition para a definição de dependência. Em situações em que as verificações de integridade não podem ser usadas, você pode usar ferramentas como Wait-for-It para permitir que os contêineres pai detectem quando suas dependências estão prontas.