I have found iis/aspi/fast cgi to be un-reliable, seems to crash once a week, I think it is related to a specific size of a post, But have not had the time to track it down
Update - Oct - 2007
Thanks this page seems to be quite popular
A much better/reliable solution is to use IIS with Mongrel behind it,
Check out HOW TO DEPLOY: Rails under IIS with ISAPI_Rewrite3/Mongrel
Update - Dec - 2007
I have updated this entry for rails 2.0
Check out Rails v2.0 with IIS, ISAPI_Rewrite3, Mongrel
Disclaimer
First off I dont recommend it, But if you must as dictated by an outside source here are the steps.
There are severl source's of information around but none that give and how/who with step-step details.
After accessing various sources, I finally got IIS to work "reasonably reliably", PS: Included are tips for trouble shooting permissions issues.
Background - How do you get IIS to talk to rails
When IIS sees an url like http://host/something.asp?search=abc, It looks up and sees if there is an application (dll/exe) associated with the extension .asp, if there is then it passes the request to the application associated with the extension.
So in order to run a ruby application behind iss, we need to associate a extension with "rubyw.exe" for each rails app, the extension can be anything, lets call this ".rap1" (Ruby Application 1).
Below details that steps to do this
STEP 1 - Rewrite The Url
We need to give IIS a url that looks something like http://host/something.rap1?information-for-rails-app,
But Rails generates nice looking urls, e.g. http://host/app1/controller/method, IIS allows you to re-write URL's,
So we take http://host/app1/controller/method?etc=1 and convert it to http://host/something.rap1?opnq=/controller/method?etc=1
To do this we grap "Ionic's Isapi Rewrite for IIS" (details below)
STEP 2 - Rewrite it back for Rails
But the Rails app is expecting "/controller/method?etc=1" not "opnq=/controller/method?etc=1", So you need to re-write it back in to a nice url inside rails.
To do this we patch ActionController::AbstractRequest.request_uri (see app1/lib/action_controller_request_ext.rb)
STEP 3 - app prefix the Url
Since we will be running multiple apps, we need to prefix the urls rails generates with /app1, to distinguish each application (see app1/lib/environment.rb, ActionController::AbstractRequest.relative_url_root = "/app1")
Background - Running Ruby from IIS
OK lets assume we have the url's ok, Next step is to actually run ruby (rubyw.exe) to get the app to work.
We could run rubyw directly as a cgi, but this would mean for each request, rails is started run and closed, VERY VERY Slow.
So we take "Shane Careveo's Fast CGI" dll which keeps the rails app running and simply feeds it new requests>
STEP 4 - Map your extension
Using IIS Map the .rap1 extension to call the isapi_fcgi.dll. (which will call rubyw)
STEP 5 - Configure fcgi to run Ruby
Tell the isapi_fcgi.dll what ruby application to run when it gets called with a .rap1 extension, (details below)
You will also need to install ruby code, to deal with how isapi_fcgi disptaches. (see dispatch.fcgi)
STEP 6 - Permission
Fix up permissions as ruby will be run as a limited user.
Misc Notes
You can replace "opnq" in the url, with anything you like, I kept it the same as used by RORIIS, also the "something" can be any name you want, I called it fastcgi, but all we need is for IIS to look at the extension .rap1 and call isapi_fcgi.dll that in turn runs ruby!!!
Install Ruby/Rails MSSQL Software
The boring bit, This section you can skip, But was included for completeness
Install MSSQL
> dotnetfx.exe # Install .Net Frame work 2.0 > SQLEXPR32-SP2.EXE # MS SQl Server 2005 EXPRESS # Install to "C:\Program Files\Microsoft SQL Server 2005 EXPRESS" # Used Named Instance "SQLEXPRESS" # Used mixed authentication, "sa" passsword "yourchoice" > SQLServer2005_SSMSEE.msi # Install MS Sql Server Managment Studio
Install Ruby + Gems
> mkdir C:\ruby > run ruby185-21.exe # Install ruby # Select Install "Ruby" and "Enable RubyGems" # Install to "C:\ruby # Check C:\ruby\bin to your everyones path !! # download rubygems, un-zip and run setup.rb > ruby setup.rb # Install ruby gems
Install Rails
> cd C:\ruby > gem install --include-dependencies rails # Wait may take a while !!! > gem install --include-dependencies win32-service # pick the most recent mswin32 !! # gem install --include-dependencies mongrel # pick the win32 pre-built # gem install --include-dependencies mongrel_service
Install MSSQL Drivers
# download ruby-dbi, un-zip and run setup.rb > ruby setup.rb config --with=dbd_ado > ruby setup.rb setup > ruby setup.rb install # Patch sqlserver_adapter.rb (See Rails Ticket #7733) > cd C:\ruby\lib\ruby\gems\1.8\gems\activerecord-1.15.3\ lib\active_record\connection_adapters > edit sqlserver_adapter.rb # Line 28x: "=~ /null/ ? nil" ==> "=~ /null/i> ? nil" # Case insensitive match on the word null
Install other gems (e.g. RMagick / Faster CSV)
# download ImageMagick and run setup.rb > ImageMagick-6.3.0-7-Q8-windows-dll.exe # Tick [x] Update executable search path. # download rmagick gem and install > gem install rmagick --local # Note: Documentation is in C:\ruby\lib\ruby\gems\ # 1.8\gems\rmagick-1.14.1-win32\doc\index.html # download fastercsv gem and install > gem install fastercsv --local
Create Rails Application and check operation
Create a basic rails app, for testing. I assume c:\rails is where your rails apps will be placed> mkdir C:\rails > cd rails > rails app1 # Create rails app called app1 > ruby script/server # Run WebBrick to test > iexplore.exe http://localhost:3000 # Should get welcome page > iexplore.exe http://localhost:3000/controller/etc # You should see routine error, no route found... # exception from the from the rails app > Ctrl+break > exit
The Details
The original source for set-up is as follows. Thanks to all.
"Ruby On Rails For IIS Fast-CGI" (This contains all the files menthoned)
NOTE: If did not install "ROR4IISFCGI_1.0.5.exe", As the install is for a single rails application, Simply Open the file with say 7-Zip and extract. I used this file simply as the source. For each step I have detailed only the final destionation folder
The set-up process detailed below, assumes the folllowing.
- Ruby is installed in c:\ruby
- Your application is called "app1" and resides in c:\rails\app1, The extension nominated for is .rap1
- Iis has C:\Inetpub as its base
- Windows is C:\Windows
Install/Configure IaspiRewriter
The following files are installed/edited
Inetpub Inetpub\IsapiRewrite4.dll Inetpub\IsapiRewrite4.ini # Copied and Edited rails rails\app1 rails\app1\lib rails\app1\lib\action_controller_request_ext.rb rails\app1\config\environment.rb # Edited rails\app1\config\routes.rb # Edited
Rewrite The Url
# copy/install Inetpub\IsapiRewrite4.dll, Inetpub\IsapiRewrite4.ini > inetmgr.exe # Add url rewriter # Goto: Default Web Site -> Properties -> ASPI Filters -> Add Name: IsapiRewrite4 Exe: C:\Inetpub\IsapiRewrite4.dll > cd C:\Inetpub > edit IsapiRewrite4.ini # Add the following rule to take urls with /app1 to call fastcgi.rap1 RewriteRule ^/app1(/[^.]+)$ /fastcgi.rap1?opnq=$1 # Note: urls, with a '.' in them are not mapped. # This is cool, because iis will handel serving up the the # public images/css etc (see later) > edit routes.rb # If using Web Services. Change the .wsdl to _wsdl as now cannot have a "." in a url destined for rails # change ':controller/service.wsdl' => ':controller/service_wsdl'
Rewrite it back for Rails
# copy/install rails\app1\lib\action_controller_request_ext.rb > cd C:\rails\app1\config > edit environment.rb # Add the following line to the section titled # "Include your application configuration below" require 'action_controller_request_ext.rb'
app1 prefix the Url
> cd C:\rails\app1\config > edit environment.rb # Add the following line to the section titled # "Include your application configuration below" ActionController::AbstractRequest.relative_url_root = "/app1" if ENV['RAILS_ENV'] == 'production'
Install/Configure FastCGI
The following files are installed/edited
Inetpub Inetpub\isapi_fcgi.dll Inetpub\wwwroot Inetpub\wwwroot\fastcgi.rap1 # Created manually rails rails\app1 rails\app1\FastCGI.reg # Created manually rails\app1\public rails\app1\public\dispatch.fcgi ruby ruby\lib ruby\lib\ruby ruby\lib\ruby\site_ruby ruby\lib\ruby\site_ruby\1.8 ruby\lib\ruby\site_ruby\1.8\fcgi.rb ruby\lib\ruby\site_ruby\1.8\i386-msvcrt ruby\lib\ruby\site_ruby\1.8\i386-msvcrt\fcgi.so Windows Windows\System32 Windows\System32\libfcgi.dll Windows\System32\msvcp71.dll # if not already present Windows\System32\msvcr71.dll # if not already present
Configure fastcgi to run Ruby
Place settings in the register to tell isapi_fcgi which ruby app to run based on the file extension it is called as
> copy files as indicated above ... > echo "# fastcgi" > C:\Inetpub\wwwroot\fastcgi.rap1 # Simply a dummy file > edit/create C:\rails\app1\FastCGI.reg # Place the following in the file. # These registry settings tell isapi_fcgi.dll what rails # app to run based on what file extension it is called with [HKEY_LOCAL_MACHINE\SOFTWARE\FastCGI] [HKEY_LOCAL_MACHINE\SOFTWARE\FastCGI\.rap1] @="" "BindPath"="Rails-FCGI-app1" "AppPath"="C:\\ruby\\bin\\rubyw.exe" "Args"="C:\\rails\\app1\\public\\dispatch.fcgi" "Environment"=hex:52,41,49,4c,53,5f,45,4e,56,3d,70,72,6f,64,75,63,74,69,6f,6e,0d,0a,00 "StartServers"=dword:00000003 "IncrementServers"=dword:00000001 "MaxServers"=dword:00000006 "MaxProcMem"=dword:00000064 "Timeout"=dword:00000258 # The key "Environment" contains "RAILS_ENV=production\r\n\0" > cd C:\rails\app1\ > FastGGI.reg # Load details into the widows registry
Configure/Map your extension IIS
We will Map a Virtual directory to our application, Map the extension .rap 1 to our application
> inetmgr.exe # Add in your application to Virtual dir # Goto: Default Web Site -> New Virtual Directory -> Name -> app1 Path -> C:\rails\app1\public Permissions -> Read > netmgr.exe # Add in your application extension .rap1 # Goto: Default Web Site -> Properties -> Home Directory -> Configration -> Mapping -> Add Executable -> C:\Inetpub\isapi_fcgi.dll Extension -> ".rap1" # with the "." Script Engine -> Ticked Check the File Exists -> Ticked # If the OK button is gray, (bug in IIS 5.1) click on the Executable File Name a 2nd time # Ensure Cache ISAP Extensions is Ticked
Configure Permissions (the messy bit)
Your app wont run yet, as rubyw will be running as a restricted user. Perform the following steps. We will set-up a group called "Rails" and assign the IIS process user "IWAM_computername" to this group.
> compmgmt.msc # Goto: Local Users and Groups -> New Group -> Rails # Add new Rails group (with no members) > compmgmt.msc # Goto: Local Users and Groups -> IWAM_computername -> # Properties -> Member Of -> Add -> Rails
Configure iis to run application's as the local user "IWAM_computername". This makes managing permissions simpler. Server 2003+ only, Configure IIS to accept the dll's and rubyw.exe application Dont forget this step otherwise your application will not run !!! Perform the following steps to test it works. Ist check your app still works with WebBrick (see above Installing Ruby etc) Simply repeat the steps above (that relate to a specific application) for your application.
Assgning your own name and extension. Simply change "app1" to your application name and".rap1" to your nominated extension I would not recommend using .asp/.aspx extension, quite yet, mind you with ruby/rails going so well, it wont be long before the .aspx extension will become un-used. :-) NOTE: Do make sure you change the "BindPath"="Rails-FCGI-app1" in the registry for fast CGI
for each application, otherwise you may end up with one app's url going to another. Some trouble shooting tips. Try the following to run your app as a restricted user. It might highlight some things I hope this write up helps some. It helped me. I know there is not much documentation on multiple apps and IIS. I have done it, but think IIS -> Apache -> Mongrel would be a better choice. All comments welcome
> inetmgr.exe
# Under Server 2003+
# Goto: Application Pools ->
DefaultAppPool -> Properties -> Identiry
# Change to "IWAM_computername"
# Under XP
# Goto: Default Web Site -> Properties ->
Home Directory -> Identiry
# Application protection to "Medium (Pooled)""
# Under Server 2003+ (Only)
> inetmgr.exe # Set permissions on applications
# Goto: Web Server Extension -> Add Web Server Extension
Name: Rails
Files: Inetpub\IsapiRewrite4.dll,
Inetpub\isapi_fcgi.dll,
Windows\System32\libfcgi.dll,
C:\ruby\bin\rubyw.exe
Status: Allowed
Set premissions on the required files/dirs for the "Rails" group
Test It
> iisreset.exe # Re-start iis
> iexplore.exe http://localhost/app1/controller/etc
# You should see routine error, no route found...
# If so you have an exception Message from the Rails app, cool !!!
# If you get fast cgi error or page not found,
# check out trouble shooting.
Configure Your Second Application
Trouble shooting
First off, Does rubyw start within iis.
Try running your app as a restricted user.
> runas /user:IWAM_TEST cmd
# You should get another cmd window as this user,
> env
# Look at the env, look ok.
> cd \rails\app1
> ruby script/server
# Look at the output, Does it say "unable to access log file"
# If so fix permissions
Navigate to http://localhost:3000/controller/etc
# Any more messages
> Ctrl+break # break out of WebBrick
> exit
Conclusion
An Update
There is one small change you need to make to cgi.rb to make fastcgi more reliable.
Check out Running Rails Apps More Reliability under IIS
1 comment:
An update by the author, there is one small change you need to make to cgi.rb to make fastcgi more reliable.
Check out Running Rails Apps More Reliability under IIS
Post a Comment