Skip to content
This repository has been archived by the owner on Apr 8, 2020. It is now read-only.

Docker + Webpack #806

Closed
zeusapps opened this issue Mar 27, 2017 · 15 comments
Closed

Docker + Webpack #806

zeusapps opened this issue Mar 27, 2017 · 15 comments

Comments

@zeusapps
Copy link

zeusapps commented Mar 27, 2017

Is it possible to use webapck and HMR with Docker?

Currently I've get exception when project start on UseWebpackDevMiddleware.

-		InnerException	{System.InvalidOperationException: Failed to start Node process. To resolve this:.

[1] Ensure that Node.js is installed and can be found in one of the PATH directories.
    Current PATH enviroment variable is: /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    Make sure the Node executable is in one of those directories, or update your PATH.

[2] See the InnerException for further details of the cause. ---> System.ComponentModel.Win32Exception: No such file or directory
   at System.Diagnostics.Process.ResolvePath(String filename)
   at System.Diagnostics.Process.StartCore(ProcessStartInfo startInfo)
   at System.Diagnostics.Process.Start()
   at System.Diagnostics.Process.Start(ProcessStartInfo startInfo)
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.LaunchNodeProcess(ProcessStartInfo startInfo)
   --- End of inner exception stack trace ---
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance.LaunchNodeProcess(ProcessStartInfo startInfo)
   at Microsoft.AspNetCore.NodeServices.HostingModels.OutOfProcessNodeInstance..ctor(String entryPointScript, String projectPath, String[] watchFileExtensions, String commandLineArguments, ILogger nodeOutputLogger, IDictionary`2 environmentVars, Int32 invocationTimeoutMilliseconds, Boolean launchWithDebugging, Int32 debuggingPort)
   at Microsoft.AspNetCore.NodeServices.HostingModels.HttpNodeInstance..ctor(NodeServicesOptions options, Int32 port)
   at Microsoft.AspNetCore.NodeServices.HostingModels.NodeServicesOptionsExtensions.<>c__DisplayClass0_0.<UseHttpHosting>b__0()
   at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.GetOrCreateCurrentNodeInstance()
   at Microsoft.AspNetCore.NodeServices.NodeServicesImpl.<InvokeExportWithPossibleRetryAsync>d__10`1.MoveNext()}	System.Exception {System.InvalidOperationException}

May be I can somehow configure webpack to work with docker?

I use Docker for Windows:

Client:
Version: 17.03.0-ce
API version: 1.26
Go version: go1.7.5
Git commit: 60ccb22
Built: Thu Feb 23 10:40:59 2017
OS/Arch: windows/amd64

Server:
Version: 17.03.0-ce
API version: 1.26 (minimum version 1.12)
Go version: go1.7.5
Git commit: 3a232c8
Built: Tue Feb 28 07:52:04 2017
OS/Arch: linux/amd64
Experimental: true

I have installed Node locally and have try to install it to the docker image, but no luck.

@attilaersek
Copy link

Yes, it's possible to use it, but you have to change a few bits.
First, change your dockerfile to include nodejs installation:

FROM microsoft/aspnetcore:1.1
RUN curl -sL https://deb.nodesource.com/setup_7.x | bash -
RUN apt-get install -y build-essential nodejs

Than you have to expose the HMR port in the dockerfile:

ENV ASPNETCORE_URLS http://*:5000
EXPOSE 5000 5001

(in this example I expose 5000 for http and 5001 for hmr traffic)

modify your startup.cs to explicitly set the hmr port:

                app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
                    HotModuleReplacement = true,
                    HotModuleReplacementServerPort = 5001,
                });

and finally, if you're using vs2017 docker tools, you have to change the docker-compose.override.yml:

    ports:
      - "5000:5000"
      - "5001:5001"

Hope it helped! It works like charm with one exception: because the source files are mapped as a volume into the container, changing them outside of the container will not trigger file change detection. you have to reload the page.

@zeusapps
Copy link
Author

zeusapps commented Mar 27, 2017

@retk, thanks for your answer.

I've tried your suggestion. Now I have no error at startup and even Chrome dev tools said that [HRM] is connected, but changes to html or ts does not display even after hard reload. Only app restart helps with refresh.

What I want to do is a couple of api apps like microservices, one app with Angular fron-end, everything as docker containers and nginx as reverse-proxy also as container.

@attilaersek
Copy link

It seems that webpack does not play nice with newer nodejs versions. Reverting back to LTS should fix your issue. Apply the following change in dockerfile:

RUN curl -sL https://deb.nodesource.com/setup_6.x | bash -

@zeusapps
Copy link
Author

zeusapps commented Mar 28, 2017

@retk, I've updated Dockerfile, but no luck again.

