Forum: Ruby on Rails Lost while trying to deploy rails app on apache

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
Ac1feb66b7653d4e113cc3a31ae94e1d?d=identicon&s=25 Ryan Nielsen (Guest)
on 2006-02-16 02:52
(Received via mailing list)
I need to graft some rails apps onto a website running apache 1.3 and
I must be missing something very obvious because I cannot get things
working properly. Here is what I need:

1) The server must be running apache 1.3. A very large body of PHP
content is currently vended by the server through 5 vhosts and I have
neither the time nor resources to replace apache1 with apache2 or
lighttpd. Maybe someday, but not right now.
2) The rails apps cannot be their own vhosts. Basically, my apps must
be accessible via vhost.server.com/path/to/my/rails/app so they fit in
seamlessly with the existing server content and structure.
3) The setup needs to be as transparent as possible. The more stuff
that gets stuffed in config files and redirected through proxies the
more unmaintainable the server becomes. "Sysadmin" isn't in my job
description, so I don't need the added job security of a complex and
opaque setup. ;-) The PHP applications on the server are dirt simple
to maintain since deployment basically consists of running 'svn
update' somewhere in the server's directory root. You don't need to
read through config files or figure out what's proxied to which
server. I'd like a similar setup for the new rails apps I'm trying to
deploy.

I had hoped those were simple requirements but I'm starting to feel
like such a setup is unachievable. I've just spent a great deal of
time over two days digging through this list's archives and through
the wiki trying to get something working. Briefly, I've tried the
following two setups:

1) Proxying my apps through apache to lighttpd instances. James Duncan
Davidson's excellent Apache2 and Rails on Lighty pages served as a
reference: <http://duncandavidson.com/essay/2006/01/railsonapache> and
<http://duncandavidson.com/essay/2005/12/railsonlighty>
2) Grafting my apps by symlinking /public to a location in the
directory root and then building FCGI and configuring Apache. I used
these two wiki pages as guides:
<http://wiki.rubyonrails.org/rails/pages/FastCGI> and
<http://wiki.rubyonrails.com/rails/pages/HowtoUseSy...

I was reluctant to start with the proxy setup since that was in
violation of goal 3, but almost all of the documentation out on the
net strongly encouraged that route if Apache had to be used for legacy
content. It also seemed simple to graft my app into a specific
subdirectory under the document root. Unfortunately, I simply could
not get it to work. Following
<http://www.hivelogic.com/articles/2005/12/01/ruby_...,
I built lighty, FCGI and the Ruby FCGI bindings. I then followed
James' guide to configure, test and deploy Rails on lighty and could
successfully connect to the server on a non-standard port. My app ran
just fine on lighty, so I stuck what I thought would be appropriate
proxy directives in the vhost's apache conf file

    ProxyRequests Off

    ProxyPass /path/to/app/ http://lighty.server.com:8001/
    ProxyPassReverse /path/to/app/ http://lighty.server.com:8001/

and restarted apache. Things looked great until I clicked on a link. I
was magically redirected from vhost.server.com/path/to/my/rails/app to
vhost.server.com. A bit of research and I discovered that I needed to
add

    ActionController::AbstractRequest.relative_url_root =
"/path/to/my/rails/app"

to my config/environment.rb file. A quick lighty restart and my paths
were preserved. (Almost there!) However, whenever I clicked on a link
the server would load
vhost.server.com/path/to/my/rails/app/controller/method/id and never
redirect back to the app's root as it should. Furthermore, the calls
to my controller's methods didn't have any effect: going back to the
root manually would bring things back in the same state. I double
checked all of my settings in apache and lighty, bounced both servers,
dug through the wiki and this list and eventually went to bed. I have
no idea why things don't work.

Today I decided to take a different route and try the second setup. I
placed the symlink into apache's document root, built mod_fcgi, added

