Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Docker] ViteRuby#dev_server_running? always return false when rails and vite run in different containers with skipProxy: true #391

Open
100terres opened this issue Aug 4, 2023 · 3 comments

Comments

@100terres
Copy link

100terres commented Aug 4, 2023

Is your feature request related to a problem? Please describe.

ViteRuby#dev_server_running? always return false when rails and vite run in different containers with skipProxy: true. We can't set the VITE_RUBY_HOST to the name of the vite container, since it need to be something like localhost for the dev server to be reachable from the browser, because we are skipping the proxy. With this configuration ViteRuby#dev_server_running? isn't able to resolve the dev server and assume that it is not running.

Describe the solution you'd like

One solution could be to have a config/env to set the reachable host from the backend code e.g. VITE_RUBY_HOST_FROM_BACKEND and use it here:

Socket.tcp(config.host, config.port, connect_timeout: config.dev_server_connect_timeout).close

Describe alternatives you've considered

Instead of checking network to see if the dev server is running, maybe we could create a file somewhere when starting the dev server and remove it when closing the dev server. To know if the dev server is running we check if the file exist or not, but that solution come with other issues.

Additional context

Here's a monkey patch we are using to bypass the current limitation:

module MonkeypatchDevServerRunning
  module InstanceMethods
    # original method: https://github.com/ElMassimo/vite_ruby/blob/6249f3b8385c89c6e5f05ad94384cae53d1e5b5d/vite_ruby/lib/vite_ruby.rb#L84-L98
    def dev_server_running?
      return super unless config.skip_proxy
      return false unless run_proxy?
      return @running if defined?(@running) && Time.now - @running_checked_at < 1

      begin
        Socket.tcp(ENV["VITE_RUBY_HOST_FROM_BACKEND"] || config.host, config.port, connect_timeout: config.dev_server_connect_timeout).close
        @running = true
      rescue StandardError
        @running = false
      ensure
        @running_checked_at = Time.now
      end
    end
  end

  class << self
    def apply_patch
      const = find_const
      mtd = find_method(const)

      unless const && mtd && mtd.arity == 0
        raise "Could not find class or method when patching ViteRuby#dev_server_running?. Please investigate."
      end

      unless vite_ruby_version_ok?
        puts "WARNING: It looks like ViteRuby has been upgraded since ViteRuby#dev_server_running? was monkeypatched in #{__FILE__}. Please reevaluate the patch."
      end

      const.prepend(InstanceMethods)
    end

    private

    def find_const
      Kernel.const_get('ViteRuby')
    rescue NameError
    end

    def find_method(const)
      return unless const
      const.instance_method(:dev_server_running?)
    rescue NameError
    end

    def vite_ruby_version_ok?
      version = Gem::Version.create(ViteRuby::VERSION)

      # The skipProxy config was added in version 3.2.12
      # see: https://github.com/ElMassimo/vite_ruby/compare/vite_ruby@3.2.11...vite_ruby@3.2.12
      version >= "3.2.12" && version < "4.0.0"
    end
  end
end

# ...

MonkeypatchDevServerRunning.apply_patch
@majkelcc
Copy link

majkelcc commented Oct 5, 2023

I recently migrated to Vite and faces the same issue, but my solution was different - not to rely on autoBuild at any point, which imho is better to be disabled. Posting my setup for consideration:

  • I'm always running Vite server manually in a different container, so my autoBuild is set to false in config/vite.json
  • In dev I'm always running vite server in a separate container, so dev_server_running? can be monkey patched to return Rails.env.development?
  • For tests in my test_helper.rb I'm building all assets upfront if they are stale (checking ViteRuby.instance.builder.last_build_metadata.stale?)
  • Not using the proxy middleware in dev, hitting Vite's server directly

That being said, I agree that there should be a way to set something like VITE_RUBY_HOST_FROM_BACKEND to keep autoBuild working correctly.

@elthariel
Copy link
Contributor

Yeah, running with container ATM is a PITA. I'm using a docker compose setup with vite running as separate container behing a traefik proxy, and I had to hack a little bit to make it work:

  • Monkey patched ViteRuby.dev_server_running?
  • Used the external host value in vite.json port entry
  • Forced 0.0.0.0 as VITE_RUBY_HOST on the vite container
  • Set skipProxy to true

@elthariel
Copy link
Contributor

Another annoying bit, when skipProxy is set to true, vite-ruby overrides the server.origin option, which sets it to 0.0.0.0, overriding the value from the vite.config.js which was properly setup to my dev dns :-/

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

No branches or pull requests

3 participants