Also I've noticed that HMR goes to port 5000 even if port 5001 specified in WebpackDevMiddlewareOptions

Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr  
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET http://localhost:5000/__webpack_hmr  
[40m[32minfo[39m[22m[49m: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]

I create repo with test project https://github.com/zeusapps/DockerWebpack

@attilaersek
Copy link

Ok, it seems that either webpack or something else changed as webpack does not detect changes on reload too. FYI the underlying issue is this: moby/moby#30105

One possible solution could be to enable polling on webpack as mentioned in the linked issue, but not sure how to do this.

about HMR: webpacks HMR module is downloaded from the application through http but it will use the port you've set to communicate.

@zeusapps
Copy link
Author

I believe that DOTNET_USE_POLLING_FILE_WATCHER=1 do the trick but it dont.

I've try to manually go to http://localhost:5001/__webpack_hmr but only 5000 port get output back.

@SteveSandersonMS
Copy link
Member

Also I've noticed that HMR goes to port 5000

Yes, the ASP.NET Core application receives the /__webpack_hmr request and proxies to to Webpack dev middleware. This means you don't need to set HotModuleReplacementServerPort or expose it externally from your Docker config. It just connects properly in the default config.

I believe that DOTNET_USE_POLLING_FILE_WATCHER=1 do the trick but it dont.

I don't think that will help, because it's Node that needs to detect the file changes, not .NET.

The workaround that angular-cli people recommend is to configure Webpack to poll for changes, rather than expecting the OS to issue change notifications. Apparently you can do that in your Webpack config using the watchOptions option (e.g., set it to poll: 1000 to check for updates once per second).

Closing because this is an external issue (in Docker) and the workaround mentioned here (poll) is the best resolution we have. Hope that's OK!

@zeusapps
Copy link
Author

zeusapps commented Mar 29, 2017

@SteveSandersonMS , thanks for your reply. Could you please help where to put watchOptions? I add it to the sharedConfig, but it have no effect.

UPDATE
Looks like it works if manually attach to running container and call node ./node_modules/webpack/bin/webpack.js --config webpack.config.js.
If then refresh changes are shown, but instantly revert back.

@SteveSandersonMS
Copy link
Member

Hmm, I would have thought sharedConfig was the right place, because from the look of the Webpack docs, it appears they want you to make it a top-level property in the returned config object. Maybe it needs to go somewhere else, or maybe it's just not adequate as a workaround (even though the angular-cli people say it is).

You could ask the Webpack folks to clarify their docs, or - for a quicker result - grep through the Webpack source code to see where it tries to read watchOptions from and what it then does with that setting. Sorry this is inconvenient - I'm afraid this is life in the world of front-end web dev!

@pglazkov
Copy link
Contributor

pglazkov commented Apr 6, 2017

@SteveSandersonMS,
I couldn't make the watchOptions workaround to work. This option seem to be ignored.

I did a little bit of research and it looks like the watchOptions have to be provided as part of the compiler.watch call, but they are not provided in the aspnet-webpack package. See the following line: https://github.com/aspnet/JavaScriptServices/blob/dev/src/Microsoft.AspNetCore.SpaServices/npm/aspnet-webpack/src/WebpackDevMiddleware.ts#L210

I suppose a possibile solution would be to pass the watchOptions as part of the UseWebpackDevMiddleware call.

@zeusapps
Copy link
Author

zeusapps commented Apr 6, 2017

Hi, @pglazkov.

I also have no luck with making this work. What I came with is if you as me want to have container per task (front-end, api, nginx) it's just a metter of using wrong tool (meaning JavaScriptServices). I use Angular-cli for manage front-end, there are a couple of good articles how to make it work with HMR and Docker. And ordinary Web-API Asp.Net Core app.
If you want to have single project for front-end and back-end you can just debug it without Docker, and use Docker only for production.

Hope it help you.

SteveSandersonMS pushed a commit that referenced this issue Apr 11, 2017
…leware (#806)

This enables Docker HMR workflow and the workaround mentioned in this comment: #806 (comment)
@eino-makitalo
Copy link

eino-makitalo commented Sep 14, 2017

Where to inform that when adding docker support to aspnetcore application in Visual Studio 2017 using react redux... it does not create Dockerfile file where node is included.

@mxa0079
Copy link

mxa0079 commented Jan 29, 2018

Could MS provide a detailed article on how to configure VSCode, Docker, Angular, and HMR? The available information is scattered and scarced.

@SteveSandersonMS
Copy link
Member

@mxa0079 To request changes to docs, please post an issue at https://github.com/aspnet/docs

@jennet
Copy link

jennet commented Mar 7, 2018

For me the problem getting HMR to work was not any of the settings, but the issue with file changes on shared drives using Docker For Windows. I'm currently running Docker Watcher during dev when I want HMR

I did not need to change any Docker, webpack or WebpackDevMiddlewareOptions config. (or rather I tried loads, found Docker Watcher, and removed all changes back to the OOB settings from the .NET Core / AngularX template. I did need to install node as part of the Docker setup otherwise webpack doesn't work, but didn't need to expose any ports or anything)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants