Phusion Passenger allows running Ruby web applications such as puppetmaster inside Apache or nginx web servers. It is also known as mod_passenger, mod_rails or mod_rack, especially when discussed in conjunction with the Apache webserver.

By default puppetmasterd runs inside a Webrick web server. However, Webrick is mostly intended for Ruby web application development and is not suitable for production use, especially when there are more than a few puppetd clients connecting to the puppetmasterd.

There is an official Puppet Wiki page describing how to run Puppetmaster using Phusion Passenger, Unfortunately information there is spotty and confusing due to several different ways you can install and configure Puppet, Passenger and Apache on a variety of platforms. This article aims at describing the steps needed to configure puppetmaster to run inside mod_passenger container hosted by Apache. This has been achieved with minimal changes to the default Debian puppetmaster setup. This process works with Debian Lenny and Squeeze.

It is also possible to setup a completely independent puppetmaster/passenger environment outside Debian packaging system. This has some benefits but is outside the scope of this article.

Installing software

On Debian Lenny need to use packages from the Lenny backports repository, as Phusion Passenger does not even work with the very old puppet version (0.24.5) that's available from stock Debian Lenny repositories. Instruction for configuring your system to use the backports repository can be found from here here. On Debian Squeeze you don't need to use the backports repository.

Note that by default (without apt-pinning) aptitude only upgrades minimum amount of packages to newer (backported) versions. While this is generally a good idea, in this case mixing backported with non-backported packages can cause strange, hard to debug issues with some puppet client versions. To avoid this make sure that all dependencies of the above packages - and their dependencies' dependencies - are fetched from the backports repository. The easiest way to do this is to use aptitude and individually select the backport packages, even when not necessary to keep the Debian packaging system happy.

On both Lenny and Squeeze you need to install puppet, puppetmaster and libapache2-mod-passenger packages.

Generating puppetmaster's certificates and keys

If you have not launched puppetmaster (with Webrick) before on the puppetmaster server, do it before starting configuring mod_passenger. This first run generates all the certificates and keys which are required.

Configuring puppetmaster to use mod_passenger

Configuration overview

There are several things one has to configure to run puppetmaster inside mod_passenger:

Configuring puppetmasterd

Debian stores puppet configuration in /etc/puppet/puppet.conf. This file will contain all puppet-related configuration details. If you're lucky, you only need to add these two entries in to the [puppetmasterd] section:

ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY

Below is a sample configuration file which works with mod_passenger:


# Here we define the default environment ("production").
# It seems that without this section 0.25.4 clients bail out.


# Stored configuration support.
storeconfigs = true
dbadapter = sqlite3
dblocation = /var/lib/puppet/storeconfigs.sqlite

# Client state database migration.
dbmigrate = true

# Use this to get lots of stuff into /var/log/puppet/rails.log
#rails_loglevel = debug

# Passenger (a.k.a. mod_rails) needs these
ssl_client_header = SSL_CLIENT_S_DN
ssl_client_verify_header = SSL_CLIENT_VERIFY

Setting up the rack environment

Phusion Passenger uses Rack to run Ruby on Rails web applications. In practice this means that we need to create a valid Rack environment for puppetmaster. The least intrusive way to do this is to create a rack directory into /var/lib/puppet. It should contain the following entries:

The file is not installed with Debian's puppet packages, so we need to fetch it separately. Note that you need a version of matching your puppet version. This file is probably easiest to fetch using the Puppet Git tree web interface. Here are a few direct links:

Once you've fetched make sure all of the above files and directories are owned by "puppet:puppet". This is especially important in case of, as mod_passenger will run as the user who owns that file.

Enabling Apache modules

The next step is to enable mod_ssl and mod_passenger. The standard "Debian way" is to use a2enmod like this:

a2enmod ssl
a2enmod passenger

Adding Apache VirtualHost definition for puppetmaster

The last step is to add a ?VirtualHost definition for Apache. Below is an example of virtualhost definition:

