O HMR não funciona com o Laravel Mix no Docker

8

Estou com problemas para configurar o Recarregamento quente do módulo no Laravel Mix dentro de um contêiner do Docker.

Eu tenho o seguinte Dockerfile:

FROM php:7.4.0-fpm

RUN curl -sL https://deb.nodesource.com/setup_13.x | bash

RUN apt-get update && \
    apt-get install -y -q --no-install-recommends \
    nano apt-utils curl unzip default-mysql-client nodejs build-essential git \
    libcurl4-gnutls-dev libmcrypt-dev libmagickwand-dev \
    libwebp-dev libjpeg-dev libpng-dev libxpm-dev \
    libfreetype6-dev libaio-dev zlib1g-dev libzip-dev && \
    echo 'umask 002' >> /root/.bashrc  && \
    apt-get clean

# Docker PHP Extensions
RUN docker-php-ext-install -j$(nproc) iconv gettext gd mysqli curl pdo pdo_mysql zip && \
    docker-php-ext-configure gd --with-freetype=/usr/include/ --with-jpeg=/usr/include/ && \
    docker-php-ext-configure curl --with-curl

WORKDIR /var/www/html

COPY . /var/www/html

EXPOSE 80

Que estou construindo usando o arquivo docker-compose.yml abaixo.

  # The Application
  app:
    build:
      context: ./
      dockerfile: app.dockerfile
    working_dir: /var/www/html
    volumes:
      - ./webroot:/var/www/html
    environment:
      - "DB_PORT=3306"
      - "DB_HOST=database"
      - CHOKIDAR_USEPOLLING=true

  # The Web Server
  web:
    build:
      context: ./
      dockerfile: web.dockerfile
    working_dir: /var/www/html
    volumes_from:
      - app
    ports:
      - 80:80

Nos aplicativos Node.js anteriores, copiei os dados dentro do dockerfile e montei o volume no arquivo de composição, no entanto, isso não parece ter o mesmo efeito com o Laravel.

Estou vendo a saída abaixo no Git Bash, no entanto, as páginas da Web não são recarregadas com alterações depois que eu executo o npm hot hot dentro do contêiner, nem mesmo com uma atualização manual:

insira a descrição da imagem aqui

Apesar disso, o npm run watch-poll, que eu usei anteriormente, ainda funciona conforme o esperado.

Normalmente, vejo logs no console do HMR e WDS dentro do navegador ao visualizar o aplicativo. No entanto, nesta situação, não estou vendo nenhuma saída.

Abaixo também incluí meu arquivo webpack.mix.js. Venho brincando com algumas das opções, como a porta e o host, pois sei que elas precisam ser configuradas de uma certa maneira quando executadas dentro de um contêiner. Qualquer ajuda seria apreciada, pois estou lutando para descobrir onde estou dando errado.

mix.options({
    hmrOptions: {
        host: 'localhost',
        port: '80'
    },
});

mix.webpackConfig({
    mode: "development",
    devtool: "inline-source-map",
    devServer: {
        disableHostCheck: true,
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        host: "0.0.0.0",
        port: 80
    },
});

Editar:

A saída de erro ao executar o npm fica quente após a configuração dos dois valores do host para web:

> @ hot /var/www/html
> cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js

events.js:298
      throw er; // Unhandled 'error' event
      ^

Error: listen EADDRNOTAVAIL: address not available 172.25.0.4:80
    at Server.setupListenHandle [as _listen2] (net.js:1292:21)
    at listenInCluster (net.js:1357:12)
    at GetAddrInfoReqWrap.doListen [as callback] (net.js:1496:7)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:69:10)
Emitted 'error' event on Server instance at:
    at emitErrorNT (net.js:1336:8)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  code: 'EADDRNOTAVAIL',
  errno: -99,
  syscall: 'listen',
  address: '172.25.0.4',
  port: 80
}
James Pavett
fonte
Não há log, ele falha silenciosamente?
loic.lopez 17/02
@ loic.lopez Sim, você sabe se há algum registro que identifique uma causa?
James Pavett
Eu acho que você poderia estar interessado em: github.com/JeffreyWay/laravel-mix/issues/868
loic.lopez
Infelizmente, trabalhei com esses dois e eles realmente não mudaram a saída. Ainda não há resposta dentro do navegador que o HMR esteja ativo
James Pavett 17/02

Respostas:

3

o problema está em

mix.options({
    hmrOptions: {
        host: 'localhost',
        port: '80'
    },
});

você não pode usar o localhost, pois neste caso, consulte o contêiner do seu APP. O que você deve fazer é usar, webpois o compose resolverá os nomes de serviço para você:

mix.options({
    hmrOptions: {
        host: 'web',
        port: '80'
    },
});

mix.webpackConfig({
    mode: "development",
    devtool: "inline-source-map",
    devServer: {
        disableHostCheck: true,
        headers: {
            'Access-Control-Allow-Origin': '*'
        },
        host: "web",
        port: 80
    },
});
LinPy
fonte
Olá @LinPy, agora estou recebendo os seguintes erros em todos os meus arquivos de recurso: web // css / app.css net :: ERR_ABORTED 504 (tempo limite do gateway) etc ...
James Pavett 20/02
seu servidor web está rodando? o que há nos logs de contêiner da web?
LinPy 20/02
Eles parecem ser os logs padrão que você esperaria: 172.25.0.1 - - [20 / Feb / 2020: 08: 52: 28 +0000] "GET /favicon.ico HTTP / 1.1" 200 0 " localhost / admin / dashboard "" Mozilla / 5.0 (Windows NT 10.0; Win64; x64)
James Pavett em
desculpe pela inconveniência, não consigo nem executar o npm hot hot agora, apenas obtendo uma saída de erro. Eu o editei no meu post principal, apenas pesquisando um pouco sobre o erro.
James Pavett
0

O Webpack pode ter problemas com o observador de arquivos estar dentro da janela de encaixe. Tente adicionar a opção de pesquisa na configuração do devServer.

mix.webpackConfig({
  mode: "development",
  devtool: "inline-source-map",
  devServer: {
    watchOptions: {
      poll: true
    }
  }
});

Para o listen EADDRNOTAVAIL: address not available 172.25.0.4:80problema:

  1. Veja se há um contêiner executando com docker ps
  2. Mate o recipiente bloqueador com docker stop [container_id]
Alan Darmasaputra
fonte
Ainda sem sorte, e não há outros contêineres em execução nesse endereço. Eu só o recebo quando defino os dois hosts para a Web, como na sugestão do @ LinPy; no entanto, caso contrário, não funciona de qualquer maneira.
James Pavett 26/02