Proxy Requests to Other Processes During Rails Development

DocSpring is a Ruby on Rails application, but our blog is powered by Hugo, and we use GitBook for documentation. Rails runs on port 3000 during development, the Hugo server runs on port 1313, and GitBook runs on port 4000.

It’s totally fine to visit http://localhost:1313/blog while working on a blog post. But it would be nice if the “Blog” link isn’t broken on the homepage during development, and if I could click relative links to jump between the blog, docs, and the Rails app. (I keep everything on the same subdomain, because I’ve heard that this can be good for SEO.)

I added the rack-reverse-proxy gem to the development group in my Gemfile:

group :development do
  gem 'rack-reverse-proxy', require: 'rack/reverse_proxy'
end

Then I added the following code to config/environments/development.rb:

  config.middleware.sinsert(0, Rack::ReverseProxy) do
    reverse_proxy '/blog', 'http://localhost:1313'
    reverse_proxy '/livereload.js', 'http://localhost:1313/livereload.js'
    reverse_proxy /^\/docs(\/?.*)$/, 'http://localhost:4000$1'
  end

That’s it! Now I can visit http://localhost:3000/blog, and Hugo’s live reloading even works (it still connects on port 1313). I can also visit http://localhost:3000/docs to access the GitBook dev server.

(Note: I needed to add a serverPath option to GitBook to fix the URLs during development. I use "serverPath": "/docs" in book.json.)

There might not be much benefit to doing this, but it’s very easy to set up with a few lines of code. And it’s always good when your development environment is close to production.

You could also use rack-reverse-proxy to proxy things in production, but I would recommend doing that in Nginx instead of your Rails application.