Ruby on rails seemless integration with legacy perl application
Comment:
This kind of set up should also work with an php, cgi (or any language, running on apache) site.
Overview:
I am (slowly) migrating a (large) legacy perl/cgi application to ruby on rails, the base requirement is that the (legacy) site continues to behave 'as expected' to the end user.
So, I need to run these two applications simultaneously from the same server and have it look like one application to clients. (i.e. transparent integration)
Existing links/sessions need to continue to work seamlessly. I decided to go the route of keeping the legacy app functioning as before, so for instance http://example.com/admin/admin.pl will still work as expected. All new development (which is in rails) will be located at http://example.com/admin2/
The first thing I needed to do was handle all session/cookies info with rails (I will do a separate post on that another time, as it is involved, although since we use sessions via a database it wasn't that bad)
Setup:
We are using apache2, enterprise ruby and phusion passenger.
Conf:
NOTE: we will use example.com for our http host for demonstration purposes
Ruby on Rails vhost conf file:
# we are now handling *ALL* http requests with mod_rails
<VirtualHost *:80>
# set server name/admin
ServerAdmin you@example.com
ServerName example.com
# be sure to point to 'public'
DocumentRoot "/usr/local/httpd/admin2/public"
ScriptAlias /admin2/ "/usr/local/httpd/admin2/public/"
RewriteEngine on
RewriteLog "/var/log/httpd/rewrite.log"
RewriteLogLevel 5
RewriteRule ^/$ /admin2/session [R,L]
RewriteRule ^/index.html$ /admin2/session [R,L]
# pass all images to legacy perl/cgi
RewriteRule ^(.*)(\.)(gif|jpg|png)$ http://example.com:8080$1$2$3 [proxy]
# pass/reroute legacy css/js requests
RewriteRule ^/css/(.*) /stylesheets/$1 [R,L]
RewriteRule ^/js/(.*) /javascripts/$1 [R,L]
### send any /admin/ page request to perl/cgi on port 8080
# /admin/ requests have not yet been migrated to rails
#http://httpd.apache.org/docs/2.0/mod/mod_proxy.html#proxyrequests
ProxyRequests Off
ProxyPreserveHost On
#15 minutes
ProxyTimeout 900
<Proxy *>
Order deny,allow
Allow from all
<Proxy>
# all requests for /admin go to legacy app
ProxyPass /admin/ http://example.com:8080/admin/
#('hides' the port)
ProxyPassReverse /admin/ http://example.com:8080/admin/
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
</VirtualHost>
If you have some ajax requests that take 'awhile', you may need to add the:
ProxyTimeout 900
SetEnv force-proxy-request-1.0 1
SetEnv proxy-nokeepalive 1
On some (long running) monthly report type queries we were getting:
Bad Gateway
The proxy server received an invalid response from an upstream server.
and this in apache logs:
[Thu Jun 11 10:58:08 2009] [error] (70014) End of file found: proxy: error reading status line from remote server
legacy perl/cgi vhost file:
# this would be the vhost file for the http://example.com:8080 host above
# we are now running perl/cgi on port 8080, mod_rails is handling
# all http requests
Listen 8080
<VirtualHost *:8080>
DocumentRoot /usr/local/httpd/htdocs
ServerName example.com
AddHandler cgi-script .pl
ScriptAlias /admin/ "/usr/local/httpd/htdocs/"
Alias /images/ "/usr/local/httpd/htdocs/images/"
RewriteEngine on
### handle with rails (/admin2/)
### 'any session page requests'
RewriteRule ^/$ http://%{HTTP_HOST}/admin2/session [L,R]
RewriteRule ^/index.html$ http://%{HTTP_HOST}/admin2/session [L,R]
RewriteRule ^/admin/session.pl$ http://%{HTTP_HOST}/admin2/session [L,R]
#### apps we have migrated to be handled with rails need a rule here
# passwd.pl is first
RewriteRule ^/admin/passwd.pl$ http://%{HTTP_HOST}/admin2/passwd [L,R]
</VirtualHost>
To rollback (or for testing. to disable the rails site) we can just comment out the rails vhost file and update the legacy vhost file to:
#Listen 8080
#<VirtualHost *:80>
<VirtualHost *:80>
ref:
Integrating Ruby on Rails with existing PHP or Perl Based Sites
http://work.rowanhick.com/2008/04/10/rails-php-sharing-the-same-session/
