How can mod_perl and Passenger run on the same Apache server? - ruby-on-rails

Is this even possible?
I have a Rails app running on Passenger and a mod_perl site that need to run on the same server. I've tried setting up two VirtualHosts and I've tried just using one VH and an Alias/Location for the mod_perl. In both cases, Passenger tries to serve the mod_perl app and tells me it can't find the correct files. Anyone know what I'm doing wrong?
Here's my setup atm:
NameVirtualHost *:80
RailsAutoDetect off
<VirtualHost *:80>
DocumentRoot (home of rails app)/public
RailsBaseURI /
</VirtualHost>
PerlModule Apache::DBI
PerlRequire /opt/rt3/bin/webmux.pl
Alias /rt /opt/rt3/share/html <== mod_perl app
<Location /rt>
AddDefaultCharset UTF-8
SetHandler perl-script
PerlHandler RT::Mason
</Location>

Well, for right now I've just set them up as two different VirtualHosts using different ports to connect. That works, but it's a little messy for my site to use and if anyone has a better idea, I'm all ears. Thanks.
Edit: Got it working! I ended up setting up two VirtualServers on different ports, then used mod-proxy to redirect traffic to the /rt site to the mod-perl VirtualServer (leaving the Passenger one as the default). This works great, and best of all my mod_perl site believes it's still in the same place as Passenger, which smooths out a lot of compatibility issues I was dealing with as well. I knew I was missing something simple! Just putting this up in case anyone else is having issues with this.

Related

Passenger on Apache: "doesn't seem to be running", app page gives 403; what next?

