# Puma can serve each request in a thread from an internal thread pool.
# The `threads` method setting takes two numbers: a minimum and maximum.
# Any libraries that use thread pools should be configured to match
# the maximum value specified for Puma. Default is set to 5 threads for minimum
# and maximum; this matches the default thread size of Active Record.
#
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
# Specifies the `worker_timeout` threshold that Puma will use to wait before
# terminating a worker in development environments.
#
worker_timeout 3600 if ENV.fetch("RAILS_ENV", "development") == "development"
# Specifies the `port` that Puma will listen on to receive requests; default is 3000.
#
port ENV.fetch("PORT") { 3000 }
# Specifies the `environment` that Puma will run in.
#
environment ENV.fetch("RAILS_ENV") { "development" }
# Specifies the `pidfile` that Puma will use.
pidfile ENV.fetch("PIDFILE") { "tmp/pids/server.pid" }
# Specifies the number of `workers` to boot in clustered mode.
# Workers are forked web server processes. If using threads and workers together
# the concurrency of the application would be max `threads` * `workers`.
# Workers do not work on JRuby or Windows (both of which do not support
# processes).
#
workers ENV.fetch("WEB_CONCURRENCY") { 2 }
# Use the `preload_app!` method when specifying a `workers` number.
# This directive tells Puma to first boot the application and load code
# before forking the application. This takes advantage of Copy On Write
# process behavior so workers use less memory.
#
# preload_app!
# Allow puma to be restarted by `rails restart` command.
plugin :tmp_restart
Yeah it’s very weird. I don’t know a lot about build packs, but the folks who do inside Fly say they’re complicated beasts with lots of moving parts.
A workaround would be to use a Ruby Dockerfile instead of a Heroku build pack. I wrote instructions on how to migrate Rails applications from Heroku to Fly with at Migrate from Heroku · Fly Docs that can walk you through the steps. You won’t have the “28” issue if you are able to go down that path.
I don’t use fly.io, but I’m facing a similar issue when building a Rails app using the heroku buildpacks. I use the heroku/ruby buildpack as the main buildpack and the heroku/nodejs buildpack to precompile my assets.
After some investigation it seems that for some reason the heroku/nodejs buildpack automatically sets the WEB_CONCURRENCY environment variable and there is no way to override that. In my case it’s also set to 28.
@hovancik not sure if you’re also using the nodejs buildpack.
Could somebody from fly.io confirm if they use the heroku buildpacks?
I’m still going back and forth with Heroku on this issue, but and having a difficult time conveying to them that they’re clobbering that variable (they think they check it first).
For now I’m inclined to say if you want to control this variable, use a different ENV var name like PUMA_WORKERS=2
If it’s of any help, the paketo buildpacks don’t seem to have this bug. Ultimately, I think fly.io should maintain their own set of buildpacks, as opposed to relying on some other company’s ones.
While we continue to support buildpacks our preference is that people use dockerfiles. If you have a puma app (with or without rails) and would like help converting to dockerlet us know.
I opened a ticket within Heroku and advised them to update the Github issues, but they don’t seem to be grasping my ask. You might open a ticket with them from the Heroku dashboard and reference the same Github issues—sometimes when they see a pattern emerge they put more resources on it
To Sam’s point, you could think of a Buildpack as a Dockerfile, but with a ton of if/else statements that magically detect things in your application. That can lead to surprising behavior, like WEB_CONCURRENCY being 28. Surprising behavior and running production web apps isn’t a great mix.
A point I have seen raised, and maybe this is your sentiment, is that your don’t want to see a Dockerfile in your project directory because you don’t want to deal with it. I feel the same and agree it’s a big ask to throw Dockerfiles in projects, but there’s no plans to change from that approach.
On the plus side, the Fly team does ship some pretty sane Dockerfiles that work for most framework usecases. A huge plus is when you need access to Linux, its much easier to do so in a Dockerfile (once you get past the huge learning curve) to change the distro, add some packages, etc.
Well, yeah. As a developer, I don’t want to learn how to create correct and secure and everything Docker container for my app. I want to write code. I would never feel safe. That’s why we all used heroku and their buildpack: git push heroku. Maybe it is all magic and ifs, but I never had any issues with it