node.jspassengerphusion

Passenger and Node.js: Is there a way to route to a specific instance?


Assuming passenger has started many instances of your node.js app and given the output from passenger-status --show=xml, is there a way to curl a specific instance?

Example output from passenger-status --show=xml:

$ sudo passenger-status --show=xml
<?xml version="1.0" encoding="iso8859-1"?>
<info version="3">
    <passenger_version>5.0.22</passenger_version>
    <group_count>1</group_count>
    <process_count>1</process_count>
    <max>1</max>
    <capacity_used>1</capacity_used>
    <get_wait_list_size>0</get_wait_list_size>
    <supergroups>
        <supergroup>
            <name>/opt/testApp/node_modules/testApp/public (production)</name>
            <state>READY</state>
            <get_wait_list_size>0</get_wait_list_size>
            <capacity_used>1</capacity_used>
            <group default="true">
                <name>/opt/testApp/node_modules/testApp/public (production)</name>
                <component_name>/opt/testApp/node_modules/testApp/public (production)</component_name>
                <app_root>/opt/testApp/node_modules/testApp</app_root>
                <app_type>node</app_type>
                <environment>production</environment>
                <uuid>Ye3PSGsJiXL7LLQxjZxY</uuid>
                <enabled_process_count>1</enabled_process_count>
                <disabling_process_count>0</disabling_process_count>
                <disabled_process_count>0</disabled_process_count>
                <capacity_used>1</capacity_used>
                <get_wait_list_size>0</get_wait_list_size>
                <disable_wait_list_size>0</disable_wait_list_size>
                <processes_being_spawned>0</processes_being_spawned>
                <life_status>ALIVE</life_status>
                <user>testUser</user>
                <uid>503</uid>
                <group>testUser</group>
                <gid>504</gid>
                <options>
                    <app_root>/opt/testApp/node_modules/testApp</app_root>
                    <app_group_name>/opt/testApp/node_modules/testApp/public (production)</app_group_name>
                    <app_type>node</app_type>
                    <start_command>node /usr/share/passenger/helper-scripts/node-loader.js</start_command>
                    <startup_file>/opt/testApp/node_modules/testApp/server.js</startup_file>
                    <process_title>Passenger NodeApp</process_title>
                    <log_level>3</log_level>
                    <start_timeout>90000</start_timeout>
                    <environment>production</environment>
                    <base_uri>/</base_uri>
                    <spawn_method>smart</spawn_method>
                    <user>testUser</user>
                    <default_user>testUser</default_user>
                    <default_group>testUser</default_group>
                    <integration_mode>standalone</integration_mode>
                    <ruby>/usr/bin/ruby</ruby>
                    <python>python</python>
                    <nodejs>node</nodejs>
                    <ust_router_address>unix:/tmp/passenger.cEAtrKS/agents.s/ust_router</ust_router_address>
                    <ust_router_username>logging</ust_router_username>
                    <ust_router_password>USTPASSWORD</ust_router_password>
                    <debugger>false</debugger>
                    <analytics>false</analytics>
                    <api_key>APIKEY</api_key>
                    <min_processes>1</min_processes>
                    <max_processes>0</max_processes>
                    <max_preloader_idle_time>300</max_preloader_idle_time>
                    <max_out_of_band_work_instances>1</max_out_of_band_work_instances>
                </options>
                <processes>
                    <process>
                        <pid>23090</pid>
                        <sticky_session_id>STICKYSESSIONID</sticky_session_id>
                        <gupid>GUPID</gupid>
                        <concurrency>0</concurrency>
                        <sessions>0</sessions>
                        <busyness>0</busyness>
                        <processed>12</processed>
                        <spawner_creation_time>1451496406616398</spawner_creation_time>
                        <spawn_start_time>1451496406629729</spawn_start_time>
                        <spawn_end_time>1451496407909872</spawn_end_time>
                        <last_used>1451506377943256</last_used>
                        <last_used_desc>53m 6s ago</last_used_desc>
                        <uptime>3h 39m 16s</uptime>
                        <life_status>ALIVE</life_status>
                        <enabled>ENABLED</enabled>
                        <has_metrics>true</has_metrics>
                        <cpu>0</cpu>
                        <rss>44340</rss>
                        <pss>43310</pss>
                        <private_dirty>36984</private_dirty>
                        <swap>0</swap>
                        <real_memory>36984</real_memory>
                        <vmsize>653728</vmsize>
                        <process_group_id>23063</process_group_id>
                        <command>Passenger NodeApp: /opt/testApp/node_modules/testApp</command>
                    </process>
                </processes>
            </group>
        </supergroup>
    </supergroups>
</info>

Solution

  • Looking at this documentation, you would think that you can use passenger-status -v to get url's and passwords for each instance. As the note on that page states, this feature is not available for Node.js instances.

    The best solution I found was using passenger-status --show=xml -v to get the linux socket for each instance, then using a command line http client to get a response

    Here is a working example of doing a simple GET request to the /health endpoint of a specific node.js instance:

    $ passenger-status --show=xml -v 
      ...
        <address>unix:/tmp/passenger.30Ge2aS/apps.s/node.34l02e</address>
      ...
    
    $ echo -e "GET /health HTTP/1.1\r\n" | sudo socat unix:/tmp/passenger.30Ge2aS/apps.s/node.34l02e STDIO
    HTTP/1.1 200 OK
    X-Powered-By: Express
    Content-Type: text/html; charset=utf-8
    Content-Length: 16
    ETag: W/"10-8MtBq0wHBRF66BmScI50YQ"
    Date: Mon, 04 Jan 2016 17:42:33 GMT
    Connection: keep-alive
    
    All systems go!