I'm having trouble getting my web server to talk to an app in Ruby on Rails. This is especially frustrating because I had it working last year for several months; I assume that some setting changed in the course of an upgrade in the meantime, but I can't find it.
The symptom: when I navigate to the page that should be serving the app (a sub-URI of the main domain), Apache gives a 403 error: "There is either no index document or the directory is read-protected.". The bottom of this error page gives the config string "Apache/2.4.9 (Unix) OpenSSL/1.0.1g Phusion_Passenger/4.0.37", which seems to indicate that Passenger is loaded and running. If I navigate directly to the public directory, or to the physical directory where the app lives, Apache happily displays the file listing of that directory (and if I click on any of the files, they display), so it doesn't seem to be that kind of permissions problem, at least.
In the httpd.conf file, there were the following lines to load Passenger:
LoadModule passenger_module modules/mod_passenger.so
PassengerRoot /usr/local/rvm/gems/ruby-2.0.0-p247/gems/passenger-4.0.14
PassengerDefaultRuby /usr/local/rvm/wrappers/ruby-2.0.0-p247/ruby
PassengerEnabled Off
PassengerLogLevel 3
and, later, the following lines to tell Apache about the app:
<Location "/pathtoapp/f13">
Options +Indexes +ExecCGI +FollowSymLinks -MultiViews
Order allow,deny
Require all granted
PassengerEnabled On
RackBaseURI /pathtoapp/f13
#RailsEnv production
RailsEnv development
</Location>
The app itself lives in /pathtoapp/f13app, and there was a symlink in the filesystem from /pathtoapp/f13 to /pathtoapp/f13app/public. If I created a symlink /pathtoapp/test to /pathtoapp/f13app/public, it worked fine (in that it showed a file listing for the public directory, so again, no permissions problems).
I tried changing around a few things based on trawling the net for possible solutions. Most didn't appear to affect anything, so I reverted them; I did note that changing Location to Directory meant that navigating to /pathtoapp/f13 in my browser gave me the file listing of the public directory.
I tried (re-)running sudo passenger-install-apache2-module even though the Apache error seemed to indicate passenger was already installed. It (re-?)installed and prompted some changes to httpd.conf, which now has:
LoadModule passenger_module /usr/lib/ruby/gems/2.1.0/gems/passenger-4.0.37/buildout/apache2/mod_passenger.so
<IfModule mod_passenger.c>
PassengerRoot /usr/lib/ruby/gems/2.1.0/gems/passenger-4.0.37
PassengerDefaultRuby /usr/bin/ruby
</IfModule>
(I'm not sure if passenger did the ruby upgrade into /usr/lib or if that came in some earlier system update I'd done, but the indicated files are indeed there.) Later in httpd.conf, based on the current text of http://www.modrails.com/documentation/Users%20guide%20Apache.html#deploying_rack_to_sub_uri , I now have
Alias /pathtoapp/f13 /pathtoapp/f13app/public
<Location "/pathtoapp/f13">
PassengerBaseURI /pathtoapp/f13
PassengerAppRoot /pathtoapp/f13app
PassengerEnabled On
RailsEnv development
</Location>
<Directory "/pathtoapp/f13app/public">
Options +Indexes +ExecCGI +FollowSymLinks -MultiViews
Allow from all
Require all granted
</Directory>
I then removed the in-filesystem symlink from f13 to f13app/public. And, of course, I've restarted httpd.
passenger-status still reports "ERROR: Phusion Passenger doesn't seem to be running.", and navigating to the app's page (/pathtoapp/f13) still gives the same 403 error. I'm now completely stuck as to what to try next, or even what diagnostic tool I should be using to help triage the problem. Any ideas?
(Extra system info: uname -r is "3.14.1-1-ARCH"; apachectl -v is "Apache/2.4.9 (Unix)"; passenger -v is "Phusion Passenger version 4.0.37")
After a lot of mucking about, I finally discovered that the problem was with the Apache configuration itself: Apache was never getting far enough in to even talk to Passenger. Specifically, on the lines
Alias /pathtoapp/f13 /pathtoapp/f13app/public
and
PassengerAppRoot /pathtoapp/f13app
it's important that the pathtoapp be relative to the filesystem, not the URI. So those two lines should really be more like
Alias /pathtoapp/f13 /srv/http/htdoc/pathtoapp/f13app/public
and
PassengerAppRoot /srv/http/htdoc/pathtoapp/f13app
though of course the exact details will vary by system. I'm not sure if this was an issue with Apache 2.2-2.4 upgrade or something else (I have root access but am not the primary sysadmin on this system), but now that I've found the problem, I didn't want to leave the question hanging. I'll also add that the Apache config line
LogLevel debug
was invaluable in helping me track down which system component the problem was in.

Rails not rendering assets over SSL (404 Not Found error)

I am kind of new to Rails and am struggling with an issue that is preventing my assets to be found if I try to access my test app using an SSL connection.
As an example of what I am referring to, if you try to access
http://domain.com/testapp the default rails page loads fine and I have no issues at all.
You can also access a page I created using this route
http://domain.com/testapp/static_pages/home
However the same address, if accessed via HTTPS is returning 404 errors for all of my assets. I am also unable to access any routes (they all return 404).
https://domain.com/testapp
https://domain.com/testapp/static_pages/home
I am currently using an Apache server with Passenger installed, and here is what my virtual host configuration looks like:
<Directory /var/www/testapp/public>
PassengerEnabled on
PassengerAppRoot /var/www/testapp
RailsBaseURI /testapp
</Directory>
Any ideas of why this might be happening?
Thanks,
Rog
Thanks all, I finally figured out what was going on so in the interest of others having the same issue, the virtual host configuration was only being applied to the default port (80) so I had to specify port 443 as well.
<VirtualHost *:80 *:443>
<Directory /var/www/testapp/public>
PassengerEnabled on
PassengerAppRoot /var/www/testapp
RailsBaseURI /testapp
</Directory>
</VirtualHost>
For people using Media Temple's DV server, this configurations has to be specified in two separate files (make sure you remove the VirtualHost tags).
vhost.conf
vhost_ssl.conf
And don't forget to restart apache.
/usr/sbin/apachectl -K graceful

