3
votes

I want to deploy RoR + React SPA to heroku as one project. As a typical production environment, use Nginx as web server and user Puma as app server.

I tried to follow readme of https://github.com/heroku/heroku-buildpack-nginx.

But after deployment, heroku popup an error

Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch

Below are my configs

heroku buildpacks

heroku/nodejs # index 1
heroku/ruby   # index 2
https://github.com/heroku/heroku-buildpack-nginx.git # index 3

Procfile

release: bundle exec rails db:migrate
web: bin/start-nginx bundle exec puma -C config/puma.rb

config/puma.rb

max_threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 }
min_threads_count = ENV.fetch("RAILS_MIN_THREADS") { max_threads_count }
threads min_threads_count, max_threads_count

environment ENV.fetch("RAILS_ENV") { "development" }
plugin :tmp_restart

bind ENV.fetch('PUMA_SOCK') { 'unix:///tmp/nginx.socket' }

on_worker_fork do
  FileUtils.touch('/tmp/app-initialized')
end

config/nignx.conf.erb => I removed unimportant config for this file because it is too long

http {
    upstream app_server {
        server unix:/tmp/nginx.socket fail_timeout=0;
    }

    server {
        listen <%= ENV["PORT"] %>;
        server_name _;
        keepalive_timeout 5;

        location / {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://app_server;
        }
    }
}
1
Have you resolved this issue? I have project that might follow this directionknd
I failed to put everything to one heroku project. In the end, I split it to 2 diff heroku projects, one for frontend, and the other for backend, using ajax/api/spa way to communicate each other.new2cpp

1 Answers

0
votes

EDIT: I think that the procfile should start Nginx too:

 web: bin/start-nginx bundle exec puma -C config/puma.rb

Remember that for the nginx build pack you should disable the demon mode in the nginx.conf:

daemon off;

EDIT2: If that line doesn't work, try running Nginx directly (this is a hack, untested)):

 web: bin/nginx -p . -c config/nginx.conf & ; bundle exec puma -C config/puma.rb

Also make sure the nginx logs are routed to stdout, placing this in the nginx.conf:

daemon off;
error_log /dev/stdout info;
http {
  access_log /dev/stdout;
  ...
}

ORIGINAL:

As the documentation for the build pack states:

Basically, for webservers that are not designed for efficient, non-blocking I/O, we will benefit from having NGINX to handle all I/O operations

However, Puma is an efficient, non-blocking I/O server. You should be able to use it directly on a Heroku dyno.

The biggest advantage that Nginx could offer a Puma server is dealing with static files - which your configuration doesn't perform.

If you're not using Nginx for static files, you might decide to skip the extra latency added the Nginx proxy. Besides, Heroku's security features should (but might not) cover all the bases Nginx could offer you at this point.

If you need extra speed for static files - some Ruby servers (such as iodine or agoo) provide a fast static file service, allowing you to skip the Nginx layer and reduce latency.