LiveView working on localhost, connects then crashes cowboy on deployment resulting in a reload loop

I’ve been bashing my head against this for two days. I’m throwing in the towel and asking for help.

I have a Phoenix 1.4 project that I upgraded to 1.5 so I can take advantage of LiveView.

The upgrade went fine. I followed the installation instructions on the LiveView docs to the letter. My LiveView implementation works on localhost, but when I deploy it live (edeliver, nginx, Ubuntu 18.04.2 LTS, Erlang/OTP 24, Elixir 1.12.0), I get the following error from the app log:

10:35:25.440 [info] CONNECTED TO Phoenix.LiveView.Socket in 79µs
  Transport: :websocket
  Serializer: Phoenix.Socket.V2.JSONSerializer
  Parameters: %{"_csrf_token" => "S1QuUwpcAFd6Sgx8DhRuQjsDKC0cLTgCyeD8C1p6W8z8bN1w_FjFVyWt", "_mounts" => "0", "vsn" => "2.0.0"}
10:35:25.593 [error] Ranch listener ReaperconWeb.Endpoint.HTTP had connection process started with :cowboy_clear:start_link/4 at #PID<0.20324.1> exit with reason: {%ArgumentError{message: "no socket supervision tree found for Phoenix.LiveView.Socket.

Ensure your ReaperconWeb.Endpoint contains a socket mount, for example:

    socket "/socket", Phoenix.LiveView.Socket,
      websocket: true,
      longpoll: true
"}, [{Phoenix.Socket.PoolSupervisor, :start_child, 4, [file: 'lib/phoenix/socket/pool_supervisor.ex', line: 17]}, {Phoenix.Channel.Server, :join, 4, [file: 'lib/phoenix/channel/server.ex', line: 26]}, {Phoenix.Socket, :handle_in, 4, [file: 'lib/phoenix/socket.ex', line: 617]}, {Phoenix.Endpoint.Cowboy2Handler, :websocket_handle, 2, [file: 'lib/phoenix/endpoint/cowboy2_handler.ex', line: 175]}, {:cowboy_websocket, :handler_call, 6, [file: '/tmp/edeliver/reapercon/builds/deps/cowboy/src/cowboy_websocket.erl', line: 528]}, {:cowboy_http, :loop, 1, [file: '/tmp/edeliver/reapercon/builds/deps/cowboy/src/cowboy_http.erl', line: 257]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 226]}]}

Checking the lib/reapercon_web/endpoint.ex:

defmodule ReaperconWeb.Endpoint do
  use Phoenix.Endpoint, otp_app: :reapercon

  @session_options [
    store: :cookie,
    key: "_reapercon_key",
    signing_salt: "xxxxxxxx"
  ]

  socket "/socket", ReaperconWeb.UserSocket,
    websocket: true,
    longpoll: false

  socket "/live", Phoenix.LiveView.Socket,
    websocket: [connect_info: [session: @session_options]]
...... etc.

On the live server, the websocket connects, then immediately crashes. All other aspects of the deployment work except for the LiveView. And everything works on localhost. What other files should I be checking? I’ve been over the LiveView installation checking my work for typos more times than I can count.

Perhaps I’m looking in entirely the wrong place and should be looking at nginx?

And since it’s often asked in many of these help requests, my mix.exs:

defmodule Reapercon.MixProject do
  use Mix.Project

  def project do
    [
      app: :reapercon,
      version: "1.0.2",
      elixir: "~> 1.5",
      elixirc_paths: elixirc_paths(Mix.env()),
      compilers: [:phoenix, :gettext] ++ Mix.compilers(),
      start_permanent: Mix.env() == :prod,
      aliases: aliases(),
      deps: deps()
    ]
  end

  # Configuration for the OTP application.
  #
  # Type `mix help compile.app` for more information.
  def application do
    [
      mod: {Reapercon.Application, []},
      extra_applications: [:logger, :runtime_tools, :edeliver, :pdf_generator]
    ]
  end

  # Specifies which paths to compile per environment.
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]

  # Specifies your project dependencies.
  #
  # Type `mix help deps` for examples and options.
  defp deps do
    [
      {:bcrypt_elixir, "~> 2.0"},
      {:phoenix, "~> 1.5.9"},
      {:phoenix_pubsub, "~> 2.0"},
      {:phoenix_ecto, "~> 4.0"},
      {:ecto_sql, "~> 3.0"},
      {:postgrex, ">= 0.0.0"},
      {:phoenix_html, "~> 3.0"},
      {:phoenix_live_reload, "~> 1.2", only: :dev},
      {:phoenix_live_view, "~> 0.16.0"},
      {:floki, ">= 0.30.0", only: :test},
      {:gettext, "~> 0.11"},
      {:jason, "~> 1.0"},
      {:plug_cowboy, "~> 2.2"},
      {:edeliver, ">= 1.6.0"},
      {:distillery, "~> 2.1", warn_missing: false},
      {:csv, "~> 2.3"},
      {:mogrify, "~> 0.7.2"},
      {:pdf_generator, ">=0.5.5"},
      {:phx_gen_auth, "~> 0.7", only: [:dev], runtime: false},
      {:bamboo, "~> 1.5"},
      {:bamboo_sparkpost, "~> 1.1"}
    ]
  end

  # Aliases are shortcuts or tasks specific to the current project.
  # For example, to create, migrate and run the seeds file at once:
  #
  #     $ mix ecto.setup
  #
  # See the documentation for `Mix` for more info on aliases.
  defp aliases do
    [
      "ecto.setup": ["ecto.create", "ecto.migrate", "run priv/repo/seeds.exs"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet", "ecto.migrate", "test"]
    ]
  end
end

Any help or insight is greatly appreciated.

I would look at reverse proxy settings of nginx for websocket. You might try to remove nginx to check if the problem comes from that.

I remember there are posts with some sample config for nginx on this forum…

Thanks. I’ll poke around nginx.

Yep. I’m not 100% sure, but I completely changed my nginx configuration, and everything was working again. In fact, I performed a complete overhaul on my deployment process and just started from scratch. So, I don’t know exactly where the problem was, but rebuilding the pipeline fixed the infinite reload.