docker 对接的Phoenix/Elixir应用程序拒绝所有HTTP/套接字请求

68de4m5k  于 2022-11-22  发布在  Docker
关注(0)|答案(3)|浏览(155)

我试图按照这个教程来让我的(在localhost上运行)elixir/phoenix应用程序在一个docker容器中运行,我遇到了困难。
https://pspdfkit.com/blog/2018/how-to-run-your-phoenix-application-with-docker/
以下是我的错误:

[info] JOIN "room:lobby" to AlbatrossWeb.RoomChannel
phoenix_1  |   Transport:  Phoenix.Transports.WebSocket (2.0.0)
phoenix_1  |   Serializer:  Phoenix.Transports.V2.WebSocketSerializer
phoenix_1  |   Parameters: %{}
phoenix_1  | inside room:lobby channel handler
phoenix_1  | [info] Replied room:lobby :ok
phoenix_1  | [error] Ranch protocol #PID<0.403.0> of listener AlbatrossWeb.Endpoint.HTTP (cowboy_protocol) terminated
phoenix_1  | ** (exit) exited in: Phoenix.Endpoint.CowboyWebSocket.resume()
phoenix_1  |     ** (EXIT) an exception was raised:
phoenix_1  |         ** (Protocol.UndefinedError) got FunctionClauseError with message "no function clause matching in Poison.Encoder.__protocol__/1" while retrieving Exception.message/1 for %Protocol.UndefinedError{description: "", protocol: Poison.Encoder, value: ["127", "127", "room:lobby", "phx_reply", %{response: %{}, status: :ok}]}
phoenix_1  |             (poison) lib/poison/encoder.ex:66: Poison.Encoder.impl_for!/1
phoenix_1  |             (poison) lib/poison/encoder.ex:69: Poison.Encoder.encode/2
phoenix_1  |             (poison) lib/poison.ex:41: Poison.encode!/2
phoenix_1  |             (phoenix) lib/phoenix/transports/v2/websocket_serializer.ex:22: Phoenix.Transports.V2.WebSocketSerializer.encode!/1
phoenix_1  |             (phoenix) lib/phoenix/transports/websocket.ex:197: Phoenix.Transports.WebSocket.encode_reply/2
phoenix_1  |             (phoenix) lib/phoenix/endpoint/cowboy_websocket.ex:77: Phoenix.Endpoint.CowboyWebSocket.websocket_handle/3
phoenix_1  |             (cowboy) /app/deps/cowboy/src/cowboy_websocket.erl:588: :cowboy_websocket.handler_call/7
phoenix_1  |             (phoenix) lib/phoenix/endpoint/cowboy_websocket.ex:49: Phoenix.Endpoint.CowboyWebSocket.resume/3
phoenix_1  |             (cowboy) /app/deps/cowboy/src/cowboy_protocol.erl:442: :cowboy_protocol.execute/4
phoenix_1  | [info] JOIN "room:lobby" to AlbatrossWeb.RoomChannel
<....repeat forever....>

我不确定是怎么回事。
我的房间大厅只是一个套接字通道,定义为room_channel.ex:

###room_channel.ex###
defmodule AlbatrossWeb.RoomChannel do
  use Phoenix.Channel

  def join("room:lobby", _message, socket) do
    IO.puts "inside room:lobby channel handler"
    {:ok, socket}
  end

  def join("room:" <> _private_room_id, _params, _socket) do
    {:error, %{reason: "unauthorized"}}
  end

  def handle_in("updated_comments", %{"payload"=>payload}, socket) do
    IO.puts("inside updated_comments handle_in")
    broadcast! socket, "updated_comments", payload
    # ArticleController.retrieve(socket)
    {:noreply, socket}
  end
end
###room_channel.ex###

当我在没有我的docker文件的情况下运行它时,它运行得很好-我添加的内容如下:
第一个
我还修改了dev.exs文件中的配置,如下所示:

###dev.exs###
config :albatross, Albatross.Repo,
  adapter: Ecto.Adapters.Postgres,
  username: "postgres",
  password: "postgres",
  hostname: "db",
  database: "db",
  # port: 5432,
  pool_size: 10
###dev.exs###

有趣的是,所有这些错误似乎都是在我的前端启动时产生的,但并没有发出请求(除了连接到套接字)。如果我尝试发出http请求,我会得到这样的结果:

