Webpacker: pack_tags don't pick up custom host when running webpack-dev-server

Created on 26 Sep 2017  ·  25Comments  ·  Source: rails/webpacker

Steps to reproduce

  1. Clone the dummy-webpacker-app I made for this issue
  2. Follow short README instructions.
    FYI, this app uses Invoker, which is like Foreman but with .dev domains and https support. Here is the content of the Procfile:
    app: bundle exec rails server -p $PORT webpacker: ./bin/webpack-dev-server --https --host webpacker.dev --port $PORT
  3. Go to http://app.dev

Actual

javascript_pack_tag produces the following:

<script src="/packs/application-c5994df31b2a76c55e0a.js"></script>

The browser console complains that it cannot find http://app.dev/packs/application-c5994df31b2a76c55e0a.js. No JS is executed.

Expected

javascript_pack_tag should produce the following (assuming that Invoker chose to use port 9001 for the webpacker process):

<script src="https://webpacker.dev:9001/packs/application-c5994df31b2a76c55e0a.js"></script>

and the browser console output should read Hello World from Webpacker.

Comments

Everything works well if I don't use webpacker-dev-server and let the rails server handle everything.
Everything works well if I just run ./bin/webpack-dev-server manually without any arguments.

The issue came up with Webpacker 3. I had no issue with Webpacker 2.

Most helpful comment

Solved here as well.

docker-compose.yml

version: '3'

services:
  webpacker:
    build: .
    command: bundle exec bin/webpack-dev-server
    environment:
      - WEBPACKER_DEV_SERVER_HOST=0.0.0.0
    volumes:
      - .:/app
    ports:
      - 8080:8080

  app:
    build: .
    command: /bin/sh -c "rm -f /app/tmp/pids/server.pid && rails server -b 0.0.0.0"
    working_dir: /app 
    environment:
      - RAILS_ENV=development
      - BUNDLE_JOBS=15
      - BUNDLE_RETRY=3
      - WEBPACKER_DEV_SERVER_HOST=webpacker
    volumes:
      - .:/app
    ports:
      - 3000:3000
    links:
      - postgres
    depends_on:
      - webpacker

  postgres:
    image: postgres:9.4
    volumes:
      - /var/lib/postgresql/data
    ports:
      - 5432:5432

webpacker.yml

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs
  cache_path: tmp/cache/webpacker

  # resolved_paths: ['app/assets']

  extensions:
    - .coffee
    - .erb
    - .js
    - .jsx
    - .ts
    - .vue
    - .sass
    - .scss
    - .css
    - .png
    - .svg
    - .gif
    - .jpeg
    - .jpg

development:
  <<: *default

  dev_server:
    https: false
    host: 0.0.0.0
    port: 8080
    public: 0.0.0.0:8080
    hmr: false
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    disable_host_check: true
    use_local_ip: false

test:
  <<: *default

  public_output_path: packs-test

production:
  <<: *default

Thanks guys

All 25 comments

@jeromedalbert There is a PR merged on master (to override public option) but yet to be released which consolidates all arguments into one: #843 and allows overriding using env variables instead. Previously, we kinda of had supported everything which made it difficult to manage these options internally, like if you are passing args through CLI but the ruby gem won't know about it etc.

So, if you are using master for both gem and npm module you can run it like so:

app: bundle exec rails server -p $PORT
webpacker: WEBPACKER_DEV_SERVER_HOST=0.0.0.0 WEBPACKER_DEV_SERVER_PUBLIC=webpacker.dev WEBPACKER_DEV_SERVER_PORT=$PORT WEBPACKER_DEV_SERVER_HTTPS=true ./bin/webpack-dev-server

or you could set these env vars in your .env file or something if you are using foreman (which picks up env variable when running processes)

These settings are also available inside webpacker.yml if you install from master branch i.e. bundle exec rails webpacker:install

I have updated the gem to the latest master, as well as the npm package with yarn add https://github.com/rails/webpacker#master (not sure this is the correct way to do it). Cf this diff in my dummy app.

When I try your suggestion code above, the webpack-dev-server process doesn't seem to pick up the WEBPACKER_DEV_SERVER_X env options, it just uses default values from webpacker.yml.

I think I am doing something wrong but I can't figure out what it is.

