Puma: From Daemonization to Process Control with Systemctl and Monit
Puma is a popular Ruby web server that is known for its speed and scalability. It has undergone significant changes in recent versions(starting 5.0.0). One of the most notable alterations is the removal of the daemonization feature. But what does it mean?
Daemonization, in the context of web servers, is a process that allows a program to run in the background as a system service. In older versions, Puma made it simple for users to daemonize their processes with a straightforward configuration snippet:
However, in recent versions, attempting to use the daemonize
code will result in an error, as this functionality has been removed from the codebase.
Why daemonization should not be part of gem?
Incorporating daemonization directly within a gem can lead to undesirable consequences: as explained by Mike Perham in a Blog Post. Here are some key points that should be considered -
- Complexity: Adding daemonization features to a gem can make its code more complex and challenging.
- Maintenance: The responsibility of maintaining daemonization, automatic restart, and similar core features becomes an additional burden.
- Efficiency: System processes are better equipped to manage tasks like daemonization. Delegating this function to the system ensures more efficient and reliable execution, rather than embedding it within the gem.
As a result of these considerations, Puma decided to remove the daemonization feature from the gem.
This decision led us to make some changes in our setup to ensure the smooth running of our applications.
Using Systemd
We had previously implemented daemonization for Sidekiq, which was a process similar to Puma’s needs. Although there were some minor adjustments required for Puma. Here are steps to achieve daemnization through systemctl:
- Remove
daemonization
from config/puma.rb file -
Create a file in
/lib/systemd/system/puma.service
. Below is sample systemd service configuration example, modify it according to your needs. -
Two prominent Puma restart strategies are Phased and Hot restarts. Phased restarts are slower but ensure that all workers finish their existing requests before restarting the server, while Hot restarts are faster but come with increased latency during the restart.
To initiate Puma with a phased restart, you can pass thephased-restart
option. This choice offers flexibility to adapt Puma's behavior according to specific needs. More about puma restarts Here. -
Monit configurations
Monit is a utility for managing and monitoring processes, programs, files, directories and filesystems on a Unix system Monit Docs.
Updatedmonitrc
file - To check if puma is running correctly follow the commands.
Exploring Other Alternatives
As alternative to this we considered using puma-daemon gem, which essentially replicated the removed code and maintained it in a separate gem. However, after careful consideration, we chose not to adopt this alternative for the following reasons:
- Violation of system standards.
- Additional gem and maintainence burden.
Summary
While the removal of daemonization from Puma may require some adjustments, it aligns with the best practices of modern web server management Managing processes at the system level, using tools like systemd and Monit, is considered a more efficient and maintainable approach. Daemonizing processes within application code is discouraged, as it’s a task that falls under the system level. Ultimately, the shift towards system-level process management ensures the stability and efficiency of web applications.