Using HTTPS Locally: Pow, SSL, Rails, and Apache

Using HTTPS local development or testing environments is a hassle. A common practice is to disable SSL in development, but I’ve had too many cases of minor bugs creeping in when routing works differently between environments. I also don’t like manually having to let my browsers know that a self-signed certificate is valid.

Here’s the configuration that I use to easily add https support on my development machine to any application served—or proxied—through port 80.

Pow

I use Pow as my development rails server. However, because I often work with other languages as well, I run Apache (you could just as easily use nginx) and reverse proxy Rails application requests to Pow.

To do this, you’ll need Pow to bind to a port that is not port 80. Here’s how to configure Pow to use port 88.

Apache

I use nginx in production environments, but I’ve been using Apache on my local development machines for years and just haven’t gotten around to changing my dotfiles to use nginx. You could just as easily use nginx here.

In any case, here’s what I was looking to achieve in my apache config:

  • Throw error logs in ~/Sites/logs
  • Support vhosts + xip.io domains
  • Access WordPress sites using site-name.wp.dev
  • Access Rails applications using site-name.dev. These requests need to reverse proxy to pow on port 88.
  • Support proxying *.test domains to a customized port. Having a *.test domain allows you to run SSL-enabled integration tests for a multi-domain Rails application against the rspec-run rails server. Checkout my series on rails testing for more details on why this is important.

I was able to get all of this working with a single file thrown in /etc/apache2/other.

Rails: Tunnelss to the Rescue

Tunnelss is a little gem that brings it all together. It looks at your pow config, generates self-signed certificates for those domains, and adds that certificate to your keychain so your browsers accept the self-signed certificate. Brilliant.

The only downside here is you must keep tunnelss running in the background. Right now, the project doesn’t have a launchd plist available. So, for now, you have to start the application manually on each system restart.