Attach iex to running elixir inside docker container

Published April 20, 2019 by Toran Billups

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 [email protected]
  

You can follow along using the docker-compose for my example on github


Twitter / Github / Email