12

Using Ubuntu Linux with docker installed. No VM.

I have build a docker image with a vuejs application. To enable hot reload I start the docker container with:

docker run -it -p 8081:8080 -e "HOST=0.0.0.0" -v ${PWD}:/app/ -v /app/node_modules --name my-frontend my-frontend-image

It starts up fine and I can access it from my host browser on localhost:8081. But when I make changes to the source files and save those changes they are not reflected in my browser before I press F5 (hot reload does not work).

Some details below:

package.json

  "scripts": {
    "dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
    "start": "npm run dev",

build/webpack.dev.conf.js

  devServer: {
    clientLogLevel: 'warning',
    ...
    hot: true,
    ...
    watchOptions: {
      //poll: config.dev.poll,
      //aggregateTimeout: 500, // delay before reloading
      poll: 100 // enable polling since fsevents are not supported in docker

    }

Tried to modify the watchOptions but it has no effect.

EDIT:

Based on below answer I have tried to pass: CHOKIDAR_USEPOLLING=true as an environment variable to docker run:

docker run -it -p 8081:8080 -e "HOST=0.0.0.0" -e "CHOKIDAR_USEPOLLING=true" -v ${PWD}:/app/ -v /app/node_modules --name my-frontend my-frontend-image

But it has not effect - still not able to hot reload my changes. Also in the provided link it says:

Update/Clarification: This problem only occurs when running your Docker engine inside a VM. If you are on Linux for both Docker and for coding you do not have this problem.

So don't think the answer applies to my setup - I am running Ubuntu Linux on my machine where I have installed docker. So no VM setup.

Another update - based on the comment below on changing the port mapping:

  # Hot reload works!
  docker run -it -p 8080:8080 -e "HOST=0.0.0.0" -v ${PWD}:/app/ -v /app/node_modules --name my-frontend my-frontend-image

  # Hot reload fails!  
  #docker run -it -p 8081:8080 -e "HOST=0.0.0.0" -v ${PWD}:/app/ -v /app/node_modules --name my-frontend my-frontend-image

So if I port map to 8080:8080 instead of 8081:8080 hot reload works! Notice the application comes up in both cases when I access it on my host browser on localhost on the before mentioned ports. Its just that hot reload only works when I map the application to 8080 on my host.

But why??

Now if I do:

PORT='8081'
docker run -it -p "${PORT}:${PORT}" -e "HOST=0.0.0.0" -e "PORT=${PORT}" -v ${PWD}:/app/ -v /app/node_modules --name my-frontend my-frontend-image

Hot reload of course works. But still not sure why I cannot map internal container port 8080 to 8081 externally on the host.

Btw; I don't see the problem at all if I use vue-cli-service serve instead - everything works out of the box.

4
  • Is this working under VM? Commented Nov 17, 2019 at 9:25
  • What do you mean as described the app is running inside a docker container. Commented Nov 18, 2019 at 6:55
  • Can changing your port definition to -p 8080:8080 -p 8081:8081 Commented Nov 20, 2019 at 12:14
  • Ha specifying 'docker run -it -p 8080:8080 -e "HOST=0.0.0.0" -v ${PWD}:/app/ -v /app/node_modules --name my-frontend my-frontend-image' works! So apperantly the application needs to port mapped to 8080 for hot reload to work. But why?? Commented Nov 20, 2019 at 15:59

3 Answers 3

6
+25

I am not a VueJS user at all, never worked with it, but I use Docker heavily for my development workflow, and in the past I experienced a similar issue.

In my case the Javascript that was sent to the browser was trying to connect with the internal port of the docker container 8080, but once the mapped one for the host was 8081, the JS in the browser was not able to reach 8080 inside the docker container, therefore hot reload was not working.

So it seems to me that you have the same scenario as me, thus you need to configure in your VueJS app the hot reload to listen in the same port you want to use in the host, or just use the same port for both as you already concluded that it works.

Sign up to request clarification or add additional context in comments.

2 Comments

Yeah sounds like it. Could be interesting with an explanation though - since right now I need to remember to apply my workaround as described. Also as I described it works out of the box if I use 'vue-cli-service serve' instead so must be something that's broken in raw 'webpack-dev-server'.
Nothing is broken in 'webpack-dev-server', you just need to understand how Docker works. Docker is like a black box for the live reload. For all it matters its talking with localhost, not docker.
1

If watchOptions doesnt work, you can try out the other option:

 environment:

  - CHOKIDAR_USEPOLLING=true

As per docs here:

“If watching does not work for you, try out this option. Watching does not work with NFS and machines in VirtualBox.”

Reference:

https://daten-und-bass.io/blog/enabling-hot-reloading-with-vuejs-and-vue-cli-in-docker/

2 Comments

Not sure about where to specify what you suggest but as I understand it needs to be set as an environment variable. If I do that to docker run it has no effect. See my updated post. Also in the link you provide it says this is only relevant when running in a VM.
This did resolve my hot-load issue: PS D:\app> docker run -dp 80:8080 -e "CHOKIDAR_USEPOLLING=true" -w /app -v "$(pwd):/app" node:15-alpine sh -c "npm run serve"
0

It's been asked a long time ago, but I had the same problem and then noticed there's a sockPort within devServer config object that let's you set the port used by the websocket connection to communicate with the server for live/hot-reloading purposes.

What I did is set this option via an environment variable and it worked just fine when accessing the dev server from outside the container.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.