HMR no funciona con Laravel Mix en Docker

8

Tengo problemas para configurar la recarga de módulos en caliente en Laravel Mix dentro de un contenedor Docker.

Tengo el siguiente 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

Lo que estoy construyendo usando el siguiente archivo docker-compose.yml.

  # 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

En aplicaciones anteriores de Node.js, copié los datos dentro del dockerfile y monté el volumen en el archivo de composición, sin embargo, esto no parece tener el mismo efecto con Laravel.

Estoy viendo la salida a continuación en Git Bash, sin embargo, las páginas web no se están recargando con los cambios después de ejecutar npm run hot dentro del contenedor, ni siquiera con una actualización manual:

ingrese la descripción de la imagen aquí

A pesar de esto, npm run watch-poll, que he usado anteriormente, todavía funciona como se esperaba.

Normalmente veo registros en la consola de HMR y WDS dentro del navegador cuando veo la aplicación. Sin embargo, en esta situación no veo ningún resultado.

A continuación, también he incluido mi archivo webpack.mix.js. He estado jugando con algunas de las opciones, como el puerto y el host, ya que sé que deben configurarse de cierta manera cuando se ejecutan dentro de un contenedor. Cualquier ayuda sería apreciada ya que estoy luchando para resolver dónde me estoy equivocando.

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:

Error al ejecutar npm run hot después de configurar ambos valores de host en la 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
fuente
No hay registro, falla en silencio?
loic.lopez
@ loic.lopez Sí, ¿sabes si hay algún registro que pueda identificar una causa?
James Pavett
Creo que te puede interesar: github.com/JeffreyWay/laravel-mix/issues/868
loic.lopez
Desafortunadamente, he trabajado con ambos y realmente no han cambiado la salida en absoluto. Todavía no hay respuesta dentro de su navegador que HMR esté activo
James Pavett

Respuestas:

3

el problema esta en

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

no puede usar localhost ya que se refiere a su contenedor de APP en este caso, lo que debe hacer es usarlo webya que compose resolverá los nombres de servicio por usted:

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
fuente
Hola @LinPy, ahora recibo los siguientes errores en todos mis archivos de recursos: web // css / app.css net :: ERR_ABORTED 504 (Tiempo de espera de la puerta de enlace), etc ...
James Pavett
¿está funcionando su servidor web? ¿Qué hay en los registros del contenedor web?
LinPy
Simplemente parecen ser los registros estándar que esperaría: 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
disculpe las molestias, ni siquiera puedo ejecutar npm run hot ahora, solo obtengo un error de salida. Lo he editado en mi publicación principal, solo investigando un poco sobre el error.
James Pavett
0

Webpack podría tener problemas con el observador de archivos dentro de la ventana acoplable. Intente agregar la opción de sondeo en la configuración de devServer.

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

Para el listen EADDRNOTAVAIL: address not available 172.25.0.4:80tema:

  1. Vea si hay un contenedor funcionando con docker ps
  2. Mata el contenedor de bloqueo con docker stop [container_id]
Alan Darmasaputra
fuente
Todavía no hay suerte, y no hay otros contenedores ejecutándose en esa dirección. Solo lo obtengo cuando configuro ambos hosts en la web como en la sugerencia de @ LinPy, sin embargo, de lo contrario, no funciona de todos modos.
James Pavett