Dockerized Phoenix / Elixir App отклоняет все запросы HTTP / сокетов - PullRequest
0 голосов
/ 12 октября 2018

Я пытаюсь следовать этому руководству, чтобы мое (работающее на локальном хосте) приложение elixir / phoenix работало в док-контейнере, и я столкнулся с трудностями.

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###

Он работает нормально, когда я запускаю это без файлов докеров - я добавил следующее:


###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###

Я также изменил конфигурацию в моем файле 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.

Что такоеидет не так?

1 Ответ

0 голосов
/ 15 октября 2018

Я думаю, что проблема заключается в вашем Dockerfile.

Вы не выставили ни один порт.

Чтобы иметь возможность опубликовать порт, вам нужно сначала открыть сообщение.

Попробуйте добавить EXPOSE 4000 в ваш Dockerfile.

...