Phusion Passenger adalah web application server open source yang berfungsi sebagai jembatan antara web server (Nginx atau Apache) dengan aplikasi berbasis Ruby, Python, maupun Node.js.
Keunggulan Passenger:
- Mudah digunakan
- Mempermudah proses deployment ke produksi
- Skalabel
- Mendukung multitenancy (bisa menjalankan beberapa aplikasi sekaligus)
Bahasa yang Didukung:
- Ruby / Ruby on Rails
- Python
- Node.js
Integrasi yang Didukung:
- Nginx
- Apache
- Standalone (tanpa web server terpisah)
Passenger secara otomatis mencoba mendeteksi file startup (entry point) sesuai bahasa yang digunakan pada aplikasi.
Passenger Startup File Convention #
| Language | Startup File (Convention) |
|---|---|
| Ruby / Ruby on Rails | config.ru |
| Python | passenger_wsgi.py |
| Node.js | app.js |
Installation #
1. Tambahkan Repository Passenger #
sudo apt-get install -y dirmngr gnupg apt-transport-https ca-certificates curl
curl https://oss-binaries.phusionpassenger.com/auto-software-signing-gpg-key.txt \
| gpg --dearmor \
| sudo tee /etc/apt/trusted.gpg.d/phusion.gpg >/dev/null
echo "deb https://oss-binaries.phusionpassenger.com/apt/passenger jammy main" \
| sudo tee /etc/apt/sources.list.d/passenger.list
sudo apt-get update2. Install Passenger #
sudo apt-get install -y passengerQuickstart Ruby #
1. Clone repository aplikasi Hello World Ruby #
git clone https://github.com/devetop/learn-ruby.git
cd learn-ruby2. Install dependency dengan Bundler #
bundle config set --local path 'vendor/bundle'
bundle config set --local disable_shared_gems '1'
bundle config set --local deployment 'true'
bundle config set --local without 'development test'
bundle config set --local jobs $(nproc)
bundle install3. Jalankan aplikasi menggunakan Passenger Standalone #
passenger start \
--environment production \
--daemonize \
--port 30002 \
--app-type rack \
--startup-file config.ru \
--instance-registry-dir /home/user/tmp/ \
--pid-file /home/user/run/passenger.30002.pid \
--log-file /home/user/logs/passenger.30002.log \
--max-pool-size 6 \
--min-instances 2 \
--max-requests 1000 \
--friendly-error-pages \
--envvar PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/bin:/root/bin \
--envvar RAILS_ENV=production \
--envvar RACK_ENV=production \
--load-shell-envvarsPassenger akan berjalan di background (daemon mode) pada port 30002.
4. Menjalankan Passenger sebagai systemd Service #
Agar aplikasi aktif otomatis saat boot dan restart jika crash, buat file:
/etc/systemd/system/myapp-ruby.service
[Unit]
Description=Passenger Standalone for MyApp (Ruby)
After=network.target
[Service]
Type=simple
User=user
Group=user
WorkingDirectory=/home/user/learn-ruby
Environment=PATH=/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/usr/kerberos/sbin:/usr/kerberos/bin:/sbin:/bin:/root/bin
Environment=RAILS_ENV=production
Environment=RACK_ENV=production
Environment=PORT=30002
ExecStart=/usr/bin/passenger start \
--port ${PORT} \
--app-type rack \
--startup-file config.ru \
--instance-registry-dir /home/user/tmp/ \
--max-pool-size 6 \
--min-instances 2 \
--max-requests 1000 \
--environment production \
--pid-file /home/user/run/passenger.${PORT}.pid \
--log-file /home/user/logs/passenger.${PORT}.log
ExecStop=/usr/bin/passenger stop \
--pid-file /home/user/run/passenger.${PORT}.pid
Restart=always
[Install]
WantedBy=multi-user.targetAktifkan service:
sudo systemctl daemon-reload
sudo systemctl enable myapp-ruby
sudo systemctl start myapp-ruby5. Load .env di config.ru (Rack apps)
#
Untuk load .env di dalam config.ru.
require 'dotenv'
Dotenv.load
require './app'
run MyAppQuickstart Python #
1. Clone repository aplikasi Hello World Python #
git clone https://github.com/phusion/passenger-python-flask-demo.git
cd passenger-python-flask-demo2. Tambahkan file passenger_wsgi.py
#
Passenger membutuhkan entry point WSGI. Tambahkan file berikut di root proyek:
passenger_wsgi.py
import sys
import os
# Tambahkan path aplikasi ke sys.path
sys.path.insert(0, os.path.dirname(__file__))
# Import aplikasi Flask Anda (ubah sesuai nama module)
from app import MyApp as application # Untuk Flask
# Jika Django, gunakan:
# from your_project.wsgi import applicationMyApp) sesuai dengan yang ada di proyek Anda.
3. Jalankan aplikasi menggunakan Passenger Standalone #
passenger start \
--environment production \
--daemonize \
--port 30001 \
--app-type wsgi \
--startup-file passenger_wsgi.py \
--instance-registry-dir /home/user/tmp/ \
--pid-file /home/user/run/passenger.30001.pid \
--log-file /home/user/logs/passenger.30001.log \
--max-pool-size 6 \
--min-instances 2 \
--max-requests 1000 \
--friendly-error-pages \
--envvar PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/home/user/passenger-python-flask-demo/venv/bin \
--envvar PYTHON=/home/user/passenger-python-flask-demo/venv/bin/python \
--envvar WSGI_ENV=production \
--load-shell-envvarsPassenger akan berjalan di background (daemon mode) pada port 30001.
4. Menjalankan Passenger Python sebagai systemd Service #
Buat service agar aplikasi berjalan otomatis saat boot dan restart jika crash.
Buat file:
/etc/systemd/system/myapp-python.service
[Unit]
Description=Passenger Standalone for MyApp (Python)
After=network.target
[Service]
Type=simple
User=user
Group=user
WorkingDirectory=/home/user/passenger-python-flask-demo
Environment=PATH=/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin:/home/user/passenger-python-flask-demo/venv/bin
Environment=WSGI_ENV=production
Environment=PYTHON=/home/user/passenger-python-flask-demo/venv/bin/python
Environment=PORT=30001
ExecStart=/usr/bin/passenger start \
--port ${PORT} \
--app-type wsgi \
--startup-file passenger_wsgi.py \
--instance-registry-dir /home/user/tmp/ \
--max-pool-size 6 \
--min-instances 2 \
--max-requests 1000 \
--environment production \
--pid-file /home/user/run/passenger.${PORT}.pid \
--log-file /home/user/logs/passenger.${PORT}.log
ExecStop=/usr/bin/passenger stop \
--pid-file /home/user/run/passenger.${PORT}.pid
Restart=always
[Install]
WantedBy=multi-user.targetAktifkan service:
sudo systemctl daemon-reload
sudo systemctl enable myapp-python
sudo systemctl start myapp-python5. Load .env di passenger_wsgi.py
#
Untuk load .env di dalam passenger_wsgi.py.
import sys
import os
from dotenv import load_dotenv
# Path ke .env
env_path = os.path.join(os.path.dirname(__file__), '.env')
# Muat environment variable
load_dotenv(env_path)
# Tambahkan path aplikasi
sys.path.insert(0, os.path.dirname(__file__))
# Import aplikasi Flask/Django
from app import MyApp as applicationQuickstart Node #
1. Clone repository aplikasi Hello World Node.js #
git clone https://github.com/phusion/passenger-nodejs-connect-demo.git
cd passenger-nodejs-connect-demo2️. Install dependensi Node.js #
npm install3️. Jalankan aplikasi menggunakan Passenger Standalone #
passenger start \
--environment production \
--daemonize \
--port 30000 \
--app-type node \
--startup-file app.js \
--instance-registry-dir /home/user/tmp/ \
--pid-file /home/user/run/passenger.30000.pid \
--log-file /home/user/logs/passenger.30000.log \
--max-pool-size 6 \
--min-instances 2 \
--max-requests 1000 \
--friendly-error-pages \
--envvar PATH=/usr/local/apps/nodejs22/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin \
--envvar NODE_ENV=production \
--load-shell-envvars4️. Membuat Service Systemd (Auto-start + Auto-restart) #
Untuk membuat aplikasi berjalan otomatis saat boot dan auto-restart jika crash, buat file:
/etc/systemd/system/myapp-node.service
[Unit]
Description=Passenger Standalone for MyApp (Node.js)
After=network.target
[Service]
Type=simple
User=user
Group=user
WorkingDirectory=/home/user/app1
# Environment variables
Environment=PATH=/usr/local/apps/nodejs22/bin:/usr/kerberos/sbin:/usr/kerberos/bin:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
Environment=NODE_ENV=production
Environment=PORT=30000
# Start Passenger
ExecStart=/usr/bin/passenger start \
--port ${PORT} \
--environment production \
--app-type node \
--startup-file app.js \
--instance-registry-dir /home/user/tmp/ \
--pid-file /home/user/run/passenger.${PORT}.pid \
--log-file /home/user/logs/passenger.${PORT}.log \
--max-pool-size 6 \
--min-instances 2 \
--max-requests 1000
# Stop Passenger
ExecStop=/usr/bin/passenger stop --pid-file /home/user/run/passenger.${PORT}.pid
# Restart automatically if crashed
Restart=always
[Install]
WantedBy=multi-user.targetAktifkan service:
sudo systemctl daemon-reload
sudo systemctl enable myapp-node
sudo systemctl start myapp-node5. Load .env di app.js
#
Untuk load .env di dalam app.js.
require('dotenv').config();
const express = require('express');
const app = express();
app.get('/', (req, res) => res.send('Hello World'));
module.exports = app;Auto-restart Saat File Berubah (Hot Reload Development Mode) #
Mode ini berguna untuk developer yang ingin melihat perubahan tanpa restart manual.
mkdir -p tmp
touch tmp/always_restart.txtLog Rotation untuk Passenger #
Agar ukuran log tidak membesar tanpa batas, Anda dapat menggunakan logrotate untuk melakukan rotasi log otomatis.
Contoh log Passenger biasanya berada di:
/home/user/logs/passenger.<port>.logBuat file konfigurasi logrotate:
/etc/logrotate.d/passenger
sudo nano /etc/logrotate.d/passengerIsi dengan konfigurasi berikut:
/home/user/logs/passenger*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
copytruncate
dateext
dateformat -%Y%m%d
}Penjelasan Opsi:
- daily — rotasi dilakukan setiap hari.
- rotate 14 — menyimpan 14 arsip log (sekitar dua minggu).
- compress — mengompres log lama (.gz).
- delaycompress — kompresi dimulai satu hari setelah rotasi, aman untuk software yang masih memakai file log.
- notifempty — tidak merotasi jika log kosong.
- copytruncate — menyalin log lalu mengosongkan file lama tanpa mematikan service (aman untuk Passenger).
- dateext dan dateformat — menambahkan tanggal pada nama file log rotasi.
Jalankan test untuk memastikan tidak ada error:
sudo logrotate -f /etc/logrotate.d/passengerJika berjalan tanpa pesan error, konfigurasi logrotate sudah benar.
Best Practice Struktur Folder untuk Passenger Standalone #
Struktur folder yang rapi akan mempermudah:
- deployment
- log management
- isolasi environment
- debugging
- integrasi dengan systemd
- backup & restore
Berikut struktur direkomendasikan untuk aplikasi Passenger Standalone (apa pun bahasanya):
/home/user/myapp/
├── app/ # kode aplikasi utama
├── config/ # konfigurasi internal app
├── public/ # file statis (jika ada)
├── vendor/ # bundler install dir (Ruby)
├── venv/ # virtualenv (Python)
├── node_modules/ # dependencies (Node.js)
│
├── logs/ # log Passenger & app
│ ├── passenger.30001.log
│ ├── app.log
│
├── run/ # pid-file
│ └── passenger.30001.pid
│
├── tmp/ # cache / always_restart.txt
│ └── always_restart.txt
│
├── .env # environment variable
├── passenger_wsgi.py # (Python) entry point
├── config.ru # (Ruby) entry point
├── app.js # (Node.js) entry point
│
└── start.sh # optional: wrapper scriptReferensi: