puma-dev
puma-dev copied to clipboard
Allow multiple copies of the same app to run independently with different configurations
Hey there! Bit of an odd use case here, but I think this could be useful functionality to add, so consider this a feature request.
The problem
I've got a Rails app that runs in multiple different "modes", depending on the value of an APP_MODE
ENV var at boot time. In my existing setup, I run multiple instances of the app on different ports, e.g.
APP_MODE=api PORT=3000 bundle exec puma -C config/puma.rb
APP_MODE=admin_dashboard PORT=3001 bundle exec puma -C config/puma.rb
Puma is perfectly happy to run these multiple app modes side-by-side, and I can easily switch between them by going to localhost:3000
or localhost:3001
.
My unsuccessful attempt at a solution
I wanted to see if I could recreate this setup with puma-dev
. First I called puma-dev link
multiple times, giving this app multiple aliases:
puma-dev link -n api
puma-dev link -n admin_dashboard
Then I built a custom .pumaenv
file in an attempt to set distinct ENV vars for the two different aliases:
#!/usr/bin/env bash
if [[ "$PWD" =~ admin_dashboard ]]; then
export APP_MODE=admin_dashboard
else
export APP_MODE=api
fi
Unfortunately, rather than booting two separate instances of the app, both api.test
and admin_dashboard.test
still end up pointing to the same single Puma instance. I'm not particularly familiar with Go, but I suspect that the problem may be because both instances want to use the same .sock
file on disk, even though their aliases are different. (I can totally see how that makes sense for other use cases, where you might WANT admin_dashboard.test
and api.test
to both run off the same single instance...but there doesn't seem any way to force the opposite use case, where you intentionally want them to differ.)
Workarounds
The best workaround I have right now is to have multiple separate copies of my Rails app/repo on disk, one for each app mode. This sorta works, but it's inconvenient because the multiple copies can fall out of sync with each other (e.g. if I commit an update to the "admin dashboard" copy, I need to remember to pull down that same change on the "API" copy).
It'd be awesome if puma-dev
allowed multiple symlinks to the same directory to have distinct configurations somehow! I imagine it would be especially useful for tasks like testing Ruby upgrades – for example, allowing a developer to run the same codebase on Ruby 2.7 (ruby_27.test
) and Ruby 3.0 (ruby_30.test
) and compare the behaviors.
I think subdomains solve your problem. You can do
puma-dev link -n api.myapp
puma-dev link -n admin_dashboard.myapp
And then somewhere in an initializer use the subdomain to set the ENV (or equivalent best practice)
I'm afraid that didn't work in my testing 😞 My initial experiments above suggested that the .sock
file on disk might be the culprit:
- When
api.myapp.test
boots up (assuming it's the first to boot), it creates a.sock
file - When
admin_dashboard.myapp.test
boots up a moment later, I believe it finds that.sock
file and thus connects to the same already-running Puma instance, rather than spawning a new Puma instance with different ENV vars - The result is that you're unable to run 2 Puma instances of the same repo side-by-side with different ENV vars