I was troubleshooting an ets lookup recently in my staging enviornment and realized I didn't know how to attach to a running Elixir application remotely. In this brief example I'll be using docker-compose to spin up 2 application nodes and attach with iex to inspect each node in realtime.
Docker
The docker-compose file declares a few services but the focus of this post will be the `app` you see at the very top.
version: '2.2'
services:
app:
build:
context: ./app
dockerfile: Dockerfile
depends_on:
postgres:
condition: service_healthy
env_file:
- .env
ports:
- 4000
entrypoint: ./entrypoint.sh
proxy:
build:
context: ./nginx
dockerfile: Dockerfile
ports:
- 80:80
links:
- app
The dockerfile for the application offers some insight into how I fetch and compile dependencies with mix at build time but the entrypoint.sh file you see declared in the docker-compose file shows how the Phoenix application is started.
#!/bin/bash
str=`date -Ins | md5sum`
name=${str:0:10}
mix run transform.exs
mix phx.digest
mix ecto.create
mix ecto.migrate
mix run priv/repo/seeds.exs
elixir --sname $name --cookie monster -S mix phx.server
The last line in particular shows that we assign a name and cookie. This will be important later as we attempt to connect remotely.
Build and run docker
If you are new to docker you first need to build the application from the root of the project. Note: this might take a few minutes if you've not run docker before.
docker-compose build
Next you need to spin up the application nodes, postgres and nginx.
docker-compose up --scale app=2
After the application is up and running you can view a listing of all containers.
docker ps
Connect to the container
Before we attach to the Elixir application with iex we need to get terminal access for a given node. The `docker ps` command will list out each running container and you should see 2 in particular prefixed with the name `example_app_`. Using the id value to the left of the name run the command below to get a bash prompt on the docker container.
docker exec -it 3160c6 /bin/bash
Attach with iex
Once complete you now have a bash prompt on the docker container running your Elixir application. Next we need to get the `sname` of the running elixir session.
ps aux | grep elixir
From the output above you should see the random string value for `sname` that was used to launch `mix phx.server`. You will use this string as the first half of the `remsh` argument. The second half is the full id of the container itself and this should be visible on the bash prompt line. If not, open another terminal and run `docker ps` again to get the full id value. Note: cookie is require to match and without it you will see a connection refused message in the docker-compose output.
iex --sname console --cookie monster --remsh c3f2473a1e@3160c633294f
You can follow along using the docker-compose for my example on github