Testing ssl_requirement with pound

ssl_requirement is a Rails gem by DHH to declaratively redirect requests to SSL.  It is useful, for example, to ensure all access to a checkout page is secure.  SSL encryption, however, is usually handled by a webserver such as Nginx or Apache, and these are not typically used in Rails test mode.  It appears most developers simply disable SSL redirects during testing, but this allows certain defects such as correct handling of flash messages to go undetected.  To test SSL redirects I’ve started using a lightweight, secure reverse proxy called pound. The pound configuration file can be kept to a bare minimum to forward requests from port 8443 to 3000 and encrypt the response:

ListenHTTPS
  Address 127.0.0.1
  Port    8443
  Cert    "pound.pem"
  AddHeader "X_FORWARDED_PROTO: https"
  Service
    BackEnd
      Address 127.0.0.1
      Port    3000
    End
  End
End

To run pound:

pound -vf ./pound.conf

Apache, Unicorn & SSL

Having used Apache with Mongrel, Thin and Passenger, I’ve now moved on to Unicorn.  Setting up Apache on Ubuntu to proxy to Unicorn requires the following installation commands:

apt-get install apache2 -y
apt-get install libapache2-mod-proxy-html libxml2-dev -y
a2enmod headers
a2enmod proxy
a2enmod proxy_http
a2enmod proxy_balancer
a2enmod rewrite
a2enmod ssl
/etc/init.d/apache2 restart

With these modules in place a virtual host can be configured something like this:

<VirtualHost *:80>
  ServerName     myhost.example.com
  DocumentRoot   /opt/example/app/public

  RewriteEngine On
  # Redirect all non-static requests to unicorn
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]

  <Proxy balancer://unicornservers>
    Allow from any
    BalancerMember http://127.0.0.1:8080
  </Proxy>
</VirtualHost>

<VirtualHost *:443>
  ServerName     myhost.example.com
  DocumentRoot   /opt/example/app/public

  RewriteEngine On
  # Redirect all non-static requests to unicorn
  RewriteCond %{DOCUMENT_ROOT}/%{REQUEST_FILENAME} !-f
  RewriteRule ^/(.*)$ balancer://unicornservers%{REQUEST_URI} [P,QSA,L]
  RequestHeader set X-Forwarded-Proto "https"

  <Proxy balancer://unicornservers>
    Allow from any
    BalancerMember http://127.0.0.1:8080
  </Proxy>

  SSLEngine     on
  SSLCertificateFile /etc/apache2/ssl/ssl.crt
  SSLCertificateKeyFile /etc/apache2/ssl/ssl.key
</VirtualHost>

mod_headers and the RequestHeader directive are useful if the Rails app is using ssl_requirement.

Rails development with multiple MySQL instances

Sometimes supporting multiple clients or projects can result in a need for more than one version of MySQL on the same workstation. This can be a pain, especially with the Ruby native mysql2 gem that can fail with a cryptic ‘failed to allocate memory’ when used with the wrong client libraries.

To address this I’ve started using Bitnami’s RubyStack.  Bitnami’s stacks provide a graphical installer that allows you to quickly specify a non-standard installation location and ports for your developer infrastructure so you can easily install the stack alongside the project being supported.

Instead of using RVM for development I now prepend the RubyStack to my path before working on the supported project:

RUBYSTACK=~/.../rubystack-3.2.1-0
PATH=$RUBYSTACK/mysql/bin:$PATH
PATH=$RUBYSTACK/ruby/bin:$PATH

Be aware the Bitnami stacks are 32-bit. The stacks include graphical and command line tools to start and stop components, see the Bitnami wiki components for more details. Bitnami AIMs are also available on EC2, various deployment options are discussed in the RubyStack README.

One year with Rails

One year since I picked up ‘Agile Web Development with Rails’ and coded my first Rails model/controller/view: seems so long ago now.

Things I’ve mastered in the past year:

  • Test driven development using unit and functional tests.
  • Master-detail forms using Ajax to add and delete rows, fetching product details in JSON for codes entered into a line item.
  • Prototype and jQuery, including jQuery UI datepickers.
  • Loading and parsing XML data files using Nokogiri.
  • Building complex reports using nested views in PostgreSQL, maintained using rails_sql_views.
  • Creating formatted, multi-tab Excel spreadsheets using Spreadsheet gem.
  • Creating pixel-perfect PDF reports using JasperReports loaded using Java-Ruby bridge.
  • Hosting using Apache with Passenger, Mongrel, Thin and Unicorn.
  • Monitoring using ScoutApp.
  • Upgrading a production app from Rails 2.3.4 to Rails 3.0.9.
  • Switching from ERB to HAML.

