How to deploy, using lighttpd on windows and SCGI
Chris Hulbert – chris-dot-hulbert-at-gmail
(ssl added to this by Noah Stern nfstern-at-yahoo)
IMPORTANT NOTICE
These days, for best practice, you will want to deploy using Mongrel
However, Mongrel does not support SSL as of this writing (2007-03-30) whereas Lighty does. You could use Apache or run the pound load balancer in front of Mongrel (requires a compile), but I found these solutions more hassitudinal to get working than Lighty. If you need this functionality, see instructions under the header SSL on how to enable this.
Things you’ll need:
Lighttpd 1.4.13 (or above) for windows
Rails (gem i rails)
Getting it working
Ok, for all of this example, i’m assuming that ruby is installed into c:\ruby, and lighty is installed into c:\lighttpd, and your rails app is installed in c:\railsapp.
Edit your c:\lighttpd\etc\lighttpd.conf file like this (obviously don’t replace the file with this, i’ve left all the unchanged bits out, to save space here):
server.modules = (
"mod_rewrite",
"mod_redirect",
"mod_access",
"mod_accesslog",
"mod_status",
"mod_scgi")
server.document-root = "C:/RailsApp/public"
server.errorlog = "C:/RailsApp/log/lighttpd-errors.log"
accesslog.filename = "C:/RailsApp/log/lighttpd-access.log"
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi", ".scgi" )
server.error-handler-404 = "/dispatch.scgi"
scgi.server = ( "dispatch.scgi" => ((
"host" => "127.0.0.1",
"port" => 9999,
"check-local" => "disable"
)) )
scgi.debug=0
status.status-url = "/server-status"
status.config-url = "/server-config"
END OF lighttpd.conf
Now, above you would have noticed that we didn’t have any url rewrite rules, and that the 404 not found is routed to the dispatch.scgi.
NOTE: there is NO dispatch.scgi file in your c:\railsapp\public folder. This is a virtual file.
Okay, next up, we need to set up the SCGI server that lighty will be talking to. Before you do this, make sure you have installed the gems for cmdparse and highline.
Go into your command prompt, and go into c:\railsapp, and run this:
scgi_ctrl config -S
This will generate your c:\railsapp\config\scgi.yaml file. Have a look at it if you want.
And now that SCGI is ready to go, i’ve set up a batch file that i run that kicks off lighty and my scgi runner:
@echo off
c:
cd C:\lighttpd\sbin
echo Stopping lighty...
process.exe -k lighttpd.exe > nul
echo Starting lighty...
lighttpd.exe -f ..\etc\lighttpd.conf
echo Stopping SCGI_service...
Process.exe -k ruby.exe > nul
cd C:\railsapp
echo Starting SCGI_service...
scgi_service
END OF c:\railsapp\run.bat
SSL
If you need this enabled because you are testing a secure login, payment system, etc., etc., and you want to set this up in a development environment, there are a few more steps involved. Fortunately, it’s not difficult.
First off, download & install the ssl_requirement plugin using this command in a windows command box: ruby script/plugin install ssl_requirement.
Next make the following modifications to the lighttpd.conf file as follows:
If you are typically running your application in development mode on port 3000 (as outlined by Curt Hibbs in his excellent tutorials), uncomment the server.port parameter and set it to 3000.
server.port = 3000
Also, I uncommented the server.bind parameter as follows:
server.bind = “127.0.0.1”
You may or may not need to do this (I did).
Next, you need to generate a certificate.
Lighttpd 1.4.13 comes with the openssl package compiled in and instructions, but basically you do this:
Open up a windows command box & go to c:\lighttpd\sbin (cd c:\lighttpd\sbin)
run this command:
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
Enter the required information at the prompts.
Add these lines to your lighttpd.conf file beneath the comment SSL engine
$SERVER“socket” == “127.0.0.1:443” {
ssl.engine = “enable”
ssl.pemfile = “C:/lighttpd/sbin/server.pem”
}
This tells Lighty what to do for requests coming in on port 443, which is basically to enable ssl & where to find the pemfile.
If you are running on port 3000 (or another port), you need to make a slight hack to the ssl_required.rb as of this writing to get redirects from https back to http working correctly (in my application, only certain pages require ssl and I want to redirect off it for pages that don’t need it).
This block:
def ensure_proper_protocol
end
Should be modified to something like this:
def ensure_proper_protocol
end
Observe the addition of the port number for non-production environments in the elsif clause.
Also, if for some good reason, you have a situation in your application where your secure page calls an action that’s not tied to an rhtml (or possibly rjs) file (mine did), you need to set ssl_allowed for that action. Otherwise you get a 404 and it’s not clear from the page and the logs what’s causing the problem.
That should more or less get you going. A couple of extra things you may find useful.
If you are doing file and/or image uploads, set this parameter in your lighttpd.conf file:
server.upload-dirs = ( “c:/lighttpd/tmp” )
I kept having my application blow up because the default upload for lighty is /var/tmp which doesn’t exist in windows.
You may also like to have a shutdown script for Lighty & SCGI. Killing Lighty from the task manager can sometimes leave processes running if you’re not careful to stop the related processes. I called mine StopLighty.bat which borrows from the bat file above and contains the following:
@echo off
c:
cd C:\lighttpd\sbin
echo Stopping lighty…
process.exe -k lighttpd.exe > nul
echo Stopping SCGI_service…
Process.exe -k ruby.exe > nul
cd C:\railsapp
Make sure your scgi.yaml file has this parameter:
:disable_signals: true
and if you are running in development mode, this:
:env: development
as opposed to :env: production
End of SSL
And finally, so that it’ll all start up as a service when the server is switched on, without me having to log on and run that batch file, you use SRVANY, which is the microsoft tool for running anything as a service.
You can find instructions for this elsewhere, but the important bit is to set this up in the registry:
HKLM\SYSTEM\CurrentControlSet\Services\RailsApp\Parameters\Application = c:\railsapp\run.bat
Go into the services applet, and stop then start that service, and you should be in business!
From the SRVANY KB Summary:
bq. “The Windows NT Resource Kit provides two utilities that allow you to create a Windows NT user-defined service for Windows NT applications and some 16-bit applications (but not for batch files).”
OR you can make it a poor man’s service using scheduled tasks, to run it when you log on ;)
READ THESE links:
Zed shaw’s SCGI RAILS runner
Kevin Worthington’s port of lighttpd
This link provided the clue to getting both ssl & non-ssl working off the same server process on windows.
Lighty with and w/out SSl on the same process
But…
Running such a bat file as a service can be a real nightmare. If the process fails to start the service runs ‘succesfully’! There are no error messages and there is no way to determine why the Ruby process is not up.
On Windows XP I have such a bat that runs succesfully from the command prompt. When I run as a service, the service starts, but the process Ruby is just not there.
How to deploy, using lighttpd on windows and SCGI
Chris Hulbert – chris-dot-hulbert-at-gmail
(ssl added to this by Noah Stern nfstern-at-yahoo)
IMPORTANT NOTICE
These days, for best practice, you will want to deploy using Mongrel
However, Mongrel does not support SSL as of this writing (2007-03-30) whereas Lighty does. You could use Apache or run the pound load balancer in front of Mongrel (requires a compile), but I found these solutions more hassitudinal to get working than Lighty. If you need this functionality, see instructions under the header SSL on how to enable this.
Things you’ll need:
Lighttpd 1.4.13 (or above) for windows
Rails (gem i rails)
Getting it working
Ok, for all of this example, i’m assuming that ruby is installed into c:\ruby, and lighty is installed into c:\lighttpd, and your rails app is installed in c:\railsapp.
Edit your c:\lighttpd\etc\lighttpd.conf file like this (obviously don’t replace the file with this, i’ve left all the unchanged bits out, to save space here):
server.modules = (
"mod_rewrite",
"mod_redirect",
"mod_access",
"mod_accesslog",
"mod_status",
"mod_scgi")
server.document-root = "C:/RailsApp/public"
server.errorlog = "C:/RailsApp/log/lighttpd-errors.log"
accesslog.filename = "C:/RailsApp/log/lighttpd-access.log"
static-file.exclude-extensions = ( ".php", ".pl", ".fcgi", ".scgi" )
server.error-handler-404 = "/dispatch.scgi"
scgi.server = ( "dispatch.scgi" => ((
"host" => "127.0.0.1",
"port" => 9999,
"check-local" => "disable"
)) )
scgi.debug=0
status.status-url = "/server-status"
status.config-url = "/server-config"
END OF lighttpd.conf
Now, above you would have noticed that we didn’t have any url rewrite rules, and that the 404 not found is routed to the dispatch.scgi.
NOTE: there is NO dispatch.scgi file in your c:\railsapp\public folder. This is a virtual file.
Okay, next up, we need to set up the SCGI server that lighty will be talking to. Before you do this, make sure you have installed the gems for cmdparse and highline.
Go into your command prompt, and go into c:\railsapp, and run this:
scgi_ctrl config -S
This will generate your c:\railsapp\config\scgi.yaml file. Have a look at it if you want.
And now that SCGI is ready to go, i’ve set up a batch file that i run that kicks off lighty and my scgi runner:
@echo off
c:
cd C:\lighttpd\sbin
echo Stopping lighty...
process.exe -k lighttpd.exe > nul
echo Starting lighty...
lighttpd.exe -f ..\etc\lighttpd.conf
echo Stopping SCGI_service...
Process.exe -k ruby.exe > nul
cd C:\railsapp
echo Starting SCGI_service...
scgi_service
END OF c:\railsapp\run.bat
SSL
If you need this enabled because you are testing a secure login, payment system, etc., etc., and you want to set this up in a development environment, there are a few more steps involved. Fortunately, it’s not difficult.
First off, download & install the ssl_requirement plugin using this command in a windows command box: ruby script/plugin install ssl_requirement.
Next make the following modifications to the lighttpd.conf file as follows:
If you are typically running your application in development mode on port 3000 (as outlined by Curt Hibbs in his excellent tutorials), uncomment the server.port parameter and set it to 3000.
server.port = 3000
Also, I uncommented the server.bind parameter as follows:
server.bind = “127.0.0.1”
You may or may not need to do this (I did).
Next, you need to generate a certificate.
Lighttpd 1.4.13 comes with the openssl package compiled in and instructions, but basically you do this:
Open up a windows command box & go to c:\lighttpd\sbin (cd c:\lighttpd\sbin)
run this command:
openssl req -new -x509 -keyout server.pem -out server.pem -days 365 -nodes
Enter the required information at the prompts.
Add these lines to your lighttpd.conf file beneath the comment SSL engine
$SERVER“socket” == “127.0.0.1:443” {
ssl.engine = “enable”
ssl.pemfile = “C:/lighttpd/sbin/server.pem”
}
This tells Lighty what to do for requests coming in on port 443, which is basically to enable ssl & where to find the pemfile.
If you are running on port 3000 (or another port), you need to make a slight hack to the ssl_required.rb as of this writing to get redirects from https back to http working correctly (in my application, only certain pages require ssl and I want to redirect off it for pages that don’t need it).
This block:
def ensure_proper_protocol
end
Should be modified to something like this:
def ensure_proper_protocol
end
Observe the addition of the port number for non-production environments in the elsif clause.
Also, if for some good reason, you have a situation in your application where your secure page calls an action that’s not tied to an rhtml (or possibly rjs) file (mine did), you need to set ssl_allowed for that action. Otherwise you get a 404 and it’s not clear from the page and the logs what’s causing the problem.
That should more or less get you going. A couple of extra things you may find useful.
If you are doing file and/or image uploads, set this parameter in your lighttpd.conf file:
server.upload-dirs = ( “c:/lighttpd/tmp” )
I kept having my application blow up because the default upload for lighty is /var/tmp which doesn’t exist in windows.
You may also like to have a shutdown script for Lighty & SCGI. Killing Lighty from the task manager can sometimes leave processes running if you’re not careful to stop the related processes. I called mine StopLighty.bat which borrows from the bat file above and contains the following:
@echo off
c:
cd C:\lighttpd\sbin
echo Stopping lighty…
process.exe -k lighttpd.exe > nul
echo Stopping SCGI_service…
Process.exe -k ruby.exe > nul
cd C:\railsapp
Make sure your scgi.yaml file has this parameter:
:disable_signals: true
and if you are running in development mode, this:
:env: development
as opposed to :env: production
End of SSL
And finally, so that it’ll all start up as a service when the server is switched on, without me having to log on and run that batch file, you use SRVANY, which is the microsoft tool for running anything as a service.
You can find instructions for this elsewhere, but the important bit is to set this up in the registry:
HKLM\SYSTEM\CurrentControlSet\Services\RailsApp\Parameters\Application = c:\railsapp\run.bat
Go into the services applet, and stop then start that service, and you should be in business!
From the SRVANY KB Summary:
bq. “The Windows NT Resource Kit provides two utilities that allow you to create a Windows NT user-defined service for Windows NT applications and some 16-bit applications (but not for batch files).”
OR you can make it a poor man’s service using scheduled tasks, to run it when you log on ;)
READ THESE links:
Zed shaw’s SCGI RAILS runner
Kevin Worthington’s port of lighttpd
This link provided the clue to getting both ssl & non-ssl working off the same server process on windows.
Lighty with and w/out SSl on the same process
But…
Running such a bat file as a service can be a real nightmare. If the process fails to start the service runs ‘succesfully’! There are no error messages and there is no way to determine why the Ruby process is not up.
On Windows XP I have such a bat that runs succesfully from the command prompt. When I run as a service, the service starts, but the process Ruby is just not there.