LoadModule fastcgi_module     libexec/httpd/mod_fastcgi.so
AddModule mod_fastcgi.c
<IfModule mod_fastcgi.c>
    FastCgiIpcDir /tmp/fcgi_ipc/
    AddHandler fastcgi-script fcgi
</IfModule>

to the global apache config file and added

    <Directory "/Volumes/Data/WebContent/htdocs/path/to/symlink">
       Options +ExecCGI

        RewriteRule ^$ index.html [QSA]
        RewriteRule ^([^.]+)$ $1.html [QSA]
        RewriteCond %{REQUEST_FILENAME} !-f
        RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
        ErrorDocument 500 "<h2>Application error</h2>The regression
voting Rails application failed to start properly."
    </Directory>

to the vhost's config. ('RewriteEngine On' was already in the vhost's
config.) I restarted apache and didn't get any love at all. I can get
to the 404.html and 500.html files but the fcgi handler never comes
into play. I turned on +Indexes and could see the contents of /public,
so the symlink is working. The apache error file didn't contain
anything juicy so I turned on mod_rewrite logging. The best I could
divine from that output was that the rewrite rules specified in the
Directory statement never got parsed... I also tried using the the
.htaccess file in /public  by setting the vhost's AllowOverride to
All, commenting out the Directory statement and restarting apache.
Same result, which didn't surprise me too much. I have no idea why the
rewrites aren't having any affect.

So, here I am at the end of two days of trying to deploy one rails
app. I'm starting to feel pretty stupid since I feel what I'm trying
to do would be fairly common and *should* be simple. Can anyone out
there help me out?

--
Ryan
F15fdc7cb2e911b3808837f2be244add?d=identicon&s=25 Adam Denenberg (Guest)
on 2006-02-16 04:47
(Received via mailing list)
".......my config/environment.rb file. A quick lighty restart and my
paths
were preserved. (Almost there!) However, whenever I clicked on a link
the server would load
vhost.server.com/path/to/my/rails/app/controller/method/id and never
redirect back to the app's root as it should. Furthermore, the calls
to my controller's methods didn't have any effect: going back to the
root manually would bring things back in the same state. I double
checked all of my settings in apache and lighty, bounced both servers,
dug through the wiki and this list and eventually went to bed. I have
no idea why things don't work."

the link has to point to /path/to/rails/app since your app is in a
subdirectory of a vhost.  What you need is to manipulate the rails
routes.rbfile to look like something like

map.connect 'path/to/rails/app/:controller/:action/:id'

this shouldl resolve your issues.  You can not hide the
/path/to/rails/app
as long as it is a subdirectory of a parent vhost, however you can make
rails recognize the controller and actions you need.

-adam


On 2/15/06, Ryan Nielsen <rpnielsen@gmail.com> wrote:
> seamlessly with the existing server content and structure.
>
> 2) Grafting my apps by symlinking /public to a location in the
> directory root and then building FCGI and configuring Apache. I used
> these two wiki pages as guides:
> <http://wiki.rubyonrails.org/rails/pages/FastCGI> and
> <
http://wiki.rubyonrails.com/rails/pages/HowtoUseSy...
>
>
> I was reluctant to start with the proxy setup since that was in
> violation of goal 3, but almost all of the documentation out on the
> net strongly encouraged that route if Apache had to be used for legacy
> content. It also seemed simple to graft my app into a specific
> subdirectory under the document root. Unfortunately, I simply could
> not get it to work. Following
> <
http://www.hivelogic.com/articles/2005/12/01/ruby_...
Ac1feb66b7653d4e113cc3a31ae94e1d?d=identicon&s=25 Ryan Nielsen (Guest)
on 2006-02-16 21:31
(Received via mailing list)
On 2/15/06, Adam Denenberg <straightflush@gmail.com> wrote:
> > no idea why things don't work."
>
> the link has to point to /path/to/rails/app since your app is in a
> subdirectory of a vhost.  What you need is to manipulate the rails routes.rb
> file to look like something like
>
> map.connect 'path/to/rails/app/:controller/:action/:id'
>
>  this shouldl resolve your issues.  You can not hide the /path/to/rails/app
> as long as it is a subdirectory of a parent vhost, however you can make
> rails recognize the controller and actions you need.