Run two different Rails application on one dedicated server

I have one dedicated server with below configurations
i3 - Dual Core - 3.06Ghz H/T
16GB RAM
500GB SATA2
Now I want to execute two different Rails application on one dedicated server. A both application are different but they are using common database.
Is it possible to do that? If yes – How can I do that?
Is Phusion Passenger with Apache a good approach? If yes - How can I configure two application with one Phusion Passenger server?
I will describe how I run multiple Rails applications on one Linux server, using Apache, Phusion Passenger, and some version of Ruby. You have many choices, but this should help you get started. Many of these details come from the installation script
First, install Phusion Passenger.
> gem install passenger
Second, build the Apache 2 Passenger module. You should be able to execute the following script installed during step one.
> passenger-install-apache2-module
This script will compile the Apache 2 module and explain how to configure Apache. If dependencies are missing the script should offer some helpful advice about how to install them.
Third, edit your Apache configuration file. I have to add something like this. (Just use this for references and don't worry about .rvm) The script run in step two will give you something that you can copy and paste.
LoadModule passenger_module /Users/me/.rvm/gems/ree/gems/passenger-3.0.9/ext/apache2/mod_passenger.so
PassengerRoot /Users/me/.rvm/gems/ree/gems/passenger-3.0.9
PassengerRuby /Users/me/.rvm/wrappers/ree/ruby
Fourth, add something like this to your Apache configuration file for each application you want to run.
<VirtualHost *:80>
ServerName app1.example.com
DocumentRoot /somewhere/app1/public # <-- be sure to point to 'public'!
<Directory /somewhere/app1/public>
AllowOverride all # <-- relax Apache security settings
Options -MultiViews # <-- MultiViews must be turned off
</Directory>
</VirtualHost>
If you have two Rails application sharing one database then they will both have similar connection information in config/database.yml
Yes, It's definitely possible. I've never done it with Passenger + Apache, but I'm sure thats a fine way. I've only ever done it with thin + nginx.
Passenger Phusion with Apache is a solid approach. The fact that they are using the same database shouldn't be a problem (just make sure they don't step on each other in any way).
Generally, just set things up as normal, but take a look at Apache name-based virtual hosts:
http://httpd.apache.org/docs/2.2/vhosts/name-based.html

jRuby deployment into a subfolder in Tomcat

