I’m currently running a socket REPL on a low traffic, single instance, live app. The app is under fairly heavy evolution, but remains usable and live at all times. The app runs on a linux virtual server with a tight firewall, is proxied behind Nginx on port 443, and the REPL port 5555 is only available via a SSH tunnel, which is plenty of security for this particular app.
I used to run it via a CI-built and -deployed uberjar in a Docker container, but due to the fairly fast development and the desire for instant
updates, now I actually just run it using a systemd script that runs clojure -m my.service.main
in the code directory. This means I can (en/dis)able the socket repl easily from the CLI args, can git pull
and then immediately require
via the REPL, and I can connect my IDE to the repl and send code live straight from my IDE.
One of the things I do the most often is to run queries and transactions on the production Datomic DB to match changes happening in the dev DB. All of the changes made are already defined in the dev code branch, so it’s mainly a matter of having a more “realtime” workflow with pushing changes live. All of this makes for a much more enjoyable “progressive” situation. It works fine for a small team of two devs, but I can imagine it being inappropriate for a large team especially with a separate dev ops team and load balanced multi-node high traffic system. However, even there it can be indispensable to have a REPL access somewhere for debugging, troubleshooting, or running investigative queries.