Clojure - как подключиться к запущенному процессу REPL удаленно

Как я могу подключиться к сеансу REPL, запущенному на удаленном сервере, к которому я могу получить доступ, например, через SSH?

6 ответов

Решение

Это может быть очевидно для сетевых специалистов, но мне потребовалось некоторое время, чтобы выяснить это, документируя это здесь.

На удаленном сервере, при запуске вашего приложения REPL, а не просто lein repl принудительная привязка к порту:

lein repl :start :port 40000

На вашей машине подключитесь к удаленному серверу обычным способом (например, через ssh). Затем подключитесь к вашему приложению следующим образом:

lein repl :connect localhost:40000

Это оно!

Я просто хочу суммировать два ответа выше. Это работает на моей машине:

На удаленной машине

lein repl :start :port 40000

На локальной машине

# SSH tunnel on one shell
ssh -NL 40000:localhost:40000 username@host

# Connect to the remote repl on another shell
lein repl :connect localhost:40000

Ну, это просто. Вкратце, необходимо сделать несколько шагов:

  1. nrepl пакет должен быть частью производственной сборки, а не просто зависимостью от разработчика;
  2. Когда ваше приложение запускается, оно также порождает сеанс repl в отдельном потоке на определенном порту;
  3. ваш сервер либо предоставляет этот порт, либо вы туннелируете его через SSH.

Теперь подробности:

1) Добавьте эти deps в основной :dependencies вектор:

:dependencies [[org.clojure/clojure "1.9.0"]
                 ;; for remote debugging
                 [cider/cider-nrepl "0.17.0"]
                 [org.clojure/tools.nrepl "0.2.13"]

Тебе нужно cider-nrepl если вы работаете с Emacs/Cider. В противном случае вы можете пропустить это.

2) Добавьте отдельное пространство имен для сервера nrepl

(ns project.nrepl
  (:require [clojure.tools.nrepl.server
             :refer (start-server stop-server)]))


(defn nrepl-handler []
  (require 'cider.nrepl)
  (ns-resolve 'cider.nrepl 'cider-nrepl-handler))


(defonce __server (atom nil))

(def set-server! (partial reset! __server))


(def port 7888)

(defn start
  []
  (when-not @__server
    (set-server!
     (start-server :port port :handler (nrepl-handler)))))


(defn stop
  []
  (when-let [server @__server]
    (stop-server server)
    (set-server! nil)))


(defn init
  []
  (start))

В вашем основном модуле просто позвоните (project.nrepl/init), Теперь ваше приложение позволяет подключаться к нему через nrepl.

3) На удаленном сервере вы можете открыть порт TCP 7888 для внешнего мира, который небезопасен. По крайней мере, порт должен быть ограничен определенными IP-адресами, например, вашим офисом. Лучшим вариантом было бы переслать его через SSH следующим образом:

ssh -L 7888:<remote-host>:7888 <user>@<remote-host>

Теперь откройте Emacs, позвоните M-x cider-connect RET localhost 7888 и все готово: вы подключены к удаленному приложению.

Кстати, вы можете легко подключиться из одного приложения REPL/ Clojure к другому REPL (например, для сравнения результатов eval между dev и UAT), как это

=> (require '[clojure.tools.nrepl :as repl])
nil
=> (with-open [conn (repl/connect :port 59258)]
     (-> (repl/client conn 1000)    ; message receive timeout required
       (repl/message {:op "eval" :code "(+ 2 3)"})
       repl/response-values))
[5]

подробнее здесь https://nrepl.xyz/nrepl/usage/clients.html

Безопасный способ подключения к удаленному clojure repl

  1. запустить repl на локальном хосте на удаленной машине
      $ clj "-J-Dclojure.server.repl={:port 5555 :accept clojure.core.server/repl}"
  1. создать туннель ssh на локальной машине
      $ ssh -L :5555:localhost:5555 remoteuser@remotehost -p 22 -N -v
  1. запустите repl на локальной машине и подключитесь к удаленному repl через ssh:
      $ clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}'
Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.pom from clojars <br>
Downloading: vlaaad/remote-repl/1.1/remote-repl-1.1.jar from clojars <br>Clojure 1.10.1 <br>
(require '[vlaaad.remote-repl :as rr])<br>
user=> (rr/repl :port 5555)
  1. или запустите реплику на локальной машине и сразу же зайдите на удаленную реплику
      clj -Sdeps '{:deps {vlaaad/remote-repl {:mvn/version "1.1"}}}' -m vlaaad.remote-repl :port 5555

Возможно ssh tunnel (если repl запущен на удаленном хосте как localhost:6666)

на локальной машине ssh -L:6666:localhost:6666 remoteuser@remotehost -N -v

затем просто подключитесь к localhost: 6666

Другие вопросы по тегам