Simplificando o Desenvolvimento em Docker com Compose Watch

Otimize o Desenvolvimento com Docker Compose Watch: Hot Reloading e Rebuild Automatizados de Imagens e Containers

Por Gabriel Luciano

Criado em 05 de outubro de 2023 às 12:13

Imagem do post

O que é o Docker Compose Watch

Utilizar containers do Docker para desenvolvimento pode ser uma tarefa árdua. Mesmo com o auxilio de ferramentas como o Docker Compose, com o comando docker compose up, ainda existem inconveniências como ter que manualmente parar os containers e utilizar o comando docker compose up --build toda vez que precisamos alterar nossa imagem, por exemplo, ao instalar uma nova dependência. Além disso, para que as alterações em nosso código sejam refletidas no container, precisamos usar o bind mounting para mapear diretórios do nosso host para o container, o que pode gerar problemas de permissões, por exemplo.

A nova função do Docker Compose, chamada de "Watch", busca resolver muitos desses problemas. Com o Docker Compose Watch, podemos especificar, em nosso arquivo docker-compose.yml, arquivos que devem ser sincronizados entre o nosso host e o container. Além disso, podemos configurar arquivos no nosso host que acionarão o rebuild automático da nossa imagem e do nosso container.

Para utilizar o Docker Compose Watch, é necessário ter o Docker Desktop na versão v4.24+ e o Docker Compose na versão v2.22+.

Docker Compose Watch com Next.js

Para demonstrar o funcionamento do Compose Watch, criei um exemplo com o framework Next.js, disponível no meu Github. O arquivo principal deste exemplo é o docker-compose.override.yml, onde estão as configurações do nosso service "next", que usa uma imagem customizada para executar nosso projeto.

services:
  next:
    image: custom-next-app:latest
    build: .
    ports:
      - "3000:3000"
    healthcheck:
      test: ["CMD-SHELL", "curl -f http://localhost:3000 || exit 1"]
      interval: 1m30s
      timeout: 10s
      retries: 3
      start_period: 40s
    develop:
      watch:
        - action: sync
          path: .
          target: /app
          ignore:
            - node_modules/
        - action: rebuild
          path: package.json

Em watch, podemos especificar múltiplas actions para serem executadas pelo Compose. Na primeira action action: sync estamos instruindo o Docker para sincronizar os arquivos do host (nossa máquina) no diretório do projeto path: . com a pasta /app dentro do container target: /app. Também estamos dizendo ao docker compose para não sincronizar a pasta node_modules em ignore. O Compose Watch também ignorará todos os arquivos e diretórios listados no arquivo .dockerignore. Além disso, outros arquivos, como o diretório .git e arquivos específicos de IDEs comuns, são ignorados por padrão, embora essa configuração possa ser sobrescrita com os comandos include e exclude.

Na segunda action action: rebuild, estamos instruindo ao Docker a reconstruir nossa imagem e substituir nosso container por um novo sempre que houver uma modificação no arquivo package.json do host. Dessa forma, podemos evitar de ter que parar e reiniciar o container manualmente, já que o Compose Watch fará isso automaticamente.

Executando o projeto

Finalmente, para executar o nosso projeto, usamos o comando docker compose watch. Esse comando irá realizar o build da nossa imagem e criará o nosso container baseado nas especificações do docker-compose.override.yml.

A imagem utilizada neste exemplo, cujo Dockerfile está disponível neste link, inicia a aplicação em Next.js em modo de desenvolvimento usando o comando npm run dev, que inclui a função de Hot Reloading. Para testar a aplicação, basta acessar o navegador em localhost:3000.

Experimente modificar os arquivos do projeto para verificar o Hot Reloading em funcionamento ou alterar o package.json para ver a imagem e o container sendo recriados automaticamente!

Conclusão

Essa nova funcionalidade certamente melhorará a vida dos desenvolvedores! Não deixe de conferir o anúncio oficial do Docker Compose Watch no blog do Docker e a documentação para mais detalhes.

Se tiver alguma dúvida, sugestão de melhoria ou encontrar algum erro, não hesite em entrar em contato através da seção de comentários relacionadas a este post no Linkedin. Até a próxima!