Getting your Rails dev environment ready for passkeys
I spent the whole day digging through WebKit bug reports & wrangling with puma-dev
, but finally have a working solution.
The gist is: while Chrome, Firefox, and non-macOS implementations of WebKit support *.localhost
subdomains (and register them as a Secure Context, see: This MDN article ), WebKit on macOS does not, because of underlying macOS networking APIs. There’s a whole set of bugs about it:
So your Rails development environment needs to run with HTTPS, which requires a certificate, which is a whole mess.
puma-dev
to the Rescue
puma-dev
solves the HTTPS issue elegantly, but I’ve never liked how it runs as a daemon process by default. macOS does not have good daemon support; and for execution environments as volatile as development, daemons aren’t the right answer.
Update: Arrrgf; turns out that puma-dev
only listens to 127.0.0.1
when run in the foreground, so it has to run as a daemon if you need cross-device testing (such as through VMs or on mobile devices).
However, I really don’t want to lose the ability to quickly kill & reboot my development environment. Again, the problem of macOS not having good daemon support and development being too volatile of an execution environment for daemons to be practical. So I ended up writing a script that:
- Force stops the
puma-dev
daemon - Prints out some text to help with attaching the debugger
- Starts tailing puma’s daemon logs.
#!/bin/bash
set -e
echo "make sure to attach a debugger with (or alias): rdbg -A"
echo "force-stopping puma-dev"
puma-dev -stop
echo "watching puma with: tail -f ~/Library/Logs/puma-dev.log"
echo "============"
tail -f ~/Library/Logs/puma-dev.log
The ideal solution would be for puma-dev
to add a flag to specify what hosts to listen on. There’s a PR for some of this, but a customizable command-line flag (like for ports) would be a great solution; since it allows for flexibility: https://github.com/puma/puma-dev/issues/306
In case it’s useful for anyone, I’ve kept my original version at the end of this post. It’s a good example of how you can hook in Ruby’s built-in debugger as part of a larger buildchain.
puma-dev
has the option to run in a foreground mode. But since puma-dev
doesn’t support TTY for its child processes, you lose the ability to use the built-in Ruby debugger.
Thankfully, Ruby’s built-in debugger has a special wrapper command that we can use to automatically get an optional debugger for any process spawned by puma-dev
.
The commands
The command to run puma-dev
in the foreground with the debugger hooks is:
rdbg --nonstop -O -c -- bundle exec puma-dev
To attach the debugger process, run:
rdbg -A
Which is…cumbersome. I prefer using an alias:
alias attachdebugger='rdbg -A'