[英]Dockerized Phoenix/Elixir App Rejects All HTTP/socket requests
I'm trying to follow along with this tutorial to get my (functioning on localhost) elixir/phoenix app running in a docker container and I'm running into difficulties. 我试图按照本教程进行操作,以使我的(在localhost上运行的)elixir / phoenix应用程序在docker容器中运行,但遇到了麻烦。
https://pspdfkit.com/blog/2018/how-to-run-your-phoenix-application-with-docker/ https://pspdfkit.com/blog/2018/how-to-run-your-phoenix-application-with-docker/
Here is my error: 这是我的错误:
[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....>
I'm not sure what is going on. 我不确定发生了什么。
My room lobby is simply a socket channel defined room_channel.ex as: 我的房间大厅只是一个将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###
It runs fine when I run this without my docker files - what I added is the following: 当我在没有docker文件的情况下运行此程序时,它运行良好-我添加的内容如下:
###run.sh###
docker-compose up --build
###run.sh###
###Dockerfile###
FROM elixir:latest
RUN apt-get update && \
apt-get install -y postgresql-client
# Create app directory and copy the Elixir projects into it
RUN mkdir /app
COPY . /app
WORKDIR /app
# Install hex package manager
RUN mix local.hex --force
# Compile the project
RUN mix do compile
CMD ["/app/entrypoint.sh"]
###Dockerfile###
###docker-compose###
# Version of docker-compose
version: '3'
# Containers we are going to run
services:
# Our Phoenix container
phoenix:
# The build parameters for this container.
build:
# Here we define that it should build from the current directory
context: .
environment:
# Variables to connect to our Postgres server
PGUSER: postgres
PGPASSWORD: postgres
PGDATABASE: db
PGPORT: 5432
# Hostname of our Postgres container
PGHOST: db
ports:
# Mapping the port to make the Phoenix app accessible outside of the container
- "4000:4000"
depends_on:
# The db container needs to be started before we start this container
- db
db:
# We use the predefined Postgres image
image: postgres:9.6
environment:
# Set user/password for Postgres
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
# Set a path where Postgres should store the data
PGDATA: /var/lib/postgresql/data/pgdata
restart: always
volumes:
- pgdata:/var/lib/postgresql/data
# Define the volumes
volumes:
pgdata:
###docker-compose###
###entrypoint.sh###
#!/bin/bash
while ! pg_isready -q -h $PGHOST -p $PGPORT -U $PGUSER
do
echo "$(date) - waiting for database to start"
sleep 2
done
# Create, migrate, and seed database if it doesn't exist.
if [[ -z `psql -Atqc "\\list $PGDATABASE"` ]]; then
echo "Database $PGDATABASE does not exist. Creating..."
createdb -E UTF8 $PGDATABASE -l en_US.UTF-8 -T template0
echo "1"
mix do ecto.drop, ecto.create
echo "2"
mix phx.gen.schema Binarys binary postnum:integer leftchild:integer rightchild:integer downvotes:integer message:string parent:string upvotes:integer
echo "3"
mix phx.gen.schema Comments comment postnum:integer children:map downvotes:integer message:string parent:string upvotes:integer identifier:uuid
echo "4"
mix ecto.migrate
echo "5"
mix run priv/repo/seeds.exs
echo "Database $PGDATABASE created."
fi
exec mix phx.server
###entrypoint.sh###
I also changed the config in my dev.exs file like this: 我还更改了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###
Interestingly all of these errors seem to spawn when my frontend is up, but not making requests (other than connecting to the socket). 有趣的是,当我的前端启动时,所有这些错误似乎都产生了,但是没有发出请求(除了连接到套接字)。 If I try and make an http request I get this:
如果我尝试发出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 |
So you can see that it sees the request and it appears to be manipulating it. 因此,您可以看到它看到了请求,并且似乎正在处理它。 It just can't return it.
它只是无法返回它。 I have my ports exposed in both my Docker and docker-compose files, I really can't see what else could be going wrong as I have this app working when I run it outside the docker containers.
我在Docker和docker-compose文件中都暴露了端口,当我在docker容器外运行该应用程序时,我真的看不到还有什么可能出问题了。
What is going wrong? 怎么了?
I think the problem lies in your Dockerfile. 我认为问题出在您的Dockerfile中。
You didn't expose any port. 您没有公开任何端口。
To be able to publish port, you need to first expose the post. 为了能够发布端口,您需要首先公开该帖子。
Try adding EXPOSE 4000
in your Dockerfile. 尝试在Dockerfile中添加
EXPOSE 4000
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.