Sometimes you need to test a feature that requires not just SSL (https) but also to run under a certain domain. For example, testing an OAuth application will mean running your development environment at the right callback URL, especially when the OAuth provider doesn't support custom callbacks. Another example is testing FIDO or WebAuthn support: not only do these features need to run via SSL, but also under the right domain, which is not where your app will typically run before it's rolled out to production.
This is a quick guide to a workaround to get your the development branch of your Rails app running via SSL and under your production URL.
The Challenge
This is somewhat challenging because it requires the following:
- A way to redirect your production domain to
127.0.0.1
orlocalhost
- A way to run
rails s
on port 443 and bound to your domain name - A way to generate and serve fake SSL certificates that your browser trusts
The Solution
Assumptions
In this example, I'm going to make the following assumptions:
- Your development web server runs on port
3000
- Your domain is
app.acme.com
- You are using a Mac (although most of this applies to other OSs without change).
Get Started
First, install the following tools:
Do these steps once:
brew install mkcert
brew install nss # if you use Firefox
brew install caddy
Now let's generate the certificates. In your Rails app folder, run the following:
mkcert --install
mkcert app.acme.com
The second command adds 2 files to your folder:
app.acme.com-key.pem
andapp.acme.com.pem
. Make sure to add those your.gitignore
file so you don't commit them into your git repo by mistake!
Create a file in your Rails folder called Caddyfile
with the following content:
app.acme.com
reverse_proxy localhost:3000
tls app.acme.com.pem app.acme.com-key.pem
Do these every time:
Now, whenever you want to run the local server as app.acme.com
do the following:
- Add
127.0.0.1 app.acme.com
to/etc/hosts
and save (you need sudo rights) - Run your Rails server as usual:
bundle exec rails s
or whatever command you use. - On a different terminal, start Caddy:
caddy
You're all set! Visit https://app.acme.com
in your browser and you'll be served from your local development machine.
Cleanup
Remember to remove the 127.0.0.1 app.acme.com
line from /etc/hosts
file when you're done.
What just happened?
What we did is simple:
- We used mkcert to generate fake certificates for your domain as well as a fake CA (Certificate Authority). Mkcert adds this fake CA to your OS so the browsers don't complain about it. You can remove this with
mkcert --uninstall
- We use Caddy to run a reverse proxy that uses this certificate and redirect the traffic to your local rails server. This is to allow your app run on port 443 like a normal HTTPS endpoint.
Pro tip
If you need to do this often, you might want to use a tool like iHosts or SwitchHosts! to create different hosts profiles and switch between them easily.
Disclaimer: I have not used these 2 tools and prefer editing
/etc/hosts
file manually.