docs/oss/building-features/node-renderer/heroku.md
Pro Feature — Available with React on Rails Pro. Free or very low cost for startups and small companies. Upgrade or licensing details →
Most React on Rails Pro installations of the Node SSR Renderer will deploy the Rails and Renderer instances on the same server. This technique results in better performance since it avoids network latency.
Scroll down if you want to have different servers.
/Procfile
web: bin/runsvdir-dyno
/Procfile.web
Your /Procfile.web should keep the puma line and use the renderer line that matches your
package manager:
| Package manager | renderer line |
|---|---|
| npm | renderer: npm run node-renderer |
| yarn | renderer: yarn run node-renderer |
| pnpm | renderer: pnpm run node-renderer |
For example, a complete /Procfile.web using pnpm:
puma: bundle exec puma -C config/puma.rb
renderer: pnpm run node-renderer
Define the script in your root package.json so Heroku can run it from the app root:
{
"scripts": {
"node-renderer": "node client/node-renderer.js"
}
}
Note: The script above relies on the default
port: process.env.RENDERER_PORT || 3800in the JS configuration example. That default is fine for the same-dyno deployment above. If you deploy the renderer as a separate Heroku app, switch the renderer config toprocess.env.PORTinstead ofRENDERER_PORT.
Be sure your node-renderer script listens on the same port as the Rails config.renderer_url
value, for example http://localhost:3800.
Not necessary if you are using bundle caching as doing so will result in the below being done automatically.
To avoid the initial round trip to get a bundle on the renderer, you can do something like this to copy the file during precompile.
See lib/tasks/assets.rake for a couple tasks that you can use.
If you're using the default tmp/bundles subdirectory for the node-renderer, you don't need to set the
ENV value for RENDERER_BUNDLE_PATH. Otherwise, please set this ENV value so the files get copied
to the right place.
Then you can use the rake task: react_on_rails_pro:pre_stage_bundle_for_node_renderer.
You might do something like this:
Rake::Task["assets:precompile"]
.clear_prerequisites
.enhance([:environment, "react_on_rails:assets:compile_environment"])
.enhance do
Rake::Task["react_on_rails_pro:pre_stage_bundle_for_node_renderer"].invoke
end
If you get this sort of error, then you're forgetting to configure the PORT on the node-renderer and setting the config.renderer_url on the Rails App.
bundler: failed to load command: puma (/app/vendor/bundle/ruby/2.6.0/bin/puma)
Errno::EADDRINUSE: Address already in use - bind(2) for "0.0.0.0" port 21752
/app/vendor/bundle/ruby/2.6.0/gems/puma-4.3.3/lib/puma/binder.rb:229:in `initialize'
renderer-test.herokuapp.com.process.env.PORT so it will use port number provided by Heroku environment. The default is to use the env value RENDERER_PORT if available.process.env.RENDERER_PASSWORD and configure the corresponding ENV variable on your Heroku dyno so the config/initializers/react_on_rails_pro.rb uses this value.renderer-test.herokuapp.com host.react_on_rails.initializers/react_on_rails_pro (assuming you have SSL certificate uploaded to your renderer Heroku app or you use Heroku wildcard certificate under *.herokuapp.com) and configure corresponding ENV variable for the render_url and/or password on your Heroku dyno.react_on_rails app should be served by <your-heroku-app>.herokuapp.com app via HTTPS.