sajad torkamani

What is Passenger?

Passenger is an application server used to serve Ruby, Python, and Node applications. It’s one of the most popular application servers for Rails apps and is an alternative to the likes of Unicorn and Puma.

How does Passenger fit in the web stack?

Passenger can be used in either standalone mode or integration mode:

  • Standalone mode: Passenger provides its own built-in web server. You typically run a command like passenger start to start the web server process.
  • Integration mode: Passenger integrates with a web server like Apache or Nginx as a module. You typically configure Passenger through Apache or Nginx config files. Integration mode is useful when you want to host multiple applications on the same server.

Passenger integration modes

How to use Passenger in standalone mode

Clone this Rails 7 blog app:

git clone https://github.com/sajadtorkamani/rails-blog

Add the passenger gem to your Gemfile:

gem "passenger", ">= 5.3.2", require: "phusion_passenger/rack_handler"

Run:

./bin/bundle install

Start server using passenger executable:

bundle exec passenger start

Or using bundle exec rails server (Rails will see the passenger entry in your Gemfile and use Passenger instead of the default Puma server):

bundle exec rails server

How logging works in Passenger standalone mode

When run in standalone mode (using passenger start), Passenger will create and use its own log file. The location of the log file will be printed to the terminal when passenger is started. The Passenger log file is different to the application log file (e.g., Rails’ log/development.log file).

Anything that the application logs will go to the application log file, but anything the application prints to stdout or stderr will be captured in the Passenger log file.

Logging behavior can be configured.

At its core, Passenger is a process manager

On initial startup, Passenger in standalone mode will spawn a single process. You can check this by running:

bundle exec passenger-status

Example output:

Version : 6.0.13
Date    : 2022-04-08 16:25:35 +0100
Instance: JydakREW (nginx/1.20.2 Phusion_Passenger/6.0.13)

----------- General information -----------
Max pool size : 6
App groups    : 1
Processes     : 1
Requests in top-level queue : 0

----------- Application groups -----------
/Users/sajad/sites/rails/rails-blog (development):
  App root: /Users/sajad/sites/rails/rails-blog
  Requests in queue: 0
  * PID: 99192   Sessions: 0       Processed: 1       Uptime: 15m 50s
    CPU: 0%      Memory  : 66M     Last used: 15m 50s ago

You can configure the maximum number of processes that Passenger should spawn with passenger_max_pool_size. You can also configure a minimum number of processes with passenger_min_instances.

Every instance of your application is managed in its own isolated process. Each process has its own memory space.

Passenger will restart crashed processes

If one process crashes (e.g., user does something dodgy that uses too much memory), Passenger will spawn a replacement process. For example, if you directly kill a process with the kill <process-id> command, Passenger will spawn another process in its place.

Passenger load balances traffic between processes

It keeps track of how many requests each process is handling and make sure that requests are evenly spread out between the allocated processes.

Passenger will dynamically scale processes

Based on the passenger_max_pool_size option, Passenger will automatically spawn additional processes to handle increasing traffic. It will also shut down processes that have been inactive for a while (5 minutes by default).

Restart application served by Passenger

Restart specific app interactively

cd /path-to-your-app
bundle exec passenger-config restart-app

This will prompt you to select which app to restart.

Restart specific app non-interactively

cd /path-to-your-app
bundle exec passenger-config restart-app <path-to-app>

Restart all apps non-interactively

cd /path-to-your-app
bundle exec passenger-config restart-app /

Sources

Tagged: Rails

Leave a comment

Your email address will not be published. Required fields are marked *