How do you configure WEBrick to use SSL in Rails?

While the scripts directory in Rails 4 is gone, the bin directory remains. You can get WEBrick working with an SSL certificate by editing the bin/rails script. Tested on Rails 4 and Ruby 2.1.1, installed with rbenv.

Much of this is from this blog post and this Stack Overflow question.

#!/usr/bin/env ruby

require 'rails/commands/server'
require 'rack'
require 'webrick'
require 'webrick/https'

if ENV['SSL'] == "true"
  module Rails
      class Server < ::Rack::Server
          def default_options
              super.merge({
                  :Port => 3001,
                  :environment => (ENV['RAILS_ENV'] || "development").dup,
                  :daemonize => false,
                  :debugger => false,
                  :pid => File.expand_path("tmp/pids/server.pid"),
                  :config => File.expand_path("config.ru"),
                  :SSLEnable => true,
                  :SSLVerifyClient => OpenSSL::SSL::VERIFY_NONE,
                  :SSLPrivateKey => OpenSSL::PKey::RSA.new(
                                   File.open("certs/server.key").read),
                  :SSLCertificate => OpenSSL::X509::Certificate.new(
                                   File.open("certs/server.crt").read),
                  :SSLCertName => [["CN", WEBrick::Utils::getservername]],
              })
          end
      end
  end
end

APP_PATH = File.expand_path('../../config/application',  __FILE__)
require_relative '../config/boot'
require 'rails/commands'

Starting the rails server from the app directory works to start an SSL enabled server now when the SSL environment variable is set to true, and the default rails settings are retained when the environment variable is omitted.

$ SSL=true rails s
=> Booting WEBrick
=> Rails 4.1.0 application starting in development on https://0.0.0.0:3001
=> Run `rails server -h` for more startup options
=> Notice: server is listening on all interfaces (0.0.0.0). Consider using 127.0.0.1 (--binding option)
=> Ctrl-C to shutdown server
[2014-04-24 22:59:10] INFO  WEBrick 1.3.1
[2014-04-24 22:59:10] INFO  ruby 2.1.1 (2014-02-24) [x86_64-darwin13.0]
[2014-04-24 22:59:10] INFO  
Certificate:
    Data:
...

If you don't want to use a pre generated certificate, you can use WEBrick's Utils::create_self_signed_cert, as outlined in this answer:

Configure WEBrick to use automatically generated self-signed SSL/HTTPS certificate


An Alternative to SSL/HTTPS on WEBrick: SSL/HTTPS on Thin

As an alternative to trying to set up WEBrick to use HTTPS/SSL for your Rails app, you can try switching to using the Thin server instead, because it comes with convenient options for setting up HTTPS/SSL out-of-the-box.

Installing Thin

First, add Thin as a gem to your Gemfile:

gem 'thin'

Then run bundle install from the command line.

Using Thin HTTPS/SSL for Development Environments

If you just want to test your Rails app using HTTPS/SSL in your local development environment, then you simply run

thin start --ssl

I have to emphasize that this is not suitable for production environments, because you need to use a valid SSL certificate from a Certificate Authority in order for SSL/HTTPS connections to be verifiable and secure.

Additional Options

There are also other options that you can pass to Thin. You can get a full list of them by running thin --help. For example, I like to specify my own ip-address and port, as well as daemonizing Thin into a background process:

thin start --ssl \
  --address <ip-address> \
  --port <port> \
  --daemonize

Using Thin HTTPS/SSL with an SSL Certificate

If you want to tell Thin to use an SSL certificate (for example, one that you've obtained from a valid Certificate Authority), then you can use these options:

thin start --ssl \
  --ssl-cert-file <path-to-public-certificate> \
  --ssl-key-file <path-to-private-key>