Lucid Simple

Connecting Remote Nodes in Elixir

Hey there - this is something I was experimenting with during the week and couldn’t find that much great information on. If you’re wanting to setup a cluster of nodes in Elixir and are completely in the dark then this info might useful to you.

Video

Setting up a simple cluster in Elixir from Jim Whiteman on Vimeo.

Notes

The Erlang Port Mapper Daemon uses port 4369 so you’ll need that open.

You’ll also need to earmark a port in your security group for each node you’ll be using.

Security Group Example

Each node needs to be setup with a name, cookie, and kernel flag:

# node 1
iex --name your-fun-node-name-here@hostname-or-ip \
    --cookie some-cookie-name \
    --erl '-kernel inet_dist_listen_min <MINPORT>' \
    --erl '-kernel inet_dist_listen_max <MAXPORT>'

# node 2
iex --name some-other-node-name@some-other-hostname-or-ip
    --cookie some-cookie-name \
    --erl '-kernel inet_dist_listen_min <MINPORT>' \
    --erl '-kernel inet_dist_listen_max <MAXPORT>'
FYI: if you mispell anything for the `--erl` flags, then it will most likely fail silently.

In the above example, there is nothing stopping MINPORT and MAXPORT from being the same (e.g 9000).

If you’ve set things up correctly, your nodes will end up using the ports you want, rather than selecting an arbitrary port from the ephemeral range.

You can test this with the net_adm module:

:net_adm.names
# => {:ok, [{'your-fun-node-name-here@hostname', 9000}]}

In this example, the final integer value would represent the port your node is listening on (9000).

After that, it’s just a matter of connecting the nodes and sending sending some messages between them. You’ll need each node name to communicate, which you can get from the node function.

# node 1
Node.connect(:'some-other-node-name@some-other-hostname')

server = spawn(fn ->
  receive do
    msg -> IO.puts "I got a message! #{inspect msg}"
  end
end)

:global.register_name(:server, server)
# node 2
:global.whereis_name(:server) |> send "hello from node 2!"

This would result in I got a message! hello from node 2! being printed to stdout in node 1.

In reality, I wouldn’t use spawn and :global in this manner. But this is a convenient way to demonstrate the the nodes are connected and can communicate.

As I stated in the video, you have to be careful with security here. Owning one Elixir/Erlang node generally means you own all of them. Keeping as much as you can safe and secure behind your firewall is probably the the safest bet.

Wrapup

The promise of easier distributed programming is one of the great selling points of Elixir/Erlang, and even simple examples such as this can be quite thrilling. And while the above examples are admittedly naive, I hope you found them useful.

If I got something wrong, please let me know in the comments below or send me an email at jimtron9000 AT gmail.com.

Here are some other articles you might be intesrested in: