How can I expose a REPL in production?

I usually deploy my apps as uberjars. I’m at the point of realizing the promise of a production REPL. Instinctively I would think to just start a dev environment, the same way I do with cider. But this unpacked way must be wrong. How do I set up a remote REPL l that will allow me, for instance, to use fig wheel in production?

In your main function (used by the uberjar) I would start an embedded nrepl server as the first step. This is how we do it:

(ns app.nrepl.server
  (:require [nrepl.server :as nrepl]))

(defn start
  (let [config [:bind ""
                :port 4000]
        server (apply nrepl/start-server
    (println "nrepl started"
             (pr-str config))
    (.addShutdownHook (Runtime/getRuntime)
                        (fn []
                          (println "stopping nrepl")
                          (nrepl/stop-server server))))))

The production instance should be behind a firewall, since is binding the port 4000 to all network interfaces. We use this, since we do the port forwarding with kubectl port-forward. However, if you use ssh it might be doable to bind to (which is the default).

The ssh call would look something like this:

ssh -L 4000:localhost:4000 username@remote_server_address

Using Figwheel in production is possible, but problematic, since you would ship the unoptimized and very large ClojureScript output to your customers. Furthermore you also expose your ClojureScript source code to the public.