Vue-cli: Webpack DevServer configuration for Docker

Created on 29 Jun 2018  ·  20Comments  ·  Source: vuejs/vue-cli

Version

3.0.0-rc.3

Reproduction link

https://codesandbox.io/s/vue

Steps to reproduce

Generate a basic project using vue-cli.
Run npm run serve in docker container.

What is expected?

App works and it's accessible, hot reload works

What is actually happening?

App works and it's accessible, hot reload doesn't work


The issue is that it automatically starts the devserver using docker container's internal IP:

app_1  |   App running at:
app_1  |   - Local:   http://localhost:8080/
app_1  |   - Network: http://172.23.0.2:8080/

I can't access 172.23.0.2:8080 at all since Docker for Mac has limited networking features.
It would be awesome to be able to configure devserver to use only 0.0.0.0 and tell it to not to listen also a LAN address.

enhancement cli-service serve

Most helpful comment

Hmm, maybe this will help?

// vue.config.js
module.exports = {
  devServer: {
    public: '0.0.0.0:8080'
  }
}

All 20 comments

have you tried npm run serve --host 0.0.0.0 ?

I believe you meant vue-cli-service serve --host 0.0.0.0 (npm run serve --host 0.0.0.0 gives an error).
No, this didn't help and I can't find any option that would disable listening on "external" address for hot module reload.
And unfortunately it seems there are no workaround for Docker as well.
Just to illustrate the behavior, here are requests when running devserver without docker, just on host machine:
screen shot 2018-06-29 at 23 39 55

and here's the same app running in Docker:
screen shot 2018-06-29 at 23 38 14

There are just no possibility to access docker container by it's IP in Mac OS. It's available only through binding to 0.0.0.0.

build your app before serve in docker

@Garito I'm running the app in development environment, maybe I'm missing something but how hot reload is related to the built app?

I see that it is hardcoded to set LAN url if 0.0.0.0 host provided: https://github.com/vuejs/vue-cli/blob/dev/packages/@vue/cli-service/lib/util/prepareURLs.js#L29

Can this be avoided in some way?

Hmm, maybe this will help?

// vue.config.js
module.exports = {
  devServer: {
    public: '0.0.0.0:8080'
  }
}

The development server activates hot reload
When you build the app doesn't use it
In the new webpack there are modes (development with hot reload and production without)

I had the same issue, the workaround I used for this problem was setting "network_mode: host" in docker-compose.

@vchaptsev thanks, but that didn't help.
@Garito I'm working in development environment, I don't need to build the application.
@DRoet thanks, that might help if you're working with a single setup although I'm running a range of different services and they're configured to be in specific docker networks

I believe vue-cli should have some option that will either tell devserver to communicate only with localhost or an option that would disable binding to LAN address at all.

You can change the mode from development to production without building the app
This should deactivate the hot reload
Besides that the new webpack configuration format will help you reconfigure webpack with your needs
Check the vue-cli 3 documentation

@Garito I think there are some miscommunication. Original post says that hot reload isn't working and I want it to be working, not the opposite.

@vchaptsev I'm sorry, you were right. Setting public: '0.0.0.0:8080' in vue.config.js solves the issue but two moments here:

  • it's a bit unclear at first that this change has affected the setup somehow. Here the public parameter affected the socks URL which, I believe, defines with which host devserver communicate. It would be great to have some additional info in the server start output regarding this.
  • I have a very weird issue with docker restart command (and that's the primary reason I didn't notice any change at first). Suppose you run docker start, everything including hot reload works just fine and then you decide to docker restart a container, even without any change to configs or data. After that no matter what you do you would receive just previous application state, not mentioning hot reload. It just looks like previous devserver hasn't been killed completely for some reason... I just can't find any particular reason what is happening. Volumes are ok and file changes are reflected inside the container, container status is ok. Or maybe file there are some issue with file watcher, dont know yet. Continue digging into that.
    The interesting thing is that if you do docker stop and docker start everything works just as expected and the application served perfectly.

@sdzyba glad to hear it :)
Yes, this is an unclear solution, but this is the best way I have found.

Sorry, my bad...
I'm using the cli with docker and hot reload comes and goes width the versions but I'm accessing it with the localhost:8080 without issues (no need to set the ip at all) when it works
Did you try that?
As I understand, docker toolbox bridges the ip of the container to your localhost exactly to avoid this kind of troubles
I could post here (if is ok) my dockerfile for the container and how I start it (so I shouldn't care if the container is destroyed or what and works for me)

Thanks a lot for everyone who's contributed to this discussion. I came here having the same issue (also Docker, but on linux), and while I'm having difficulty getting yarn serve to pick up vue.config.js, (_I realized I had to change 0.0.0.0 to the public IP of the vps_) this feels like a good temporary fix.

As a permanent fix, would it be reasonable to change whatever is hardcoded to the Network IP, and have it respect serve --host with a default of the same IP used to serve the page, or have the websocket not refer to specific IP at all?

Use devServer.public to specify the actual URL from which you will be accessing your dev server.

General note on using Vue CLI 3 with docker: you need to run the container with proper command:

docker run \
  # run in interactive mode
  -it \
  # bind the port properly
  -p 8080:8080 \
  # mount your app volume so that changes trigger HMR
  -v $(pwd)/app:/app \
  your-image-name

Adjust the command above according to your Dockerfile.

When you try to access the app, you can ignore network address shown by the serve command (there's no way for us to know you are running inside docker). Use localhost:<your container's exposed port> instead.

HMR issue should be fixed in da38ed4a (tested with Docker for mac).

I spent way too much time on this one... 🤦🏻‍♂️😐

devServer: {
    host: '0.0.0.0',
    ....
}

On Windows we solved it using polling.

Adding the following code to vue.config.js

devServer: {
        watchOptions: {
            ignored: /node_modules/,
            aggregateTimeout: 300,
            poll: 500
        }
    }

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

webpack-dev-server docker in windows no hot push need:

devServer: {
watchOptions: {
ignored: /node_modules/,
aggregateTimeout: 300,
poll: 500
}
}

Was this page helpful?
0 / 5 - 0 ratings

Related issues

DrSensor picture DrSensor  ·  3Comments

OmgImAlexis picture OmgImAlexis  ·  3Comments

jgribonvald picture jgribonvald  ·  3Comments

sanderswang picture sanderswang  ·  3Comments

miyamoto-san picture miyamoto-san  ·  3Comments