Please could you update binstubs: bundle binstubs webpacker --force

Thanks I was missing the binstub, now the ENV options are picked up by the webpack-dev-server process.

The original problem still persists: javascript_pack_tag doesn't point to my webpacker.dev dev server, so no javascript gets loaded.

Don't know if this helps, but here is my public/packs/manifest.json:

{
  "application.js": "/packs/application-646d2e5a8a7a5d6f2ecf.js"
}

And looking at the webpacker ruby source code, the pack_tags get their value from sources_from_pack_manifest / Webpacker.manifest.lookup, which looks up the manifest.json above.

Should the ruby code prepend the looked up path with the dev_server address? Or should the dev server address be directly in the manifest.json path?

@jeromedalbert You don't need to set host for webpack dev server:

app: bundle exec rails server -p $PORT
webpacker: ./bin/webpack-dev-server

BTW, forgot to mention - you won't get full urls with dev server, the internal proxy will route that for you: https://github.com/rails/webpacker/blob/master/lib/webpacker/dev_server_proxy.rb#L11

For HTTPS:

app: bundle exec rails server -p $PORT
webpacker: WEBPACKER_DEV_SERVER_HTTPS=true ./bin/webpack-dev-server

For custom domain for dev server:

app: bundle exec rails server -p $PORT
webpacker: WEBPACKER_DEV_SERVER_PUBLIC=app.dev:3035 WEBPACKER_DEV_SERVER_HOST=0.0.0.0 WEBPACKER_DEV_SERVER_HTTPS=true ./bin/webpack-dev-server

although you will get SSL error in your console, just open the dev server link and accept the exception.

app dev

Lets keep this open until a new version is released.

You're right, I don't need to set a webpacker particular host, I just need https through any host for one of my apps, and proxying through app.dev works just as well.

I can see that it works for you in your GIF, but for me when an https request is done to https://app.dev/packs/application-xxxxxxxxxxxxxxxxxxxx.js, I get the following stack trace:

Puma caught this error: SSL_connect SYSCALL returned=5 errno=0 state=SSLv2/v3 read server hello A (OpenSSL::SSL::SSLError)
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/2.4.0/net/protocol.rb:44:in `connect_nonblock'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/2.4.0/net/protocol.rb:44:in `ssl_socket_connect'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/2.4.0/net/http.rb:948:in `connect'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/2.4.0/net/http.rb:887:in `do_start'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/2.4.0/net/http.rb:882:in `start'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rack-proxy-0.6.2/lib/rack/http_streaming_response.rb:71:in `session'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rack-proxy-0.6.2/lib/rack/http_streaming_response.rb:60:in `response'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rack-proxy-0.6.2/lib/rack/http_streaming_response.rb:29:in `headers'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rack-proxy-0.6.2/lib/rack/proxy.rb:120:in `perform_request'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/bundler/gems/webpacker-bb6d126caa88/lib/webpacker/dev_server_proxy.rb:15:in `perform_request'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/rack-proxy-0.6.2/lib/rack/proxy.rb:57:in `call'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/railties-5.1.4/lib/rails/engine.rb:522:in `call'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/puma-3.10.0/lib/puma/configuration.rb:225:in `call'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/puma-3.10.0/lib/puma/server.rb:605:in `handle_request'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/puma-3.10.0/lib/puma/server.rb:437:in `process_client'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/puma-3.10.0/lib/puma/server.rb:301:in `block in run'
/Users/jerome/.rbenv/versions/2.4.2/lib/ruby/gems/2.4.0/gems/puma-3.10.0/lib/puma/thread_pool.rb:120:in `block in spawn_thread'

(Maybe related: I am using macOS High Sierra released yesterday, and I recently updated my ruby version to 2.4.2)

Does it work without https?

Nevermind, I must have done something wrong, it works! 👍 Thanks for your help & patience!

I ended up with your first suggestion:

app: bundle exec rails server -p $PORT
webpacker: WEBPACKER_DEV_SERVER_HTTPS=true ./bin/webpack-dev-server

and made sure to access https://app.dev through https for everything to work.

Awesome 👍

The same issue. I use:

  • Rails 5.1.4
  • webpacker gem from master branch (78b2dd9106034f5ddfc8ee021851143fb64dfdc8)
  • @rails/webpacker package from master branch (78b2dd9106034f5ddfc8ee021851143fb64dfdc8)

