Ruby on Rails
Proxy LigHTTPD Apache2 on Debian Sarge

Proxy Lighty through Apache2 on Debian Sarge

It took a while to figure this out, so I thought I’d pass on to the community. I found some directions elsewhere that were so-so, didn’t cover SSL and didn’t really cover vhosts well. Here’s a list:

Here was my situation: I wanted to use Apache2 for some static pages, cgi stuff (not rails), php and a few other things. I’m familiar with it fairly (so please edit this if you have tips). I wanted to use Lighttpd to serve rails b/c Apache2 was having problems using fastcgi, fcgid and scgi and I found Lighttpd worked a little better with fastcgi. So I wanted to use Apache2 to face :80 and :443, and have it proxy my rails URLs to Lighttpd.

As a side benefit, this made it easy to setup SSL protected pages for Rails, as I had Apache2 proxy both :80 and :443 for those particular rails apps to the same lighttpd rails instance – no more having to run two whole instances of the app!

In the end, this was how I did things.

First, install apache2 and enable various modules.

# apt-get install apache2
# cd /etc/apache2/mods-available
# a2enmod proxy
# a2enmod ssl
# a2enmod rewrite
# /etc/init.d/apache2 restart

You will need to edit /etc/apache2/ports.conf and add port 443 (if you have ssl sites).

Next, I compiled and installed lighttpd. There are some great instructions for installing lighttpd, mysql, gems, etc. here

After installing Lighttpd, I setup my rails apps to be served on ports 3000..3005. I used the lighttpd socket hack. In lighttpd.conf, I setup each rails instance like this:

$SERVER["socket"] == "127.0.0.1:3000" {
var.my-app = "/path/to/rails/app/base/directory"
server.document-root = my-app + "/public"
url.rewrite = ( "^/$" => "index.html", "^([^.]+)$" => "$1.html" )
server.error-handler-404 = "/dispatch.fcgi"
fastcgi.server = (
        ".fcgi" =>
                (
                        "localhost" =>
                                (
                                        "min-procs" => 1, 
                                        "max-procs" => 4,
                                        "socket" => "/tmp/my-app.fcgi.socket",
                                        "bin-path" => my-app + "/public/dispatch.fcgi",
                                        "bin-environment" => ( "RAILS_ENV" => "production" )
                                )
                )
)
}

Each lighttpd site was on a different port, 3000..3005.

I also needed to add a little block of code to /etc/apache2/mods-available/proxy.conf:

       <Proxy <a href="http://127.0.0.1">http://127.0.0.1</a>:3000>
                Order deny,allow
                Deny from all
                Allow from all
        </Proxy>

Again, one block per proxy, changing the port as necessary.

Then, each vhost in apache looked like this:

<VirtualHost xxx.xxx.xxx.xxx:80>
        ServerName              my-app.domain.tld
        ServerAdmin             <a href="mailto:webmaster@domain.tld">webmaster@domain.tld</a>
        ProxyRequests           Off
        ProxyPreserveHost       On
        RewriteEngine           On
        RewriteRule             ^/(.*) <a href="http://127.0.0.1">http://127.0.0.1</a>:3000/$1 [P,L]
        ProxyPassReverse        / <a href="http://127.0.0.1">http://127.0.0.1</a>:3000/
</VirtualHost>
<VirtualHost xxx.xxx.xxx.xxx:443>
        SSLEngine               On
        SSLCertificateFile      /etc/apache2/ssl/my-app.crt
        SSLCertificateKeyFile   /etc/apache2/ssl/my-app.private.key

        ServerName              my-app.domain.tld:443
        ServerAdmin             <a href="mailto:webmaster@domain.tld">webmaster@domain.tld</a>
        ProxyRequests           Off
        ProxyPreserveHost       On
        RewriteEngine           On
        RewriteRule             ^/(.*) <a href="http://127.0.0.1">http://127.0.0.1</a>:3000/$1 [P,L]
        ProxyPassReverse        / <a href="http://127.0.0.1">http://127.0.0.1</a>:3000/
</VirtualHost>