There is more than one way to do this. Here is an example.
Remote setup
mix new foo
Edit foo/lib/foo.ex to look like this:
defmodule Foo do
def connect do
Node.start(:foo@foohostname, :shortnames)
Node.set_cookie(:foo@foohostname, :shh_dont_tell)
end
def hello do
IO.puts :world
end
end
Be sure to put your hostname on your local network in place of foohostname.
Next, start it up. You mentioned you want to avoid iex, so you can start your application however you prefer. You could create a mix script to start it and connect, for example. But since that is a digression from the topic at hand, I will start it with iex:
iex -S mix
Followed by:
iex(1)> Foo.connect
Local setup
mix new bar
In bar/lib/bar.ex:
defmodule Bar do
def connect do
Node.start(:bar@barhostname, :shortnames)
Node.set_cookie(:bar@barhostname, :shh_dont_tell)
Node.connect(:foo@foohostname)
end
end
Remember to substitute the hostname for bar into barhostname and likewise for foo.
Now, you have a programmatic means to connect your nodes. You can access the other Foo node anywhere in the Bar application.
Let's use iex again for an example. Follow along at the commandline:
iex -S mix
iex(1)> Bar.connect
#PID<16393.795.0>
iex(bar@barhostname)> Node.spawn_link :foo@foohostname, fn -> Foo.hello end
world
#PID<16393.795.0>
Note that connecting the nodes is not necessary for spawning one-off function calls like this, so in this example you could choose not to include the Node.connect line, but it is necessary for more sophisticated node management.