Serving Ember and Rails locally with SSL/TLS

Cory Forsyth
4 min readJan 18, 2017

--

(After you’re done reading this article, be sure to check out our article on setting up TLS for free with LetsEncrypt and Heroku.)

Update Jan 24 2017: Changed the recommended common name to localhost.ssl — using localhost alone can cause the browser to cache the https which causes some problems.

If you are writing an Ember app that requires that your connection be secured, there is a bit of setup you will need to do in order to serve connections via https locally. This was the case recently when our team at 201 Created, built a proof-of-concept progressive web app that accepted Apple Pay. This post outlines the approach we took to set up both our ember app and rails apps to serve via TLS*.

Luckily, ember-cli already has an “ssl” configuration option, so all you need to do is turn that option on and provide your own certificate and key. Because your app is running locally, a self-signed certificate will suffice.

Step 1: Generate a self-signed cert

Heroku has a nice guide to creating a self-signed certificate via the command line, or you can copy-paste the lines (one at a time) below:

openssl genrsa -des3 -passout pass:x -out server.pass.key 2048
openssl rsa -passin pass:x -in server.pass.key -out server.key
rm server.pass.key
openssl req -new -key server.key -out server.csr

The last command will prompt you with some questions. Your answers to these questions don’t matter very much except for the Common Name, which should be localhost.ssl.

Prompts for certificate properties

At this point you have generated key and certificate signing request files. The last step is to use these two files to sign your certificate yourself (this is where the “self-signed” part of “self-signed cert” comes in):

openssl x509 -req -sha256 -days 365 -in server.csr -signkey server.key -out server.crt

You can delete the certificate signing request file (server.csr) now, but keep the server.key and your new cert server.crt handy.

Step 1b: Update /etc/hosts

We used localhost.ssl as the common name, so you’ll want to edit your /etc/hosts file so that it points at your local host. Add this line to the hosts file:

127.0.0.1                  localhost.ssl

etc/hosts is a protected file so you’ll need to use sudo to edit it.

Step 2: Use your certificate with ember-cli

By default, ember-cli will look for your certificate and key in a directory named ssl in the root of your project. Go ahead and create the ssl directory and move your server.key and server.crt files into it. Next, edit your .ember-cli file (located in the root of your project) to have the setting"ssl": true.

Step 3: Trust your certificate

Start your ember app by running ember serve and open https://localhost.ssl:4200 in Safari. You’ll see this warning message:

Check the box to trust your certificate.

Check that Always trust “localhost.ssl” box and hit continue. At this point your ember app is running via TLS!

Note: You do need to use Safari to get that “trust” checkbox. Chrome and Firefox don’t have a mechanism allow you to trust the certificate. This is because Safari will update your OS X Keychain.

If for you don’t want to do this through Safari, or you have trouble doing so, you can instead add it directly to your keychain by opening up the Keychain Access, dragging in the server.crt, and double-clicking it to choose to “Always Trust” it. This has the same effect.

Step 4 (optional): Run rails over TLS

If you have a rails app that you run locally to provide a backend for your ember app, you’ll want to run it over TLS as well.

You can use the same cert and key files that you generated in the previous steps. Simply copy both server.key and server.crt to a directory in your rails app (we use a ssl directory in the project root for symmetry with the ember app, but you can put it wherever you want).

We use puma to run our rails apps locally, and puma also allows you to configure TLS usage. First, ensure you have added puma to your Gemfile, and then, to direct puma to serve TLS, use the bind flag, -b :

puma -b 'ssl://127.0.0.1:3000?key=ssl/server.key&cert=ssl/cert.crt'

Update the key and cert parameters to match your file paths if you didn’t put the files in the ssl directory.

If you use foreman to run your app (which you should), you can store the puma configuration parameters in a local Procfile. Add a Procfile.dev file in your project root with the puma configuration:

web: puma -b 'ssl://127.0.0.1:3000?key=ssl/server.key&cert=ssl/cert.crt'

Now you can start up your rails server with foreman:

bundle exec foreman start -f Procfile.dev

Now visit your rails app at https://localhost:3000. Because you’re reusing the same self-signed cert that you’ve already trusted, you should be all set! Bask in the warmth of the green lock icon.

  • I’m pedantically using TLS because it is the technically correct term, even though SSL is still quite common. (TLS is the IETF name, SSL is the old name invented by Netscape.) For the purposes of this article the terms are more similar than they are different, so feel free to s/TLS/SSL/g in your mind if that’s your preference.

Want to hear more about 201 Created and what we do? Follow 201 Created on twitter or drop us a line: hello@201-created.com.

--

--

Cory Forsyth

Lifelong learner and technologist, based in NYC. Engineer @ Addepar, formerly co-ran Ember consultancy 201 Created.