Docker and Webpack hot reload not working

Viewed 4007

Here I would like to use Docker for my future react/webpack app, but I can't configure Webpack and/or docker correctly for the reload to work (webpack-dev-server ).

I don't really understand why, the configuration seems ok to me, maybe my "start" command which is not good ?

Here is the Dockerfile config :

FROM node:11-alpine

WORKDIR /app
COPY package.json /app
RUN npm install
COPY . /app

CMD npm start
EXPOSE 8081

Here Webpack.config.js :

const HtmlWebPackPlugin = require("html-webpack-plugin");
const path = require('path');

module.exports = {
entry: "./src/App.jsx",
output: {
  path: path.resolve(__dirname, 'dist'),
  filename: 'bundle.js'
},
module: {
  rules: [
    {
      test: /\.(js|jsx)$/,
      exclude: /node_modules/,
      use: {
        loader: "babel-loader"
      }
    },
    {
        test: /\.s[ac]ss$/i,
        use: [
            // Creates `style` nodes from JS strings
            'style-loader',
            // Translates CSS into CommonJS
            'css-loader',
            'resolve-url-loader',
            // Compiles Sass to CSS
            'sass-loader',
        ]
    }
  ]
},
devServer: {
  historyApiFallback: true,
  port:8081,
  host: '0.0.0.0',
  watchOptions: {
    aggregateTimeout: 500, // delay before reloading
    poll: 1000 // enable polling since fsevents are not supported in docker
}
},
plugins: [new HtmlWebPackPlugin({ template: "./src/index.html" })]
};

Here npm start scripts :

    "start": "webpack-dev-server --host 0.0.0.0 --config ./webpack.config.js --mode development",

Thank you !

3 Answers

From the comment, you are not using binding host volume to the container. you should bind host volume to make hot reloading work.

docker run -it --rm -v $PWD/host_app_code/:/app test

where $PWD/host_app_code/ is the path to host files, once you bind this path, your change on the host will effect inside the container and hot reload should work and you will not need to build image every time.

As mentioned in @Adiii's answer, you will need to use a bind-mount volume so that the files are changed inside the container as you change them on your host, without having to rebuild the image.

I just wanted to add that Docker's getting started tutorial explains using bind-mounts for development. I would definitely recommend to go through that if you haven't, as it can give a deeper understanding of how it works and why this is necessary.

Docker's getting-started tutorial is available on docker-hub:

docker run -d -p 80:80 docker/getting-started

For hot reloading to work, You need docker container to know when there is a change in the filesystem. We bind host volumes in containers for this.

We need to remove the COPY command from dockerfile because we are directly mounting the whole directory of code. So your dockerfile should look like this

FROM node:11-alpine

WORKDIR /app

CMD npm start
EXPOSE 8081

For mounting host volumes to containers, we have to use -v when starting the container. Use the below format

docker run -it --rm -v <SOURCE_PATH>:/app <IMAGE_NAME>

replace

SOURCE_PATH with the code directory path

IMAGE_NAME with the image name

Related