I think changing the default route to
'path/to/rails/app/:controller/:action/:id' would fix my problems if I
able to successfully run using fcgi in apache. Unfortunately, I cannot
get the rewrite rules to take effect so the dispatch.fcgi script never
gets called and the routes are never processed.

How can I debug this failure? I'd love to get fcgi working in apache
so that I can drop all of this proxy stuff.

Changing the default route wouldn't help my proxy issues since lighty
is calling dispatch.fcgi with the proper ':controller/:action/:id'. In
fact, setting a default route of
'path/to/rails/app/:controller/:action/:id' breaks path recognition.
This makes sense since apache is proxying
'http://vhost.server.com/path/to/rails/app/:control... to
'http://lighty.server.com/:controller/:action/:id'.

As far as I can tell, proxying and url generation is working as it
should. For example, when I go to
"http://vhost.server.com/path/to/rails/app" the request is proxied to
"http://lighty.server.com" and I see the index that I expect. All
links on the page are prefixed properly and appear as
"http://vhost.server.com/path/to/rails/app/:control....
The problem is that nothing happens when I click on those links, even
though it seems as though all of the back-end magic is working
correctly.

--
Ryan
Ac1feb66b7653d4e113cc3a31ae94e1d?d=identicon&s=25 Ryan Nielsen (Guest)
on 2006-02-19 07:58
(Received via mailing list)
> I think changing the default route to
> 'path/to/rails/app/:controller/:action/:id' would fix my problems if I
> able to successfully run using fcgi in apache. Unfortunately, I cannot
> get the rewrite rules to take effect so the dispatch.fcgi script never
> gets called and the routes are never processed.
>
> How can I debug this failure? I'd love to get fcgi working in apache
> so that I can drop all of this proxy stuff.

Since the recommended "proxy from apache -> lighty" setup isn't
working, I'm trying to work out the problems with the "running under
fcgi in Apache" setup.

Here's what should be the relevant excerpt from the global apache 1.3
conf file:

	LoadModule fastcgi_module libexec/httpd/mod_fastcgi.so
	AddModule mod_fastcgi.c
	<IfModule mod_fastcgi.c>
		FastCgiIpcDir /tmp/fcgi_ipc/
		AddHandler fastcgi-script fcgi
	</IfModule>

This is my vhost configuration:

	<VirtualHost *:80>
		ServerName vhost.server.com
		DocumentRoot "/var/vhost"
		DirectoryIndex "index.html" "index.php"

		RewriteEngine On
		RewriteLog /var/tmp/rewrite.log
		RewriteLogLevel 9

		<Directory "/var/vhost/htdocs">
			Options All -Indexes -Includes +ExecCGI +FollowSymLinks +MultiViews
			AllowOverride All
		</Directory>
	</VirtualHost>

This is the .htaccess file:

	AddHandler fastcgi-script .fcgi
	AddHandler cgi-script .cgi
	Options +FollowSymLinks +ExecCGI

	RewriteEngine On
	#Alias /rails /var/vhost/htdocs/rails
	#RewriteBase /rails
	RewriteRule ^$ index.html [QSA]
	RewriteRule ^([^.]+)$ $1.html [QSA]
	RewriteCond %{REQUEST_FILENAME} !-f
	RewriteRule ^(.*)$ dispatch.fcgi [QSA,L]
	ErrorDocument 500 "<h2>Application error</h2>Rails application failed
to start properly

Most, if not all, of this should be the default setup, minus comments.
Why do I still get 500 errors when I try to access the site?

It took me less time to learn Ruby and Rails and write this app than
it's taken me to get this far in deployment... I'm sorry, but it
really shouldn't be this hard. I've tried so many different variations
of this over the past couple of days that I think I'm starting to go
mad.