Usually it doesn't work:

webpack_1  |                               Asset      Size  Chunks                    Chunk Names        
webpack_1  | application-ca7a775c6e9b8dc4c8db.js    899 kB       0  [emitted]  [big]  application        
webpack_1  |                       manifest.json  68 bytes          [emitted]                            
webpack_1  |   [34] multi (webpack)-dev-server/client?http://localhost:3035 ./app/javascript/packs/application.js 40 bytes {0} [built]                                                                             
webpack_1  |   [35] (webpack)-dev-server/client?http://localhost:3035 7.23 kB {0} [built]                
webpack_1  |   [36] ./node_modules/url/url.js 23.3 kB {0} [built]                                        
webpack_1  |   [37] ./node_modules/punycode/punycode.js 14.7 kB {0} [built]                              
webpack_1  |   [42] ./node_modules/strip-ansi/index.js 161 bytes {0} [built]                             
webpack_1  |   [44] ./node_modules/loglevel/lib/loglevel.js 7.74 kB {0} [built]                          
webpack_1  |   [45] (webpack)-dev-server/client/socket.js 1.04 kB {0} [built]                            
webpack_1  |   [78] (webpack)-dev-server/client/overlay.js 3.73 kB {0} [built]                           
webpack_1  |   [79] ./node_modules/ansi-html/index.js 4.26 kB {0} [built]                                
webpack_1  |   [80] ./node_modules/html-entities/index.js 231 bytes {0} [built]                          
webpack_1  |   [83] (webpack)/hot nonrecursive ^\.\/log$ 170 bytes {0} [built]                                                
webpack_1  |   [84] (webpack)/hot/log.js 1.04 kB {0} [optional] [built]                                  
webpack_1  |   [85] (webpack)/hot/emitter.js 77 bytes {0} [built]                                        
webpack_1  |   [86] ./node_modules/events/events.js 8.33 kB {0} [built]                                  
webpack_1  |   [87] ./app/javascript/packs/application.js 515 bytes {0} [built]                          
webpack_1  |     + 73 hidden modules                                                                     
webpack_1  | webpack: Compiled successfully.                                                             
app_1      | Started GET "/" for 172.18.0.1 at 2017-10-02 08:00:06 +0000                                 
app_1      | Processing by ApplicationController#index as HTML                                           
app_1      |   Rendering application/index.html.erb within layouts/application                           
app_1      |   Rendered application/index.html.erb within layouts/application (11.5ms)                   
app_1      | Completed 200 OK in 5137ms (Views: 3909.5ms)                                                
app_1      |                                                                                             
app_1      |                                                                                             
app_1      | Started GET "/packs/application-ca7a775c6e9b8dc4c8db.js" for 172.18.0.1 at 2017-10-02 08:00:11 +0000                                                                                                  
app_1      |                                                                                             
app_1      | ActionController::RoutingError (No route matches [GET] "/packs/application-ca7a775c6e9b8dc4c8db.js"):                                                                                                 

But it works if I save packs/application.js and then make a request:

