Home » Nodejs » Rails and Node in the same app on Heroku?

Rails and Node in the same app on Heroku?

Posted by: admin November 30, 2017 Leave a comment


I’m building a Rails application that deals with file uploads through CarrierWave. Currently, larger file uploads block the server for a significant amount of time. I have seen solutions like the s3-swf-upload-plugin gem that skip the local server and send files straight from the browser to S3, but this would require some modifications for pre-generating unique filenames and synchronizing them with the database. I’m sure it wouldn’t be too much trouble, but Heroku’s new Cedar stack gave me the idea of offloading these long running requests to a node.js instance running in the same app. I’m not very experienced with these kinds of things, so excuse my wording if it’s a bit off.

Would something like this be possible? How would you configure things such that certain requests (ones involving file uploads, in this case) would be handled by a node app bundled in the same heroku repository as the main rails app?


I don’t think it’s possible to mix Rails and Node in the same app. However, you could get roughly the same functionality by using two separate apps that communicate with each other.

You can use ENV[‘DATABASE_URL’] to determine your database connection string. Use the heroku console to set it as an ENV variable for your Node app (e.g. heroku config:add OTHER_DB=your_connection_string) should then be able to use the same connection string to connect to the same database from your other heroku app. You could even access it outside of heroku if you have a dedicated database, see: http://devcenter.heroku.com/articles/external-database-access

For seamless integration between the two apps, you could have a form rendered by the Rails app post to a URL of the Node app. In addition to the file upload, include in that form via hidden input fields any other variables you need to communicate to the Node app. When the upload to the Node app is done, it could redirect the client back to the Rails app, passing any status or variables as get parameters.

Run the two apps under two subdomains of the same domain and you could even share cookies between them.


You need two apps. I am doing exactly what’s described in this question. I wanted large streaming uploads, and since Rack writes downloads to a temp file before passing them through to the handler, it is not possible to do this with Rails.

Node.js, on the other hand, does this beautifully. So there are two Heroku apps, the Rails web app and the Node.js (Express) web app. The Rails web app uses SWFUpload as the client-side solution. The Rails app and the Node.js app both have a secret key as a Heroku config variable. When it’s time for the user to upload, client-side Javascript requests an upload URL from the Rails server. The Rails server forms an upload URL with an Expires parameter and computes a signature using the secret key. The client-side Javascript handler passes this URL along to SWFUpload (upload_url property). The user selects the files to upload, and SWFUpload starts posting them to the upload_url. The Node.js app verifies that the URL is not expired and that the signature is valid. It processes the form data with the formidable library.

One other detail. Flash requires the Node.js app to serve a crossdomain.xml that permits the cross-site request.

My Node.js app doesn’t touch the database; but if it did I would share DATABASE_URL as previously suggested. Note that you can’t share a DATABASE_URL outside of Heroku unless you have a dedicated DB. The DATABASE_URLs for shared databases are not reachable from outside Heroku (unlike some other services like RedisToGo).