While developing a jRuby application using webbrick as the webserver, all my code is written with http://localhost:3000 as the root.
When deploying to Tomcat, I create a WAR file and it creates a subfolder under the webapps/ folder: localhost:8080/project_name/
This causes a load of problems with my code. Is there anything I can do in my ruby routes.rb file to deal with this?
Should I resort to using some sort of virtual host in Tomcat?
Although this question is quite old, we ran into a similar problem with a current project of ours. The project is done with JRuby on Rails, using Tomcat 6.x (7.0.26 in development for testing purposes), needing multiple deployments of the same application on the same servlet container, having individual server names. It took me quite some time to find a good enough solution and I like to share it with you.
Continue reading, if root context is no option for you (as cosmikduster described it above). If it is, use it.
TL;DR
Use virtual hosts for each app provided by Tomcat to give yourself root context for individual apps deployed on the Tomcat servlet container. The explanation provided below is based on this and is just an illustrative example with a step by step solution attached.
The problem
The problem arises when deploying a *.war file to Tomcat, as per default, the deployed app, let's call it awesome_app_uno for now, will live under http://localhost:8080/awesome_app_uno. This is all fine and dandy but can cause problems with the internal path generation of rails, which by default will now use /awesome_app_uno for every path generated.
Explanation & initial setup
Now, JRuby Rack, which is the rack implementation for JRuby is kind enough to include a feature that automatically sets the relative_url_root for you, I quote from the README:
The Rails controller setting ActionController::Base.relative_url_root is set for you automatically according to the context root where your webapp is deployed.
Normally, I would cheer - but in the real world, we'd probably do not want something like this, as we'll have something like a proxy to get ourselves some nice domainname, e.g.
http://awesomeappuno.com/
And now we're screwed. If we take a naive solution for this, we'd probably end up using an Apache (or an nginx, whatever you like) to function as a proxy. We'll want something like
http://awesomeappuno.com/ -> http://localhost:8080/awesome_app_uno
Just for the fun of it, lets look at the configuration for an apache config file:
<VirtualHost *:80>
ServerName awesomeappuno.com
ErrorLog /var/log/apache2/awesomeappuno_error.log
LogLevel warn
CustomLog /var/log/apache2/awesomeappuno_access.log combined
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://localhost:8080/awesome_app_uno
ProxyPassReverse / http://localhost:8080/awesome_app_uno
</VirtualHost>
Kindly stolen from here.
The madness
With that being your configuration, you can now visit http://awesomeappuno.com.
This is where you'll notice, that despite now having a clean root without prefixes, Rails will still generate paths with the /aweseome_app_uno prefix, i.e.
http://awesomeappuno.com/awesome_app_uno/the/path/you/wanted
This is generally undesirable. While some of you could propably live with this, I couldn't. Moreover, there's awesome_app_dos coming up on the horizon which needs to be deployed on the same Tomcat instance, needing it's own domain name http://awesomeappdos.com, along with the two ugly cousins awesome_staging and awesome_integration behind it. The gist is, if you're forced to use the same Tomcat container for all these apps, giving on app root context is not really an option.
You can try some solutions like writing custom initializers, resetting the ENV hash, which gets initially filled by the jruby-rack (see comments and answers above). You might find yourself rewriting the paths manually or using absolute urls. Or you create hacks for a single environment. Or you could try to use rewrites. Or mod_subsitute. You could even try using multiple tomcat instances running everything under root context.
Don't do that.
Please.
Virtual Hosts to the rescue
While reading up on the issue (and trying everything described in the last paragraph), I stumpled on an entry in the ruby forum.
You can create virtual hosts with Tomcat, providing a root context for each app. To get more in depth knowledge, you can start here or here. In short, suppose your Tomcat (7.x) is located under /usr/local/tomcat, this would be the quick and dirty version:
Create a virtual host
The host will have it's appBase within the tomcat installation for this. If this isn't your stale, change it.
(cd /usr/local/tomcat/libexec)
I am using an installation via homebrew here, I am on a mac under OSX 10.7.4 - however with slight alterations this should work on a standard Debian as well.
Open up conf/server.xml and within the engine tag create another host:
<Host name="awesome_app_uno" alias="awesomeappuno" appBase="awesome_app/uno" unpackWARs="true" autoDeploy="true" xmlValidation="false" xmlNamespaceAware="false">
<Context path="" docBase="ROOT"></Context>
</Host>
After that, create a file called conf/Catalina/awesome_app_uno/ROOT.xml. These are the contents:
<?xml version="1.0" encoding="UTF-8"?>
<Context docBase="${catalina.base}/awesome_app/uno/ROOT.war">
</Context>
Afterwards, place the awesomeappuno.war as /usr/local/tomcat/libexec/awesome_app/uno/ROOT.war and restart Tomcat. You can check the virtual host via http://localhost:8080/host-manager/html.
You should be able to visit http://awesome_app_uno:8080 and find your app there. Paths should now be correct, however, port 8080 isn't that user friendly. With slight changes to the previously shown apache config, we can also get a nice name for this:
<VirtualHost *:80>
ServerName awesomeappuno.com
ErrorLog /var/log/apache2/awesomeappuno_error.log
LogLevel warn
CustomLog /var/log/apache2/awesomeappuno_access.log combined
<Proxy *>
Order allow,deny
Allow from all
</Proxy>
ProxyPreserveHost On
ProxyRequests off
ProxyPass / http://awesome_app_uno:8080/
ProxyPassReverse / http://awesome_app_uno:8080/
</VirtualHost>
Reload your apache and you should now have no further problems with pathing, routing, because everything now happens under the root context of the tomcat virtual host.
Rinse and repeat for additional apps on the same tomcat instance.
The end
Hope i could help you with this.
lg,
flo
There is code in JRuby-Rack to deal with this. Depending on the version of Tomcat and/or Rails, it may not be detecting the extra context path correctly.
The environment variable that is supposed to take effect is called ENV['RAILS_RELATIVE_URL_ROOT']. You might print out the value of that expression during boot time and see whether it's getting set when you run in Tomcat.
The code in question is here:
https://github.com/nicksieger/jruby-rack/blob/master/src/main/ruby/jruby/rack/rails.rb#L32-38
The versions of Tomcat, Rails and JRuby-Rack you're using would help diagnose the problem further.
Your app should almost never care about the host/domain/port it will run under. To deploy at the relative path /, instead of /myapp, simply rename the WAR to ROOT.war instead of myapp.war when you copy it to the tomcat/webapps folder.