webpack_1  | webpack: Compiling...
webpack_1  | Hash: 30d14d0f98ffcd4e747d
webpack_1  | Version: webpack 3.6.0
webpack_1  | Time: 47ms
webpack_1  |                               Asset      Size  Chunks                    Chunk Names
webpack_1  | application-ca7a775c6e9b8dc4c8db.js    899 kB       0             [big]  application
webpack_1  |                       manifest.json  68 bytes          [emitted]
webpack_1  |   [34] multi (webpack)-dev-server/client?http://localhost:3035 ./app/javascript/packs/application.js 40 bytes {0}
webpack_1  |   [35] (webpack)-dev-server/client?http://localhost:3035 7.23 kB {0}
webpack_1  |   [36] ./node_modules/url/url.js 23.3 kB {0}
webpack_1  |   [37] ./node_modules/punycode/punycode.js 14.7 kB {0}
webpack_1  |   [42] ./node_modules/strip-ansi/index.js 161 bytes {0}
webpack_1  |   [44] ./node_modules/loglevel/lib/loglevel.js 7.74 kB {0}
webpack_1  |   [45] (webpack)-dev-server/client/socket.js 1.04 kB {0}
webpack_1  |   [78] (webpack)-dev-server/client/overlay.js 3.73 kB {0}
webpack_1  |   [79] ./node_modules/ansi-html/index.js 4.26 kB {0}
webpack_1  |   [80] ./node_modules/html-entities/index.js 231 bytes {0}
webpack_1  |   [83] (webpack)/hot nonrecursive ^\.\/log$ 170 bytes {0} [built]
webpack_1  |   [84] (webpack)/hot/log.js 1.04 kB {0} [optional]
webpack_1  |   [85] (webpack)/hot/emitter.js 77 bytes {0}
webpack_1  |   [86] ./node_modules/events/events.js 8.33 kB {0}
webpack_1  |   [87] ./app/javascript/packs/application.js 515 bytes {0} [built]
webpack_1  |     + 73 hidden modules
webpack_1  | webpack: Compiled successfully.
app_1      | Started GET "/" for 172.18.0.1 at 2017-10-02 08:00:18 +0000
app_1      | Processing by ApplicationController#index as HTML
app_1      |   Rendering application/index.html.erb within layouts/application
app_1      | [Webpacker] Compiling…
app_1      | [Webpacker] Compiled all packs in /app/public/packs
app_1      |   Rendered application/index.html.erb within layouts/application (2863.8ms)
app_1      | Completed 200 OK in 2918ms (Views: 2908.0ms)

What do I do wrong?

Are you using invoker and such or just rails server?

What does mean invoker? I use docker + docker-compose. Here is docker-compose.yml:

version: '3'

services:
  webpack:
    image: evserykh/rails:ruby2.3
    volumes:
      - .:/app:cached
    working_dir: /app
    ports:
      - 3035:3035
    environment:
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
      WEBPACKER_DEV_SERVER_PUBLIC: localhost:3035
    command: /bin/bash -c './bin/yarn && ./bin/webpack-dev-server'

  app:
    image: evserykh/rails:ruby2.3
    volumes:
      - .:/app:cached
      - .bundle:/usr/local/bundle:cached
    working_dir: /app
    ports:
      - 3000:3000
    command: /bin/bash -c 'rm -rf tmp/pids/server.pid && bundle exec rails s -b 0.0.0.0'

I tried with WEBPACKER_DEV_SERVER_* variables and without them. It seems env variables doesn't make any impact

I guess in my case Docker is guilty. What I found out:
here is place where webpack-dev-server is checked whether webpack-dev-server is running or not. As I use Docker I run rails server and webpack-dev-server in different containers, and I have to use 0.0.0.0 as host for webpack-dev-server. So rails container can't check is host 0.0.0.0 opens any port and the checking returns false and I can't get compiled file.

@evserykh Ahh I see, were you able to fix it?

3.0.2 released. Closing 👍

@gauravtiwari I fixed it editing my docker-compose.yml and all works fine.
Important things are --listen-host and --disable-host-check for webpack container and WEBPACKER_DEV_SERVER_HOST env var for web container.
Now my docker-compose.yml looks like this:

version: '3'                                                                                                               

services:                                                                                                                  
  webpack:                                                                                                                 
    image: evserykh/rails:ruby2.3                                                                                          
    volumes:                                                                                                               
      - .:/app:cached                                                                                                      
    working_dir: /app                                                                                                      
    entrypoint: ./docker-entrypoint.sh                                                                                     
    command: /bin/bash -c './bin/yarn && ./bin/webpack-dev-server --listen-host 0.0.0.0 --disable-host-check'              
    ports:                                                                                                                 
      - 3035:3035                                                                                                          

  web:                                                                                                                     
    image: evserykh/rails:ruby2.3                                                                                          
    depends_on:                                                                                                            
      - webpack                                                                                                            
    volumes:                                                                                                               
      - .:/app:cached                                                                                                      
      - .bundle:/usr/local/bundle:cached                                                                                   
    working_dir: /app                                                                                                      
    entrypoint: ./docker-entrypoint.sh                                                                                     
    environment:                                                                                                           
      WEBPACKER_DEV_SERVER_HOST: webpack                                                                                   
    command: /bin/bash -c 'rm -rf tmp/pids/server.pid && bundle exec rails s -b 0.0.0.0'                                   
    ports:                                                                                                                 
      - 3000:3000 

