Enabling webpack hot-reload in a docker application

22,833

Solution 1

I couldn't make webpack or webpack-dev-server watch (--watch) mode work even after mounting my project folder into container.
To fix this you need to understand how webpack detects file changes within a directory.
It uses one of 2 softwares that add OS level support for watching for file changes called inotify and fsevent. Standard Docker images usually don't have these (specially inotify for linux) preinstalled so you have to install it in your Dockerfile.
Look for inotify-tools package in your distro's package manager and install it. fortunately all alpine, debian, centos have this.

Solution 2

Docker & webpack-dev-server can be fully operational without any middleware or plugins, proper configuration is the deal:

devServer: {
  port: 80, // use any port suitable for your configuration
  host: '0.0.0.0', // to accept connections from outside container
  watchOptions: {
      aggregateTimeout: 500, // delay before reloading
      poll: 1000 // enable polling since fsevents are not supported in docker
  }
}

Use this config only if your docker container does not support fsevents.

For performance efficient way check out HosseinAgha answer #42445288: Enabling webpack hot-reload in a docker application

Solution 3

try doing this:

  1. Add watchOptions.poll = true in webpack config.

    watchOptions: { poll: true },

  2. Configure host in devServer config

    host:"0.0.0.0",

Share:
22,833
Kannaj
Author by

Kannaj

Updated on July 12, 2022

Comments

  • Kannaj
    Kannaj almost 2 years

    I have a docker app with the following containers

    1. node - source code of the project. it serves up the html page situated in the public folder.
    2. webpack - watches files in the node container and updates the public folder (from the node container) on the event of change in the code.
    3. database

    this is the webpack/node container setup

     web:
        container_name: web
        build: .
        env_file: .env
        volumes:
          - .:/usr/src/app
          - node_modules:/usr/src/app/node_modules
        command: npm start
        environment:
          - NODE_ENV=development
        ports:
          - "8000:8000"
    
      webpack:
        container_name: webpack
        build: ./webpack/
        depends_on:
          - web
        volumes_from:
          - web
        working_dir: /usr/src/app
        command: webpack --watch
    

    So currently , the webpack container monitors and updates the public folder. i have to manually refresh the browser to see my changes.

    I'm now trying to incorporate webpack-dev-server to enable automatic refresh in the browser

    these are my changes to the webpack config file

    module.exports = {
      entry:[
        'webpack/hot/dev-server',
        'webpack-dev-server/client?http://localhost:8080',
        './client/index.js'
      ],
    
      ....
    
      devServer:{
        hot: true,
        proxy: {
          '*': 'http://localhost:8000'
        }
      }
    }
    

    and the new docker-compose file file webpack

      webpack:
        container_name: webpack
        build: ./webpack/
        depends_on:
          - web
        volumes_from:
          - web
        working_dir: /usr/src/app
        command: webpack-dev-server --hot --inline
        ports:
          - "8080:8080"
    

    i seem to be getting an error when running the app

    Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
    webpack     |  - configuration.entry should be one of these:
    webpack     |    object { <key>: non-empty string | [non-empty string] } | non-empty string | [non-empty string] | function
    webpack     |    The entry point(s) of the compilation.
    webpack     |    Details:
    webpack     |     * configuration.entry should be an object.
    webpack     |     * configuration.entry should be a string.
    webpack     |     * configuration.entry should NOT have duplicate items (items ## 1 and 2 are identical) ({
    webpack     |         "keyword": "uniqueItems",
    webpack     |         "dataPath": ".entry",
    webpack     |         "schemaPath": "#/definitions/common.nonEmptyArrayOfUniqueStringValues/uniqueItems",
    webpack     |         "params": {
    webpack     |           "i": 2,
    webpack     |           "j": 1
    webpack     |         },
    webpack     |         "message": "should NOT have duplicate items (items ## 1 and 2 are identical)",
    webpack     |         "schema": true,
    webpack     |         "parentSchema": {
    webpack     |           "items": {
    webpack     |             "minLength": 1,
    webpack     |             "type": "string"
    webpack     |           },
    webpack     |           "minItems": 1,
    webpack     |           "type": "array",
    webpack     |           "uniqueItems": true
    webpack     |         },
    webpack     |         "data": [
    webpack     |           "/usr/src/app/node_modules/webpack-dev-server/client/index.js?http://localhost:8080",
    webpack     |           "webpack/hot/dev-server",
    webpack     |           "webpack/hot/dev-server",
    webpack     |           "webpack-dev-server/client?http://localhost:8080",
    webpack     |           "./client/index.js"
    webpack     |         ]
    webpack     |       }).
    webpack     |       [non-empty string]
    webpack     |     * configuration.entry should be an instance of function
    webpack     |       function returning an entry object or a promise..
    

    As you can see , my entry object doesnt have any duplicate items.

    Is there something additional i should be doing? anything i missed?

    webpack-dev-server should basically proxy all requests to the node server.

  • Kannaj
    Kannaj about 7 years
    i added the config and the browser automatically updates now .. but the changes arent getting reflected :( (not even after a manual refresh) - would you happen to know where the error could be? the console shows that webpack indeed updates the static files.
  • Kannaj
    Kannaj about 7 years
    Decided to use webpack-dev-middleware instead of having a separate docker container just for webpack alone.
  • sgohl
    sgohl over 4 years
    This is only about file-changes, that's no problem at all. webpack is re-compiling instantly. The actual problem is the hot-reload of the browser. The browser does not refresh itself automatically.. that's what called hot-reload (see the title of the question)
  • HosseinAgha
    HosseinAgha over 4 years
    Other answers enable webpack polling that is inefficient and exponentially slow when depth of file system tree increases. By installing inotify we let watchpack to listen to change events instead of polling. No need to enable polling on that case.
  • sgohl
    sgohl over 4 years
    but the problem's not about the polling. Polling and recompiling works fine. it's about the browser not reloading. there is a sockjs service thing in the browser which calls the wrong url, maybe thats the cause, but I dont know.