Rails app Hangs and Ruby uses 100% CPU

I have an apache2 server running Phusion Passenger. On this machine I have two virtual hosts setup each look like this (path's are different for the 2nd virtualhost...but other directives are the same)
ServerName beta.mysite.us
DocumentRoot "/var/www/beta/mysite/public"
<Directory "/var/www/beta/mysite/public">
RewriteEngine on
AllowOverride All
Options FollowSymLinks
</Directory>
# http://www.modrails.com/documentation/Users guide.html
PassengerAppRoot "/var/www/beta/mysite"
RailsEnv development
PassengerMaxPoolSize 6
PassengerDefaultUser mysite
# PassengerHighPerformance does come at a trade off of lack of support for mod_rewrite
PassengerHighPerformance off
RailsSpawnMethod conservative
RailsFrameworkSpawnerIdleTime 0
RailsAppSpawnerIdleTime 0
PassengerPoolIdleTime 300
ErrorLog "/var/log/httpd/mysite-beta-error_log"
CustomLog "/var/log/httpd/mysite-beta-access_log" common
Apache starts fine. I can go to one of the virtualhosts and it will load Rails and work. When I go to the second virtualhost, a ruby process spawns ("Rails: /var/www/mysite/current" according to ps awuxf) and uses 100% CPU. This process never exits. At this point neither virtualhost is responsive. If I kill the the offending ruby process, another ruby process replaces it and uses 100% cpu. If I kill these processes about 5-6 times, then both virtualhosts respond but they, are somehow, running the same Rails app?!
I have another virtualhost on this machine that is not setup with phusion passenger..This one never exhibits any problems.
Any help / ideas would be much appreciated!
I would recommend switching to nginx
I had faced similar issues with phusion passenger, with no success in debugging. Later, I switched to apache2+mongrel with mod_proxy. I have seen best stability with nginx though. nginx FTW :)
The obvious thing would be to check you don't have any inadvertent infinite loops or impossible to finish conditions in any of your application. It's all too easy to do a find(:all) by accident on a table too massive to fit in memory.
Does it jam immediately or is there something you must do to trigger it? For example, loading a specific page, or not loading a page at all. There could be something in an initializer that causes trouble.
Being able to power up script/console is always a good sign, especially if you can load records. There's not a lot of information in your description. A copy-paste of the output of 'ps aux' would help.
Is it possible you have some code causing this? We have a number of apache/passenger installations. It's more likely something with your code than aapache/passenger.
(A reminder to my future self)
I recently inherited a Rails 2.3.x/Ruby 1.8.7 app running on Passenger and Apache2. I updated RubyGems from an old 1.3.x to 1.6.2, and immediately noticed a ruby process spiking to 100% when passenger loaded. Downgrading to RubyGems 1.5.3 resolved the issue.

Resources