Just a couple days ago, I encountered an issue with having to serve a rails app over SSL from a local development environment. Unfortunately the localhost was a windows machine, so using passenger wasn’t much of a choice. I found several good articles talking about how to do this, however they didn’t work for me. The one that got me the closeset was from a post at zunisoft.com (thanks Keith!).
I believe the issue I had was that the articles I was referencing were nearly a year old, and probably used an older version of rails. I took a look at the server script that others proposed, vs the latest server.rb file (and hence rails’ server command.rb file) that is used in 2.3.x rails applications; and I believe the difference comes down to the changes in rails’ underpinnings to being rack based and how the webrick server & rails envirionment is setup and configured.
I first cracked open the ‘script/console.rb’ file from my app:
#!/usr/bin/env ruby
require File.dirname(__FILE__) + '/../config/boot'
require 'commands/server'
Turns out that, it isn’t too helpful, as the bulk of the logic exists somewhere else. Turns out if you freeze your rails gems, it’s in: ‘vendor/rails/railties/lib/commands/server.rb’. If you don’t freeze your gems, it’ll be in: $GEMS_HOME/gems/rails-2.3.x/lib/commands. This file’s a bit large to post here, but for discussion’s sake here’s a link to it on github.
After reviewing the file, I found I needed to add values into the options hash, but there didn’t seem an easy way to make that happen. Since I was short on time, I took the path of least resistance 🙂 – I copied commands/server.rb and created a file in scirpts/ssl_server.rb. For reference, here is a copy of the ssl_server script file I am running.
There are three notable changes I made:
- Modified port to be 443 (to simplify testing)
- Added options values for SSLEnable, SSLVerifyClient, SSLCertName
- Removed block that determines server and forces the use of webrick
One last thing to note, in our scenario we needed to have mixed traffic over both 80 and 443. In order to accomplish this, I borrowed a suggestion from the 81electric blog, and ran both the ssl_server and standard server scripts at the same time – maybe not elegant, but simple!