Using Apache with Mongrel or Thin and Rails 3

When using mod_proxy to load balance between members of a mongrel or thin cluster it’s important not to pass requests through for static content.  A basic virtual site can be configured like this:

<VirtualHost *:80>

    ServerName myapp.mydomain.com
    DocumentRoot /opt/myapp/public

    <Proxy balancer://thinservers>
        BalancerMember http://127.0.0.1:3000
        BalancerMember http://127.0.0.1:3001
        BalancerMember http://127.0.0.1:3002
    </Proxy>

    ProxyPreserveHost On
    ProxyPass /images !
    ProxyPass /stylesheets !
    ProxyPass /javascripts !
    ProxyPass / balancer://thinservers/
    ProxyPassReverse / balancer://thinservers/

    <Proxy *>
     Order deny,allow
     Allow from all
    </Proxy>

    ErrorLog /var/log/apache2/error.log
    LogLevel warn
    CustomLog /var/log/apache2/access.log combined

</VirtualHost>

Thin with Apache

Having run into compatibility issues between Passenger and RJB and between Mongrel and Rails 2.3.8 I’ve been looking at Thin.

Slicehost has a couple of good articles on setting up a Thin cluster with Apache on Ubuntu.

In summary:

gem install thin
thin install
/usr/sbin/update-rc.d -f thin defaults
thin –h # help
thin -C /etc/thin/${appenv}.yml -c ${apphome} -s 3 -e production config
su – ${appenv}bat ; thin -C /etc/thin/${appenv}.yml start

Rails Datepickers

There are multiple ways to add date-pickers to a Rails application. Searching for a date picker online I came across one Prototype based gem called calendar_date_select that was featured by Ruby Inside, and another one called Calendar-DatePicker-for-Rails.  On closer inspection, however, calendar_date_select was last updated in 2008 and is looking for a new maintainer: the demo still uses Rails 2.2.2: it does not work with some later versions.

Apart from using a date-picker specifically packaged for Rails it is not that difficult to use a free-standing Javascript solution: I found a nice looking solution called unobtrusive-date-picker but it appears to have limited support. There are also Javascript widget libraries like AUI and jQuery UI.  Finally I came across a Railscast that mentions calendar_date_select but goes on to recommends jQuery UI.  jQuery can be integrated with Rails 2.x using jRails or Rails 3 with jquery-rails and/or jquery-ujs or you can simply forgo the integration and just use jQuery directly. In my case I linked to the libraries hosted by Google like this:

 <%= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js", "http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.7/jquery-ui.min.js" %>
 <%= stylesheet_link_tag "http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/humanity/jquery-ui.css" %>

The remaining details of using a jQuery UI datepicker with Rails are covered in the Railscast.

Installing Phusion Passenger on Ubuntu 10.04 LTS

Before installing Phusion Passenger you will need a working installation of Rails:

apt-get install ruby rubygems # distro packages rubygems 1.3.7
gem install rubygems-update
PATH=$PATH:/var/lib/gems/1.8/bin
update_rubygems
gem install rails -v=2.3.4 # or whatever

The Phusion installation script builds an Apache loadable module by linking various libraries. Make sure these libraries are installed before running the script.

apt-get install build-essential ruby1.8-dev libopenssl-ruby
apt-get install apache2 apache2-prefork-dev libapr1-dev libaprutil1-dev
apt-get install libcurl4-openssl-dev

gem install passenger
passenger-install-apache2-module # compilation dependencies satisfied above

The Passenger installation script displays a message to add some lines to your Apache configuration script. One way to do this with Apache2 on Ubuntu is:

cat > /etc/apache2/mods-available/passenger.load <
   LoadModule passenger_module /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15/ext/apache2/mod_passenger.so
   PassengerRoot /usr/lib/ruby/gems/1.8/gems/passenger-2.2.15
   PassengerRuby /usr/bin/ruby1.8
EOF
a2enmod passenger
/etc/init.d/apache2 restart

Posts navigation

1 2 3
Scroll to top