How to bind phoenix app to specific ip address?

How to bind a phoenix app to a specific ip address?

could not find anything about that, nowhere, unfortunately, but for me this is quite important, as our servers have multiple ip addresses and I need to bind phoenix to one.

Thanks!

You can use the following snippet in your conf:

config :app_name, AppName.Endpoint,
  http: [ip: {0,0,0,0}],
  ...

Be aware of the fact, that you need to specify the IP-address in tuple notion

9 Likes

you saved my sunday, thank you very much!!!

Will this config variable be used for both http and websockets?

It is btw, absolutely impossible to find this totally important information anywhere, may I asked where you got that secret knowledge from (besides maybe you wrote or read the sourcecode)? I really would just like to read that up somewhere and rather not annoy people in forums with such basic questions, but could not find it in neither guides nor docs.

again: thank yo very much!

And it wold be great if anybody with commit rights would like to put that piece of information into the phoenix deployment guides, btw.

have a nice sunday!

https://hexdocs.pm/plug/Plug.Adapters.Cowboy.html

1 Like

ah, thanks! have a nice day!

Sorry, have to come back with that, your instructions seem to be wrong or I do not understand how to use them the right way.
This config line:
http: [port: 5000, host: {127,0,0,1}]

generates this error:
[warn] Transport option {:host, {127, 0, 0, 1}} unknown or invalid.

This seems to work:
http: [port: 5000, ip: {127,0,0,1}]

Did you know that you must set that if you do not want your app to listen on 0.0.0.0?
The default in prod.exs also makes your app listen on 0.0.0.0 - I do not think this is a good thing and it should be changed to listen to 127.0.0.1 only.

Why would you want your server in production environment listen to localhost only by default? Then nobody from outside would be able to connect to it :scream:

Thank you for the info, I’ll edit my previous post accordingly.


Yes, I did know that. That is cowboys default, I told you that it is that way in the sister thread you opened.

Also it is very common to have a server software listen on 0.0.0.0 but let the firewall handle the rest. It is much easier to debug something via telnet/ssh if you are able to use lynx or similar to do a quicktest on the terminal.

Usually because you have something like nginx proxying in front of it. :slight_smile:

4 Likes

Excellent! Taking note for future projects. :slight_smile:

Frequently however you don’t, in the event you have a load balancer in front of several instances of your application. Additional reverse proxying on each server doesn’t really give you much.

I almost always have something in front, whether nginx or squid (or both). :slight_smile:

After wanting a nicer way to specify IP addresses in the normal “human” format for a couple of projects, I wrote a super-simple library called socket_address to help with generating addresses in the tuple format that Cowboy requires (for both IPv4 and IPv6). It’s essentially a wrapper around the Erlang :inet.parse_address/1 function that handles some port/address validation for you in an Elixir-like way, and also provides a helper for outputting the actual server options keyword list.

Just thought it might be useful for others that run across this thread and need to configure a bind address that’s more complicated than {127, 0, 0, 1}.

1 Like

Currently setting up my first production server and app. Came across this thread and it’s left me a little confused. Do I bind my app to 127.0.0.1 or not? It is behind a firewall and nginx. My preference is to take the pragmatic approach but I’m too much of a noob to understand the risks/consequences of this decision.

You need to bind to an IP that is reachable by your ReverseProxy if you use one (and it sounds as if you were). If (and only if) your reverse proxy is running on the same host, then you can bind to 127.0.0.1.

So if you have a docker container with your app and your reverse proxy runs in another one or even on the physical host, then binding to 127.0.0.1 will break.

Which IPs you have to bind to under which circumstances is networking 101, and if you are not sure how to do it correctly you should consult someone who helps you, probably with even more than just that, as you will probably miss a lot of other things that one needs to consider when preparing the set up.

Thanks for the reply, much appreciated. I look forward to being able to follow your advice and consult an expert in these fields. Having re-read this thread and further information on 127.0.0.1 v 0.0.0.0 my Phoenix app can keep it’s a default configuration and continue to be served by it’s nginx reverse proxy on 127.0.0.1, losing ssh access for debugging was the consequence that swung the argument for me.

… 10 minutes later… Having not tried to fire up a console against the newly deployed production app I decide to give it a whirl and discover that despite not adjusting the IP configuration of it’s Endpoint it is bound to 127.0.0.1, done a bit of digging and it’s certainly not something I’ve set. Perhaps the defaults in Plug.Adapters.Cowboy have changed? Although a default isn’t apparent in the docs or source code.

In Rails I use rails server -b 192.168.1.11 -p 80 to start a Rails app in specific IP or Port.

Are there any Elixir way to start Phoenix server in different IP or Port?

Cheers!

@arrose Yes, this is the topic of this thread, and the answer is in second post by @NobbZ with documentation linked in the fourth post by @andre1sk . You set it in a config file in config/*.exs

1 Like

For future reference, If you would like to bind the ip address to a domain name locally for CORS debugging you can do the following.

  1. Change the host file (MacOS)
  2. Change the endpoint configuration in config.exs file or dev.exs to:
config :zencca_server, ZenccaServerWeb.Endpoint,
  http: [port: 5540],
  url: [host: "clientapp.com"]

This will let your server run on http://clientapp.com:5540 and the hostname used is what you configure in your hosts file.