The CS project web server has Phusion Passenger (Version 6.0.14) which allows for support of Ruby, Node.js, and Python/WSGI web applications through the Apache webserver. The instructions below will walk you through creating simple applications under each of these frameworks.
Contents
Global Requirements
Every Phusion Passenger application needs a minimal set of Passenger directives set in the Apache vhost configuration file. This change was introduced in Phusion Passenger version 5.2.0 and summarized in their blog post. For example, if you want to run a Passenger application in your project web space rooted at /n/fs/myproject/www
and accessible at myproject.cs.princeton.edu
, send a message to CS Staff requesting the following directives be associated with your project web space:
PassengerEnabled on
PassengerAppRoot /n/fs/myproject/www
These two directives are necessary and sufficient for instantiating a Passenger application. There are, however, numerous other configuration options available for Passenger. For more complex tasks, like using your own version of Python/Node/etc., please see below and/or contact CS Staff for assistance.
You will also want to create a folder named tmp within the PassengerAppRoot. Passenger keeps applications running continuously so that each instance of a process can handle multiple web requests, which means that updates to your application's code may not take effect immediately. In order to force Passenger to restart your application and use the most up-to-date version, you must issue the following command from your PassengerAppRoot directory:
touch tmp/restart.txt
Whenever Passenger has noticed that this file's timestamp has changed, it will restart the application. See restart.txt in the Phusion Passenger documentation.
Node.js
The project server currently runs Node.js version 12.22.2. (You can find this version of Node.js on cycles by issuing the command node --version
.)
Below is a sample Node.js hello world application. To create a bare-bones Node.js application, request the Passenger Apache directives listed above, then create a file called app.js
in the PassengerAppRoot directory with the following content:
var http = require('http');
var server = http.createServer(function(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });
res.end("Hello, World!\n");
});
server.listen(3000);
This is a basic Node.js application that accepts HTTP requests passed to it through Passenger and returns a 200 response code and the text "Hello, World!".
Visiting the section of your site that corresponds with the PassengerAppRoot should now generate a very plain "Hello World!" response.
More resources on Node.js can be found here.
Ruby on Rails
The project server currently runs Ruby version 2.6.10p210. (You can check this version of Ruby on cycles by issuing the command ruby --version
.)
Phusion has their own Hello World Ruby-on-Rails application available for download and usage. In order to install it, request the Passenger Apache directives listed above, then clone the git repository containing the example application:
cd <root directory>
git clone https://github.com/phusion/passenger-ruby-rails-demo .
bundle install --path=vendor/bundle
There are two additional steps: one necessary, and one possibly-optional, possibly-necessary depending on the structure of your site.
The first step is setting the production secret in <approot>/config/secrets.yml
, without which your site will crash. For testing purposes, it's enough to copy the secret_key_base
line from the 'test' section to the 'production' section, but for sites intended for public usage, we encourage you to investigate and follow Ruby best practices for secret storage.
The second step is only necessary if your site is operating out of a subdirectory of your web space root (e.g., if your web space root is /n/fs/myproject/www
and your ruby application is located at /n/fs/myproject/www/ruby
).
If this is the case, then you will need a route to <approot>/config/routes.rb
to send requests to the home page of your Rails app. For example, if myproject.cs.princeton.edu
points to /n/fs/myproject/www
but your ruby application is located at /n/fs/myproject/www/ruby
and by extension myproject.cs.princeton.edu/ruby
, then you will need to add the following line to /n/fs/myproject/www/ruby/config/routes.rb
directly under root 'home#index'
:
get "/ruby" => "home#index"
This tells the Rails application to redirect all requests from myproject.cs.princeton.edu/ruby
to the homepage of your Rails app.
Python/WSGI
Last updated: 2022-08-16
Phusion uses WSGI to interface with Python web applications as described in PEP 3333. It takes the place of components such as Gunicorn or uWSGI in a typical stack.
To get started, you must create a Python virtual environment in project space that references a Python interpreter available on the project web server. Because end-users do not have shell access to the project web server, the virtual environment must be created and maintained on the cycles
machines referencing a Python interpreter that is available both on cycles
(to create the virtual environment and manage its pip packages) and on the project web server (where the virtual environment is used) at the same relative location in the file system.
Currently, Python interpreter options for virtual environments on CS Systems are:
-
Pre-installed “System Python” version 3.6.8.
-
User-built Python interpreters following the instructions at: Building a Local Version of Python
Configure and Test “Hello, World!”
Because there is very little diagnostic feedback available to end-users (and sometimes sysadmins!) when things are not configured correctly, we highly recommend that you get this “Hello, World!” application running in your project web space before using or configuring Python web frameworks such as Django, Flask, Bottle, or Pyramid.
-
Make sure that you have set up project disk space (e.g.,
/n/fs/myproject
) and requested project web space (e.g.,myproject.cs.princeton.edu
) with a document root at least one level deeper into the project disk space (e.g.,/n/fs/myproject/www
) as outlined above. -
Make sure you have set up your virtual environment in your project space as outlined in the previous section. For this example, we assume the virtual environment is located at
/n/fs/myproject/myvenv
. -
Create a file named
passenger_wsgi.py
in your document root (e.g.,/n/fs/myproject/www/passenger_wsgi.py
) with the following content:import grp import os import platform import pwd import sys def get_username(): return pwd.getpwuid(os.getuid()).pw_name def get_groupname(): return grp.getgrgid(os.getgid()).gr_name def application(env, start_response): start_response( '200 OK', [('Content-Type','text/plain; charset=utf-8')] ) s = (f'Hello, World!\n' f'Python {platform.python_version()}\n' f'Interpreter: {sys.executable}\n' f'User: {get_username()}\n' f'Group: {get_groupname()}\n') return [s.encode('utf-8')] if __name__ == '__main__': b = application(None, lambda x, y: None) print(b[0].decode('utf-8'))
-
Test this program on
cycles
using the virtual environment:$ cd /n/fs/myproject/www $ /n/fs/myproject/myvenv/bin/python passenger_wsgi.py
-
In addition to the minimal Phusion Passenger directives described above, you will need to specify the location of your Python interpreter in your virtual environment. Send a message to CS Staff requesting that the following directives (edited with your specifics) be associated with your project web space:
PassengerEnabled on PassengerAppRoot /n/fs/myproject/www PassengerPython /n/fs/myproject/myvenv/bin/python
-
Test that the web server is running your application by using a web browser and navigating to
https://myproject.cs.princeton.edu
.
With the above working, you will have completed an important step in deploying a WSGI-based Python application on the CS infrastructure. General use of web frameworks are beyond the scope of this document. However, we do have information in the CS Guide on Setting up a Django Website in the Princeton CS Environment.
Additional Python-specific information (including deploying a web application to a sub-URI or subdirectory) can be found at the official Passenger Phusion site: Deploying a Python application on Passenger + Apache
Further Reading
More documentation on Phusion Passenger, its configuration (including specifying your own version of Python and different paths to the Python/Rails/Node applications) and its operation can be found in the Passenger Library.
/node/2849 built from passenger.md on 2022-08-16 10:08:17