连接到 运行 heroku phoenix 应用程序

Hooking up into running heroku phoenix application

前一天晚上我在家里的两台机器上修改 Elixir 运行 代码,但当我醒来时,我问自己我真的可以使用 heroku run 命令做同样的事情吗?

我觉得理论上只要设置得当应该是完全可以的。显然 heroku run iex --sname name 执行并允许我访问 shell(没有令人恼火的退格功能)但我还没有访问我的应用程序。

每次我执行命令时,它都会给我不同的机器。我想这就是 Heroku 实现沙箱的方式。我也试图找到一种方法来确定我的应用程序机器的地址,但还没有找到任何运气。

我真的可以连接 dyno 运行 代码以像在本地 iex -S mix phoenix.server 那样计算表达式吗?

当您执行 heroku run 时,它将启动一个新的 one-off dyno,这是一个临时实例,当您完成 heroku run 会话时将取消配置。这个 dyno 不是 web dyno,不能通过 Heroku 的路由层接收入站 HTTP 请求。

来自文档:

One-off dynos can never receive HTTP traffic, since the routers only route traffic to dynos named web.N.

https://devcenter.heroku.com/articles/one-off-dynos#formation-dynos-vs-one-off-dynos

如果您希望您的 phoenix 应用程序接收 HTTP 请求,您必须在网络测功机上将其设置为 运行。

很遗憾,这是不可能的。 要互连 Erlang VM 节点,您需要打开 EPMD 端口 (4369)。 Heroku 不允许打开自定义端口,所以这是不可能的。
如果您想在 Phoenix 服务器和 Elixir 节点之间建立连接,您必须:

同一台机器上的两个节点:

  1. 使用 iex --name phoenix@127.0.0.1 -S mix phoenix.server
  2. 启动 Phoenix
  3. 开始iex --name other_node@127.0.0.1
  4. 使用来自 other_node 的 Node.ping 建立连接:
    iex(other_node@127.0.0.1)1> Node.ping(:'phoenix@127.0.0.1')
    (应该 return :pong 而不是 :pang

不同机器上的两个节点

  1. 使用一些外部地址启动 Phoenix
    iex --name phoenix@195.20.2.2 --cookie someword -S mix phoenix.server
  2. 启动第二个节点
    iex --name other_node@195.20.2.10 --cookie someword
  3. 使用来自 other_node 的 Node.ping 建立连接:
    iex(other_node@195.20.2.10)1> Node.ping(:'phoenix@195.20.2.2')
    (应该 return :pong 而不是 :pang

两个节点应该通过他们通常在网络上看到的地址相互联系。 (不同网络时的完整外部IP,同一本地网络中的192.168.X.X,同一台机器上的127.0.0.1

如果他们在不同的机器上,他们也必须设置相同的 cookie 值,因为默认情况下它会在您的主目录中自动生成 cookie。您可以通过 运行:
查看 cat ~/.erlang.cookie

最后您必须确保您的 EPMD 端口 4369 已打开,因为 Erlang VM 使用它进行节点间数据交换。 作为旁注,如果您将其保持打开状态,请确保将您的 cookie 设置为尽可能私密,因为如果有人知道,他就可以对您的机器拥有绝对的控制权。

你问这个问题已经有一段时间了,但有人可能会觉得这个答案很有价值。

截至 2021 年,Heroku 允许转发多个端口,这允许 remsh 进入 运行 ErlangVM 节点。这取决于您部署应用程序的方式,但一般来说,您需要:

  1. 给你的节点一个名字和一个cookie(即--name "myapp@127.0.0.1" --cookie "secret"
  2. 准确地告诉节点应该绑定到哪个端口,这样你就知道要转发哪个 pot(即 --erl "-kernel inet_dist_listen_min 9000 -kernel inet_dist_listen_max 9000"
  3. 通过 运行 heroku ps:forward 9001:4369,9000
  4. 转发 EPMD 和节点端口
  5. Remsh 进入您的节点:ERL_EPMD_PORT=9001 iex --cookie "secret" --name console@127.0.0.1 --remsh "myapp@127.0.0.1"

最终你应该用这样的东西启动你的服务器(如果你还在使用 Mix 工具):MIX_ENV=prod elixir --name "myapp@127.0.0.1" --cookie "secret" --erl "-kernel inet_dist_listen_min 9000 -kernel inet_dist_listen_max 9000" -S mix phx.server --no-halt

如果您使用的是 Release,Elixir 团队已经为您完成了大部分设置。

要验证 EPMD 端口是否已正确转发,请尝试 运行 epmd -port 9001 -names。输出应该是:

epmd: up and running on port 4369 with data:
name myapp@127.0.0.1 at port 9000

您可以关注我关于如何为 Dockerized 版本做这件事的笔记(还有一点麻烦):https://paveltyk.medium.com/elixir-remote-shell-to-a-dockerized-release-on-heroku-cc6b1196c6ad