phoenix_1  | [info] POST /addComment
phoenix_1  | inside addComment
phoenix_1  | [debug] Processing with AlbatrossWeb.PageController.addComment/2
phoenix_1  |   Parameters: %{"payload" => %{"message" => "sf", "parent" => "no_parent", "postnum" => 6, "requestType" => "post", "urlKEY" => "addComment"}}
phoenix_1  |   Pipelines: [:browser]
phoenix_1  | [error] Failure while translating Erlang's logger event
phoenix_1  | ** (Protocol.UndefinedError) got FunctionClauseError with message "no function clause matching in Plug.Exception.__protocol__/1" while retrieving Exception.message/1 for %Protocol.UndefinedError{description: "", protocol: Plug.Exception, value: %Protocol.UndefinedError{description: "", protocol: Plug.Exception, value: %Protocol.UndefinedError{description: "", protocol: Plug.Exception, value: %Protocol.UndefinedError{description: "", protocol: String.Chars, value: %Postgrex.Query{columns: nil, name: "", param_formats: nil, param_oids: nil, param_types: nil, ref: nil, result_formats: nil, result_oids: nil, result_types: nil, statement: ["INSERT INTO ", [34, "comment", 34], [], [32, 40, [[[[[[[[[[], [34, "children", 34], 44], [34, "downvotes", 34], 44], [34, "identifier", 34], 44], [34, "message", 34], 44], [34, "parent", 34], 44], [34, "postnum", 34], 44], [34, "upvotes", 34], 44], [34, "inserted_at", 34], 44], 34, "updated_at", 34], ") VALUES ", [], 40, [[[[[[[[[[], [36 | "1"], 44], [36 | "2"], 44], [36 | "3"], 44], [36 | "4"], 44], [36 | "5"], 44], [36 | "6"], 44], [36 | "7"], 44], [36 | "8"], 44], 36 | "9"], 41], [], " RETURNING ", [], 34, "id", 34], types: nil}}}}}
phoenix_1  |     (plug) lib/plug/exceptions.ex:4: Plug.Exception.impl_for!/1
phoenix_1  |     (plug) lib/plug/exceptions.ex:19: Plug.Exception.status/1
phoenix_1  |     (plug) lib/plug/adapters/translator.ex:79: Plug.Adapters.Translator.non_500_exception?/1
phoenix_1  |     (plug) lib/plug/adapters/translator.ex:49: Plug.Adapters.Translator.translate_ranch/5
phoenix_1  |     (logger) lib/logger/erlang_handler.ex:104: Logger.ErlangHandler.translate/6
phoenix_1  |     (logger) lib/logger/erlang_handler.ex:97: Logger.ErlangHandler.translate/5
phoenix_1  |     (logger) lib/logger/erlang_handler.ex:30: anonymous fn/3 in Logger.ErlangHandler.log/2
phoenix_1  |     (logger) lib/logger.ex:861: Logger.normalize_message/2
phoenix_1  |     (logger) lib/logger.ex:684: Logger.__do_log__/3
phoenix_1  |     (kernel) logger_backend.erl:51: :logger_backend.call_handlers/3
phoenix_1  |     (kernel) logger_backend.erl:38: :logger_backend.log_allowed/2
phoenix_1  |     (ranch) /app/deps/ranch/src/ranch_conns_sup.erl:167: :ranch_conns_sup.loop/4
phoenix_1  |     (stdlib) proc_lib.erl:249: :proc_lib.init_p_do_apply/3
phoenix_1  |

所以你可以看到它看到了请求,并且似乎正在处理它。它只是不能返回它。我的端口在我的Docker和Docker-compose文件中都是公开的,我真的看不出还有什么问题,因为当我在Docker容器外运行这个应用程序时,它还在工作。
出了什么问题?

xqkwcwgp

xqkwcwgp1#

我觉得问题出在你的Dockerfile上。
你没有暴露任何端口。
为了能够发布端口,您需要首先公开帖子。
尝试将EXPOSE 4000添加到Docker文件中。

e5njpo68

e5njpo682#

没有足够的信誉来回复其他的答案,但是我想告诉潜在的读者,EXPOSE指令只是文档。在发布之前没有必要公开一个端口。
从官方的docker文档中:
EXPOSE指令实际上并不发布端口。它的作用是作为构建映像的人和运行容器的人之间的一种文档,说明哪些端口要发布。要在运行容器时实际发布端口,请在docker运行时使用-p标志来发布和Map一个或多个端口,或者使用-P标志发布所有公开的端口并将它们Map到高阶端口。

pieyvz9o

pieyvz9o3#

很抱歉添加这个作为答案,但我在尝试为Elixir/Phoenix应用程序创建Docker容器时遇到了一些问题,我只是在创建REST API(没有HTML)项目的类型,它在本地工作得很好,但当我创建Docker图像和容器并运行容器时,应用程序运行得很好,但当我从Postman尝试时,我总是得到一个错误,说X1 M0 N1 X,这不是很清楚,请检查以下 Postman 的错误。
picture socket hang up error 1picture socket hang up error 2显示器
这是我的Dockerfile:

FROM elixir:alpine
RUN mkdir /app
COPY . /app
WORKDIR /app
RUN apk update && apk add inotify-tools
RUN mix local.hex --force && mix local.rebar --force
RUN mix do deps.get, deps.compile
EXPOSE 4000
CMD ["mix", "phx.server"]

你必须知道,我正在尽我所能地做到最简单,因为我还在学习Elixir和Phoenix,我想把事情弄清楚,所以我没有任何网络或安全性与docker-compose或任何其他集成。我只想在一个docker容器中运行我的用Elixir/Phoenix制作的REST API。

相关问题