Configuring Pow with NGINX and SSL on OSX

This is a step by step guide on how to setup your local development environment to serve a Rails (or any Rack) app with Pow and NGINX over HTTPS.

To begin I’m going to assume you’re using OSX (probably Mountain Lion), HomeBrew and rbenv. For other setups ymmv.

What is Pow?

Pow (a 37signals project) runs as your user on an unprivileged port, and includes both an HTTP and a DNS server. The installation process sets up a firewall rule to forward incoming requests on port 80 to Pow. It also sets up a system hook so that all DNS queries for a special top-level domain (.dev) resolve to your local machine.

Pow - artwork by Jamie Dihiansan

For more information on Pow, read the intro or browse the manual.

Why use Pow?

  • Easily host multiple Rack apps on your local machine under different domains e.g
  • Configure local apps to run under SSL (explained below)
  • Use the domain to visit your app from other devices on your local network
  • Serve requests with multiple Pow workers
  • Easy to configure, customise and works with multiple Rubies (via rbenv or RVM) and Bundler

Installing Pow

Install Pow with this command;

curl | sh

Next create a symlink in ~/.pow to your app’s base directory like so;

ln -s /full/path/to/your-app ~/.pow/your-app

Note: If you are running zsh with rbenv you may need to follow these instructions and add a PATH export to your ~/.powconfig file like so;

export PATH=`brew --prefix rbenv`/shims:`brew --prefix rbenv`/bin:$PATH
  # then restart pow again with touch ~/.pow/restart.txt

This should be enough for you to see your app working at The next steps assume you have this working.

Installing and configuring NGINX

Install NGINX via brew;

brew install nginx

By default brew will install and configure NGINX to listen on port 8080. We need to run it on port 443 (decrypting SSL and proxy-ing all requests through to our Pow server).

Using this config file we can set up NGINX with some good defaults, and tell it to look for sites in /usr/local/etc/nginx/sites-enabled.

mkdir -p /usr/local/etc/nginx/sites-enabled
  mkdir -p /usr/local/etc/nginx/sites-available

  curl -0 > /usr/local/etc/nginx/nginx.conf

Next we create our site configuration in /usr/local/etc/nginx/sites-available

curl -0 > /usr/local/etc/nginx/sites-available/

Edit this file, setting the root (public) directory and replacing throughout. Finally symlink it into sites-enabled;

ln -s /usr/local/etc/nginx/sites-available/ /usr/local/etc/nginx/sites-enabled/

Generating an SSL Cert

You might have noticed that the config file you just edited referenced an SSL cert that we have not yet created.

In a tmp directory, let’s use this handy gist to generate it and move the cert files into place;

curl > /tmp/nginx_gen_cert.rb
  ruby /tmp/nginx_gen_cert.rb
  rm /tmp/nginx_gen_cert.rb

You should now have SSL cert files for your app properly configured and contained in /usr/local/etc/nginx/ssl.

Trying it out

Thats it! To start NGINX (since we are listing on port 443) you need to run it with sudo;

sudo nginx

Visit now to see your app served via HTTPS.

Controlling things

The web app can be restarted by running touch tmp/restart.txt in the base directory. And you can control NGINX from the command line with flags like this;

sudo nginx -s start
  sudo nginx -s stop
  sudo nginx -s reload

Debugging with pry-remote

Since your app is now running in Pow’s own worker processes, to operate a live debugger you will need to use something like pry-remote.

First add the pry and pry-remote gems to your Gemfile (and bundle install). Then to introduce a breakpoint use this in your code;


Fire off a request and when it stalls, run this command from your app’s base directory;

bundle exec pry-remote

A connection to the running worker process is established and you should be presented with a regular pry prompt. You can read more about pry-remote and pry here.

Further steps

Your browser may complain about not trusting your new SSL cert - we can fix that!

Restart or open Safari to visit and click ‘Show Certificate’ from the warning dialog. Choose the ‘Trust’ drop-down and select ‘Always Trust’. This adds your newly generated cert to the OSX keychain.

Setting up more sites is easy, just add them with a similar NGINX site config, generate an SSL cert (using the helper script again) and symlink things into place.

You can play with Pow’s configuration (e.g timeouts, workers) by defining ENV variables in ~/.powconfig, for example;

export POW_DOMAINS=dev,test
  export POW_DST_PORT=80
  export POW_TIMEOUT=300
  export POW_WORKERS=3

Any change to ~/.powconfig needs a Pow restart;

touch ~/.pow/restart.txt

I hope this guide has been useful. Comments or questions are always welcome.

photo of Matt

comments powered by Disqus