Puma
Puma is a modern, concurrent web server for Ruby and Rack applications. Designed with speed and simplicity in mind, Puma is known for its ability to handle multiple requests simultaneously, making it a popular choice for serving Ruby on Rails applications in both development and production environments.
Simplify Local Rails Development with Puma-dev
Developing Rails applications locally can be a hassle, especially when we want to run multiple Rails applications on our machine. Doing that with localhost:3000
will get annoying at some point (cookie sharing, changing ports, everyone in the team handling it differently, no HTTPS to test with…).
for example we have to run multiple servers to run the app and API.
# To run the app
cd ~/projects/web-app
rails server -p 3000
# another terminal window to run API
cd ~/projects/web-api
rails server -p 3001
Working on a system like this locally requires developer to run multiple Rails servers in multiple terminal windows.
Thankfully, we can make this process much easier with puma-dev.
Puma-dev
Puma-dev is a tool that provides a quick
and easy way to manage Puma-powered web apps in development on macOS
and Linux. We can run
and manage our applications without needing to tweak our /etc/hosts
file or constantly start
and stop individual servers. Access them using the .test
subdomain,
and run multiple custom domains at the same time.
https://appname.test
With puma-dev, each app gets its own subdomain, making local development more seamless and organized.
The servers started by puma are centrally managed. Once puma-dev accepts an HTTP access, the puma server is started automatically. It automatically sleeps if there is no access for a while. As stated above, server operations are managed by puma-dev without any manual operation.
Key features of puma-dev include:
- Easy startup and idle shutdown of rack/Rails apps.
- Easy access to apps using the .test subdomain (configurable).
- Support for running multiple custom domains simultaneously, e.g. .test, .puma.
- Support for HTTPS out of the box.
- Support for Rails 5 ActionCable via rack.hijack websockets.
Using puma-dev
Prerequisites:
Before we start, ensure we have the following installed:
- macOS or Linux (puma-dev is designed for these platforms)
- Ruby (version 2.5+)
- Bundler
- Rails (version 5.0+)
Installing puma-dev
To install puma-dev, follow these steps:
- Install puma-dev:
On macOS or GNU/Linux, we can use Homebrew:
brew install puma/puma/puma-dev
we can also download the appropriate binary from the puma-dev releases page https://github.com/puma/puma-dev/releases and place it in our PATH.
- Set up puma-dev:
# configure some DNS settings that have to be done as root
sudo puma-dev -setup
- Start puma-dev:
# configure puma-dev to run in the background on ports 80 and 443 with the domain .test
puma-dev -install
Here are the few useful commands of puma-dev:
# To start
puma-dev
# To stop
puma-dev -stop
# If we would like to have puma-dev restart a specific app
run `touch tmp/restart.txt` in that app's directory.
# If we wish to have puma-dev use a port other than 80, for example to use port 81:
puma-dev -install -install-port 81
# Custom Domain Extension. Replace custom_extension with our desired extension (e.g., local, myapp, etc. (default "test")).
puma-dev -d custom_extension
# To uninstall
puma-dev -uninstall
Configuring our Rails Application
With puma-dev installed, we need to configure our Rails application to work with it.
Step 1
We need to be using Puma as our Rails development web server.
# Gemfile
gem "puma"
Step 2
In development ensure that our Rails app is configured to allow requests from host.
# config/environments/development.rb
Rails.application.configure do
...
config.hosts = []
...
end
Step 3
For puma-dev to run our application, we have to symlink the application directory into ~/.puma-dev
with the help of puma-dev link
command.
# Navigate into application directory and run this command
puma-dev link -n app_name
# Here give the desired domain name as app_name. example: puma-dev link -n miru
our application will now be available at https://app_name.test
. Here is the url of above example: https://miru.test
.
Update bin/setup
When working as a team, it’s beneficial to know the domain that other developers are using for local application development.
To ensure everyone uses the same URL, we can add the puma-dev link
command to our Rails bin/setup
file instead of running it manually.
# bin/setup
# Existing Rails setup
...
puts "\n== Configuring Puma-dev to host https://app_name.test =="
system! "puma-dev link -n app_name"
By running bin/setup
we get a consistent development environment with a consistent URL.
The recent Rails PR #51088 suggests adding puma-dev configuration to the bin/setup
script. Here’s how we can do it:
# bin/setup
# Existing Rails setup
...
def command_exists?(command)
system("command -v #{command} > /dev/null 2>&1")
end
# Install puma-dev if it's not installed
unless command_exists?('brew')
puts "Homebrew is not installed. Please install Homebrew first."
exit 1
end
unless command_exists?('puma-dev')
puts "Installing puma-dev..."
system('brew install puma/puma/puma-dev')
puts "Running puma-dev setup..."
system('sudo puma-dev -setup')
puts "Installing puma-dev DNS settings..."
system('puma-dev -install')
end
# Link the current app to puma-dev
puts "\n== Configuring Puma-dev to host https://app_name.test =="
app_name = File.basename(APP_ROOT)
system! "puma-dev link -n #{app_name}"
puts "puma-dev setup complete for #{app_name}.test"
With out any manual input from the developer, above bin/setup
script installs puma-dev
if not installed in the local machine
and takes care of all the necessary configurations regarding the installion process. After installing, it also set’s the domain for the app to run.
our application will now be available at https://app_name.test
.
Conclusion
Puma-dev is a powerful tool for developers working with multiple Ruby web applications. It avoids the headache of managing multiple Rails servers in multiple terminal windows by running a background process to manage all the Rails apps along with features like custom domain support and easy start/stop commands, makes it an essential part of development workflow on macOS and Linux.
By integrating puma-dev
configuration into our bin/setup
script, we can make it easy for our entire team to get up
and running quickly, without having to worry about managing the local server setup.