I'm trying to deploy my application to Heroku using Puma. This is my first time using Puma, as this is my first attempt at a "production quality" application. I've added puma as described in the dev center but I'm running into a no method error once deployed. Here's my error from the logs: config/puma.rb:5:in _load_from': undefined method preload_app!' for #<Puma::Configuration::DSL:0x007f89e2686140> (NoMethodError)
I used the suggested configuration in my config\puma.rb:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
as shown in the error above, it seems Heroku has a problem with the preload_app! command. I'm stuck and don't know where to go from here - I have a feeling I somehow miscreated the file - i.e. I just made a new file in my editor rather than from the command line.
This is how we set config/puma.rb up on Heroku using Rails 4.1.0
workers Integer(ENV['PUMA_WORKERS'] || 3)
threads Integer(ENV['MIN_THREADS'] || 1), Integer(ENV['MAX_THREADS'] || 16)
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# worker specific setup
ActiveSupport.on_load(:active_record) do
config = ActiveRecord::Base.configurations[Rails.env] ||
Rails.application.config.database_configuration[Rails.env]
config['pool'] = ENV['MAX_THREADS'] || 16
ActiveRecord::Base.establish_connection(config)
end
end
We keep the workers and threads to a minimum (we are on the free plan).
When I restart our dyno, I get this output in the logs:
2015-03-.. app[web.1]: [3] Puma starting in cluster mode...
2015-03-... app[web.1]: [3] * Version 2.9.1 (ruby 2.1.5-p273), codename: Team High Five
2015-03-... app[web.1]: [3] * Min threads: 1, max threads: 3
2015-03-... app[web.1]: [3] * Environment: production
2015-03-... app[web.1]: [3] * Process workers: 2
2015-03-... app[web.1]: [3] * Preloading application
Related
I have a new, Rails 6 app that I'm trying to deploy to Heroku.
Judging from the deploy log and the logs I'm getting with heroku logs --tail everything seems to work, but when I go to the deployed, herokuapp.com domain, I get the 'No such app' screen.
Here is the latest logs:
2021-11-19T13:45:11.000000+00:00 app[api]: Build succeeded
2021-11-19T13:45:11.060793+00:00 heroku[web.1]: Starting process with command `bundle exec puma -C config/puma.rb`
2021-11-19T13:45:12.126085+00:00 app[web.1]: [4] Puma starting in cluster mode...
2021-11-19T13:45:12.126103+00:00 app[web.1]: [4] * Puma version: 5.5.2 (ruby 3.0.2-p107) ("Zawgyi")
2021-11-19T13:45:12.126103+00:00 app[web.1]: [4] * Min threads: 5
2021-11-19T13:45:12.126104+00:00 app[web.1]: [4] * Max threads: 5
2021-11-19T13:45:12.126104+00:00 app[web.1]: [4] * Environment: production
2021-11-19T13:45:12.126104+00:00 app[web.1]: [4] * Master PID: 4
2021-11-19T13:45:12.126104+00:00 app[web.1]: [4] * Workers: 2
2021-11-19T13:45:12.126127+00:00 app[web.1]: [4] * Restarts: (✔) hot (✖) phased
2021-11-19T13:45:12.126133+00:00 app[web.1]: [4] * Preloading application
2021-11-19T13:45:13.203269+00:00 app[web.1]: [4] * Listening on http://0.0.0.0:54150
2021-11-19T13:45:13.203334+00:00 app[web.1]: [4] Use Ctrl-C to stop
2021-11-19T13:45:13.207647+00:00 app[web.1]: [4] - Worker 0 (PID: 7) booted in 0.0s, phase: 0
2021-11-19T13:45:13.209455+00:00 app[web.1]: [4] - Worker 1 (PID: 9) booted in 0.0s, phase: 0
2021-11-19T13:45:13.336382+00:00 heroku[web.1]: State changed from starting to up
And here's the puma config:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
Which is the one recommended by Heroku in their documentation.
The Procfile is a simple one-liner:
web: bundle exec puma -C config/puma.rb
I also tried the heroku configuration by running PORT=3000 heroku local on my machine and it works wonderfully, but not on Heroku's platform :(
I'm using Rails 6.1.4.1 and ruby 3.0.2
Can you point me at where I could try to find the root of the problem?
Thank you,
Balint
This seems to have been a transient issue. When I came back to the problem a few hours later, it just worked without me having to change anything.
I'm running a rails app on heroku, I have two web dynos.
How can I remove the ! WARNING: Detected 1 Thread(s) started in app boot: warning?
My puma.rb file:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 5)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do |worker_number|
# Worker specific setup for Rails 4.1+
# See: https://devcenter.heroku.com/articles/deploying-rails-applications-with-the-puma-web-server#on-worker-boot
ActiveRecord::Base.establish_connection
end
The logs:
2016-09-03T14:21:24.742960+00:00 app[web.1]: [3] * Listening on tcp://0.0.0.0:53786
2016-09-03T14:21:24.743135+00:00 app[web.1]: [3] ! WARNING: Detected 1 Thread(s) started in app boot:
2016-09-03T14:21:24.743181+00:00 app[web.1]: [3] ! #<Thread:0x007f382b59fca8#/app/vendor/bundle/ruby/2.2.0/gems/rufus-scheduler-3.2.2/lib/rufus/scheduler.rb:563 sleep> - /app/vendor/bundle/ruby/2.2.0/gems/rufus-scheduler-3.2.2/lib/rufus/scheduler.rb:571:in `sleep'
2016-09-03T14:21:24.743257+00:00 app[web.1]: [3] Use Ctrl-C to stop
2016-09-03T14:21:24.754941+00:00 app[web.1]: [3] - Worker 0 (pid: 7) booted, phase: 0
2016-09-03T14:21:24.756269+00:00 app[web.1]: [3] - Worker 1 (pid: 20) booted, phase: 0
2016-09-03T14:21:25.525174+00:00 app[web.2]: ** [NewRelic][2016-09-03 14:21:25 +0000 web.2 (18)] INFO : Doing deferred dependency-detection before Rack startup
It's very easy. Stop using rufus-scheduler. It's using threads, that's what is causing your warning.
Look at:
2016-09-03T14:21:24.743181+00:00 app[web.1]: [3] !
<Thread:0x007f382b59fca8#
/app/vendor/bundle/ruby/2.2.0/gems/rufus-scheduler-3.2.2/lib/rufus/scheduler.rb:563
sleep> -
/app/vendor/bundle/ruby/2.2.0/gems/rufus-scheduler-3.2.2/lib/rufus/scheduler.rb:571
:in `sleep'
Rufus-scheduler clearly is the cause of the warning.
Cf https://github.com/jmettraux/rufus-scheduler/issues/213
Now there is another way to look at the thing: the warning is not emitted by rufus-scheduler, it's emitted by Puma. There's probably a way to disable the warning, but that's a question for people with knowledge of Puma.
I have setup my puma web server based on heroku manual: Deploying Rails Applications with the Puma Web Server
config/puma.rb:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['RAILS_MAX_THREADS'] || 2)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
ActiveRecord::Base.establish_connection
end
Procfile contains:
web: bundle exec puma -C config/puma.rb
Now when I try to access action which has sleep 10 which delays the response and then try to access some other action, my understanding was that Puma would handle these 2 requests concurrently (since I have 2 workers). But instead it waits for the first request which sleeps to finish then it proceeds to the second one. Am i missing something?
My setup is:
Ruby 2.2.4
Rails 4.2.0
EDIT:
Ok, so I found out that on Heroku, it works, so question is, why it doesn't work in development mode?
rails s does not use the Procfile, you may want to look at using a tool like foreman: https://github.com/ddollar/foreman
update: this was the solution:
config.allow_concurrency = true in the rails development config.
I'm running the following puma config
threads_count = Integer(ENV["DB_POOL"] || ENV["MAX_THREADS"] || 15)
threads threads_count, threads_count
workers 3
preload_app!
rackup DefaultRackup
port ENV["PORT"] || 3000
environment ENV["RACK_ENV"] || "development"
on_worker_boot do
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
end
before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end
It's great for production, but I don't want to spin up 3 workers or use webrick in development. I tried wrapping the worker specific code in an environment check, but that breaks the puma DSL. Any ideas for running puma in non-clustered mode in development?
Rails is not defined in puma config file, so Rails.env can't be used here, but RACK_ENV is ok.
workers(ENV["RACK_ENV"] == "production" ? 3 : 0)
I figure out a working solution before seeing scorix's answer which I accepted, but I ended up with a slightly different solution. This allows you to set the worker count, so I can run 1 in staging and 3 in production for example.
threads_count = Integer(ENV["DB_POOL"] || ENV["MAX_THREADS"] || 15)
threads threads_count, threads_count
rackup DefaultRackup
port ENV["PORT"] || 3000
environment ENV["RACK_ENV"] || "development"
if ENV["RACK_ENV"] == "production"
workers ENV.fetch("WEB_CONCURRENCY") { 3 }
preload_app!
ActiveSupport.on_load(:active_record) do
ActiveRecord::Base.establish_connection
end
before_fork do
ActiveRecord::Base.connection_pool.disconnect!
end
end
Check out the Configuration part on the docs.
What I did was set up the production config on config/puma/production.rb, so on production you would run puma with puma -C config/puma/production.rb (or however you run it on prod) and on development, rails server won't use that configuration
Why do I have 4 Puma workers if I've set WEB_CONCURRENCY=3 in my Heroku config?
In this question, I learned that New Relic calls Puma workers "app instances".
Here is my puma.rb configuration:
workers Integer(ENV['WEB_CONCURRENCY'] || 2)
threads_count = Integer(ENV['MAX_THREADS'] || 1)
threads threads_count, threads_count
preload_app!
rackup DefaultRackup
port ENV['PORT'] || 3000
environment ENV['RACK_ENV'] || 'development'
on_worker_boot do
# Valid on Rails 4.1+ using the `config/database.yml` method of setting `pool` size
ActiveRecord::Base.establish_connection
end
Heroku config:
WEB_CONCURRENCY: 3
Puma has one master process.
It does not deal with request. It monitors and manages(restart or something) workers.
If you set 3 concurrency, there are 4 process. 3 workers(managing request) and 1 master precess(managing workers)