Connect nodes using Libcluster with docker-compose

So, let’s start with the manual connection in docker. Once it works on your side we can move to libcluster :slight_smile:

We run two iex in two different containers, connected to the same elixir network and passing the same ERLANG_COOKIE via env variable

First let’s create the bridge network (something that docker-compose creates automatically)

docker network create elixir

Then run the first container in a terminal, attaching it to the elixir network. The container’s name is app1 which is its domain name inside the network.

The command we run in the container is iex --sname app@app1 --cookie ${ERLANG_COOKIE}

$ docker container run -it  --rm --network elixir  \
  -e ERLANG_COOKIE="its_a_secret" \
  --name app1 \
   elixir:1.9 \
  bash -c 'iex --sname app@app1 --cookie ${ERLANG_COOKIE}'

then we run the second app2 container in another terminal

$ docker container run -it  --rm --network elixir  \
  -e ERLANG_COOKIE="its_a_secret" \
  --name app2 \
   elixir:1.9 \
  bash -c 'iex --sname app@app2 --cookie ${ERLANG_COOKIE}'

and we connect it to app@app1

iex(app@app2)1> Node.connect(:app@app1)
true
iex(app@app2)1> Node.list
[:app@app1]

So we can test connection with docker-compose using a simple script app.exs I just made for this case. We make available in the two containers via bind mounting

docker-compose.yaml

version: "3.7"
services:
  app1:
    image: "elixir:1.9"
    environment:
      ERLANG_COOKIE: "its_a_secret"
    volumes:
      - ./app.exs:/app.exs

    command: ["bash", "-c", "elixir --no-halt --sname app@app1 --cookie $$ERLANG_COOKIE app.exs"]
    # command: ["bash", "-c", "sleep infinity"]

  app2:
    image: "elixir:1.9"
    environment:
      ERLANG_COOKIE: "its_a_secret"
    volumes:
      - ./app.exs:/app.exs
    command: ["bash", "-c", "elixir --no-halt --sname app@app2 --cookie $$ERLANG_COOKIE app.exs"]
$ docker-compose up
app2_1  | I'm here! Sleeping for 2 seconds
app1_1  | I'm here! Sleeping for 2 seconds
app2_1  | [self is :app@app2]: :app@app1
app2_1  | connect (from :app@app2: true
app1_1  | [self is :app@app1]: :app@app2
app1_1  | connect (from :app@app1: true
app2_1  | nodes: [:app@app1]
app2_1  | ping :app@app1: :pong
app1_1  | nodes: [:app@app2]
app1_1  | ping :app@app2: :pong
app2_1  | ping :app@app1: :pong
...

@Zios does it work on your side?

8 Likes