All I want to do is seamlessly deploy my fancy new app in on a server
that has a bunch of legacy content.

--
Ryan
Ac1feb66b7653d4e113cc3a31ae94e1d?d=identicon&s=25 Ryan Nielsen (Guest)
on 2006-02-21 00:52
(Received via mailing list)
Ok, I've returned from mod_rewrite hell. In order to get this setup
working I had to basically rewrite the mod_rewrite directives. The
following fails:

RewriteRule ^$ index.html [QSA]
RewriteRule ^([^.]+)$ $1.html [QSA]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.cgi [QSA,L]

while the following works:

RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^(.*)[^/]$ %{REQUEST_URI}/ [R=301,L]
RewriteCond %{REQUEST_FILENAME}/index.html -f
RewriteRule ^([^.]*)$ %{REQUEST_URI}/index.html [L]
RewriteCond %{REQUEST_FILENAME}.html -f
RewriteRule ^([^.]+)$ %{REQUEST_URI}.html [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ dispatch.fcgi

For a period of time I even had to set RAILS_ROOT manually... now that
I've finally converged on a set of rewrite directives that actually
work, though, the explicit RAILS_ROOT doesn't seem to be needed.
Hopefully that remains the case.

I do have a question, though: Why have all of the [QSA] flags on the
original RewriteRule directives? It seems to me that we don't want to
append anything to the original query string -- we just want to
redirect. Right?

In the meantime, I'm going to file a ticket on this.

In summary: all of the documentation on getting rails to work when
symlinked into a Apache document root failed miserably for me. Here's
what worked:

1) Follow the instructions for building the fastcgi API on
<http://www.hivelogic.com/articles/2005/12/01/ruby_....
2) Also download the mod_fcgi sources from
http://www.fastcgi.com/dist. Follow the INSTALL file's instructions
for compiling and installing an Apache DSO.
3) Open up apache's global config file (on Mac OS X:
/etc/httpd/httpd.conf) and make sure the appropriate FCGI goop's in
place. Namely:
	LoadModule fastcgi_module     libexec/httpd/mod_fastcgi.so
	AddModule mod_fastcgi.c
	<IfModule mod_fastcgi.c>
	    FastCgiIpcDir /tmp/fcgi_ipc/
	    AddHandler fastcgi-script fcgi
	</IfModule>

Make sure the LoadModule and AddModule directives are grouped with the
file's other LoadModule and AddModule directives. The LoadModule
directive must come before and ClearModuleList directives, while the
AddModule should be after.
4) Bounce httpd. `sudo apachectl graceful` will do the trick.
5) If you are using a vhost config (I believe that, by default, this
is the case on Mac OS X. If you have a file in /etc/httpd/sites/ then
you should be.) then make sure that there is an "AllowOverride All"
directive somewhere in there and is wrapped in the correct Directory
directive. If all hosts should be able to run rails apps then go ahead
and change the global conf file's setting from "AllowOverride None" to
"AllowOverride All". This lets the .htaccess files take affect.

[As an aside, it would be wonderful to restrict the AllowOverride to a
specific filesystem directory outside of the document root, like
/var/www/rails when the doc root is /var/www/htdocs. Unfortunately,
this doesn't seem to be possible. You can only restrict it to a set of
paths in /var/www/htdocs, as far as I can tell. If anyone knows of a
way around this, I'd love to hear it.]

6) Create your rails app. Write your fancy code. Test.
7) Make sure all files and directories are readable by the web server.
Make sure the public/dispatch* files are executable by the server.
8) Create the symlink from <app>/public to <server document
root>/path/to/final/url
9) Edit .htaccess and replace the current mod_rewrite voodoo with my
(hopefully correct) voodoo listed above.
10) Profit.

Feedback is welcome. I wouldn't be surprised if I've done something
wrong...

--
Ryan
This topic is locked and can not be replied to.