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
- 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
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:
Which is…cumbersome. I prefer using an alias:
alias attachdebugger='rdbg -A'