quda
Plug Cowboy - Search dynamically for a free port to run the server
I am building a simple http server using Plug.Cowboy (no Phoenix pls!) to serve a json API for a customer. A microservice.
The problem is the customer has a complex environment with multiple services of many sorts, containers, microservices etc. that are serving on various ports in his server. Therefore we were requested to develop the service to look dynamically and launch itself on a free/unused port.
When we build the Elixir app it is requested to declare the port at Plug initialization or it defaults to 4000/4040:
def start(_type, _args) do
children = [
{Plug.Cowboy, scheme: :http, plug: MyApp, port: 1234}
]
...
How can I re-factory this to search the first available unused port in a certain range ?
Thanks in advance,
Q.T.
Marked As Solved
dodo
You could probably use gen_tcp — OTP 29.0.2 (kernel 11.0.2) (not tested):
def start(_type, _args) do
children = [
{Plug.Cowboy, scheme: :http, plug: MyApp, port: get_free_port(4000)}
]
...
end
defp get_free_port(start) do
case :gen_tcp.listen(start, [:binary]) do
{:ok, socket} ->
:ok = :gen_tcp.close(socket)
start
{:error, :eaddrinuse} ->
get_free_port(start + 1)
end
end
Also Liked
joey_the_snake
If you put port: 0 it seems to look for an available port and use it. I’m not sure if this is safe to be counted on though. I tried it out because in erlang gen_tcp.listen finds an available port when you set port to 0.
Nicd
It should be safe at least on Linux, see the source: linux/net/ipv4/inet_connection_sock.c at 38f80f42147ff658aff218edb0a88c37e58bf44f · torvalds/linux · GitHub
This seems to be a Unix convention of getting a random available port. If you then need to know what port you got, possibly you can dig at the Cowboy socket to gain that information.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