Great 👍

In 3.0.2, we removed --listen-host and other CLI args to avoid confusion. Just use WEBPACKER_DEV_SERVER_HOST: 0.0.0.0 to override host and WEBPACKER_DEV_SERVER_DISABLEHOSTCHECK is also available as env variable.

I'm having the same issue. Adding WEBPACKER_DEV_SERVER_HOST doesn't seems to help.
My docker is:

version: '3'
services:
  db:
    image: postgres
  webpacker:
    build: .
    environment:
      - WEBPACKER_DEV_SERVER_HOST=0.0.0.0
    command: bundle exec bin/webpack-dev-server
    volumes:
      - .:/app
    ports:
      - "3035:3035"
  web:
    build: .
    command: bundle exec rails s -p 4000 -b '0.0.0.0'
    volumes:
      - .:/app
    ports:
      - "4000:4000"
    depends_on:
      - db

after going up, I get:

web_1        | [6] * Listening on tcp://0.0.0.0:4000
web_1        | [6] Use Ctrl-C to stop
webpacker_1  |  10% building modules 2/2 modules 0 active
webpacker_1  | Project is running at http://localhost:3035/

@hovancik Try to add WEBPACKER_DEV_SERVER_HOST: webpacker to your web service

Thanks, that worked. I've also had to edit webpack settings:

  dev_server:
    https: false
    host: 0.0.0.0
    port: 3035
    public: 0.0.0.0:3035
    hmr: false
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    disable_host_check: true
    use_local_ip: false

My docker looks like this, now:

version: '3'
services:
  db:
    image: postgres
  webpacker:
    build: .
    environment:
      WEBPACKER_DEV_SERVER_HOST: 0.0.0.0
    command: bundle exec bin/webpack-dev-server
    volumes:
      - .:/app
    ports:
      - "3035:3035"
  web:
    build: .
    environment:
      WEBPACKER_DEV_SERVER_HOST: webpacker
    command: bash -c "rm -rf ./tmp/pids/server.pid && bundle exec rails s -p 4000 -b '0.0.0.0'"
    volumes:
      - .:/app
    ports:
      - "4000:4000"
    depends_on:
      - db

Solved here as well.

docker-compose.yml

version: '3'

services:
  webpacker:
    build: .
    command: bundle exec bin/webpack-dev-server
    environment:
      - WEBPACKER_DEV_SERVER_HOST=0.0.0.0
    volumes:
      - .:/app
    ports:
      - 8080:8080

  app:
    build: .
    command: /bin/sh -c "rm -f /app/tmp/pids/server.pid && rails server -b 0.0.0.0"
    working_dir: /app 
    environment:
      - RAILS_ENV=development
      - BUNDLE_JOBS=15
      - BUNDLE_RETRY=3
      - WEBPACKER_DEV_SERVER_HOST=webpacker
    volumes:
      - .:/app
    ports:
      - 3000:3000
    links:
      - postgres
    depends_on:
      - webpacker

  postgres:
    image: postgres:9.4
    volumes:
      - /var/lib/postgresql/data
    ports:
      - 5432:5432

webpacker.yml

default: &default
  source_path: app/javascript
  source_entry_path: packs
  public_output_path: packs
  cache_path: tmp/cache/webpacker

  # resolved_paths: ['app/assets']

  extensions:
    - .coffee
    - .erb
    - .js
    - .jsx
    - .ts
    - .vue
    - .sass
    - .scss
    - .css
    - .png
    - .svg
    - .gif
    - .jpeg
    - .jpg

development:
  <<: *default

  dev_server:
    https: false
    host: 0.0.0.0
    port: 8080
    public: 0.0.0.0:8080
    hmr: false
    # Inline should be set to true if using HMR
    inline: true
    overlay: true
    disable_host_check: true
    use_local_ip: false

test:
  <<: *default

  public_output_path: packs-test

production:
  <<: *default

Thanks guys

Was this page helpful?
0 / 5 - 0 ratings

Related issues

towry picture towry  ·  3Comments

ankitrg picture ankitrg  ·  3Comments

Eearslya picture Eearslya  ·  3Comments

pioz picture pioz  ·  3Comments

christianrojas picture christianrojas  ·  3Comments