Search code examples
ipv6phoenix-frameworkcowboy

How to get Phoenix to listen on IPv6?


I'm struggling to find information about getting Phoenix (and Cowboy and Ranch for that matter) to listen on both IPv4 and IPv6.

I'm running on a VPS with Ubuntu 16.04. It has both an IPv4 and IPv6 address. When running netstat -tulpn it shows that beam is only listening on IPv4, with the ports specified in Phoenix config. Whereas other processes, like epmd, are able to listen on both IPv4 and IPv6.

I've tried specifying a port like "::4000" in my config.exs, but it crashes due to failure to parse as an integer.

Can someone point me in the right direction? Do I need to add a custom Cowboy listener somehow?

I'd rather not have to run Nginx in front to listen to IPv6 traffic.

Config I tried:

config :my_app, MyApp.Endpoint,
  http: [port: "[::]:4000"]

Stack trace (looks like Phoenix only expects an integer port):

** (Mix) Could not start application my_app: MyApp.start(:normal, []) returned an error: shutdown: failed to start child: MyApp.Endpoint
    ** (EXIT) shutdown: failed to start child: Phoenix.Endpoint.Server
        ** (EXIT) an exception was raised:
            ** (ArgumentError) argument error
                :erlang.binary_to_integer("[::]:4000")
                (phoenix) lib/phoenix/endpoint/server.ex:32: Phoenix.Endpoint.Server.to_port/1
                (phoenix) lib/phoenix/endpoint/server.ex:28: Phoenix.Endpoint.Server.default/3
                (phoenix) lib/phoenix/endpoint/server.ex:17: anonymous fn/5 in Phoenix.Endpoint.Server.init/1
                (elixir) lib/enum.ex:1623: Enum."-reduce/3-lists^foldl/2-0-"/3
                (phoenix) lib/phoenix/endpoint/server.ex:15: Phoenix.Endpoint.Server.init/1
                (stdlib) supervisor.erl:294: :supervisor.init/1
                (stdlib) gen_server.erl:328: :gen_server.init_it/6
                (stdlib) proc_lib.erl:247: :proc_lib.init_p_do_apply/3

Also this is Phoenix {:phoenix, "~> 1.2.0"} and Cowboy {:cowboy, "~> 1.0"}


Solution

  • According to https://hexdocs.pm/phoenix/endpoint.html you can also use just :inet6. This works for me:

    config :my_app, MyApp.Endpoint,
      http: [:inet6, port: 4000],