# You probably want to tune the settings below

# Unlike some webapps puppetmaster can use
# Passenger's high-performance mode
PassengerHighPerformance on
PassengerMaxPoolSize 12
PassengerPoolIdleTime 1500
# PassengerMaxRequests 1000
PassengerStatThrottleRate 120
RackAutoDetect On
RailsAutoDetect On

# Uncomment to limit interfaces on which puppetmaster responds to requests
# Listen
Listen 8140

<VirtualHost *:8140>
        SSLEngine on
        SSLProtocol -ALL +SSLv3 +TLSv1
        SSLCipherSuite ALL:!ADH:RC4+RSA:+HIGH:+MEDIUM:-LOW:-SSLv2:-EXP

        SSLCertificateFile      /var/lib/puppet/ssl/certs/<replace-with-puppetmaster-fqdn>.pem
        SSLCertificateKeyFile   /var/lib/puppet/ssl/private_keys/<replace-with-puppetmaster-fqdn>.pem
        SSLCertificateChainFile /var/lib/puppet/ssl/ca/ca_crt.pem
        SSLCACertificateFile    /var/lib/puppet/ssl/ca/ca_crt.pem
        # If Apache complains about invalid signatures on the CRL, you can try disabling
        # CRL checking by commenting the next line, but this is not recommended.
        SSLCARevocationFile     /var/lib/puppet/ssl/ca/ca_crl.pem
        SSLVerifyClient optional
        SSLVerifyDepth  1
        SSLOptions +StdEnvVars

        #RackBaseURI /
        DocumentRoot /var/lib/puppet/rack/public/
        <Directory /var/lib/puppet/rack/public/>
                Options None
                AllowOverride None
                Order allow,deny
                allow from all
                # We are told that this is required for correct operation
                Options -MultiViews

Make sure to change the SSLCertificateFile and SSLCertificateKeyFile entries to match your system.

Testing and debugging

Once you've configured everything restart Apache and check that it's listening for connections on port 8140:

$ /etc/init.d/apache2 restart
Restarting web server: apache2 ... waiting .
$ netstat -an|grep LISTEN|grep 8140
tcp6       0      0 :::8140                 :::*                    LISTEN

Also make sure that firewall is not blocking access to port 8140, e.g. with

$ iptables -L -v

Next test that puppet clients can connect to master and fetch their catalogs. If not (which is likely), check out the relevant log files:

Passenger web interface itself is very useful for debugging Puppetmaster startup problems. Simply point your browser to the puppetmaster URL, e.g. https://<your-puppet-master-server>:8140 and check what it says.

Integrating puppet-dashboard into Passenger

On Debian Squeeze you can install puppet-dashboard Debian package available here. For the most part you can follow setup instructions given here regarding reports directory setup and database generation/migration. If you've configured Puppet+Passenger as described above, the following ?VirtualHost definition should work:

# Uncomment to limit the interface dashboard listens on
Listen 8141

<VirtualHost *:8141>
        DocumentRoot /usr/share/puppet-dashboard/public/
        <Directory /usr/share/puppet-dashboard/public/>
                Options None
                AllowOverride AuthConfig
                Order allow,deny
                allow from all
  ErrorLog /var/log/apache2/dashboard.example.com_error.log
  LogLevel warn
  CustomLog /var/log/apache2/dashboard.example.com_access.log combined
  ServerSignature On

Potential caveats

Running puppetmaster as user other than puppet

Running puppetmaster as non-puppet user (e.g. www-data) is not recommended, as it effectively forces you to create a completely separate puppetmaster + passenger environment outside Debian packaging system or heavy modifications to permissions of default puppet directories. Also, running puppetd on the puppetmaster server is problematic: every time puppetd runs it changes owner of certificate files (by default located in /var/lib/puppet/ssl) to puppet. This means that the puppetmasterd (which is not running as puppet user) can't read those files anymore. External nodes obviously don't trigger this error.