I am currently working with elixir. It is a neat language, with a lot of good tooling. It’s rooted in the erlang world. A very useful tool to have some overview on the internals of the BEAM is the erlang observer.
Nowadays, the common workflow relies on containers. It is a very common issue to try to start graphical applications from within a container. Let’s prepare a playground
FROM elixir:1.10.4 ARG uid=1000 ARG gid=1000 RUN groupadd -g ${gid} alchymist \ && useradd -u ${uid} -g alchymist alchymist \ && mkdir -p /test \ && chown alchymist:alchymist /test USER alchymist WORKDIR /test ENTRYPOINT ["iex"] CMD []
We can build it with
docker build --build-arg=uid=$(id -u) --build-arg=gid=$(id -g) -t alchymist:0 .
Let’s start normally
docker run --rm -ti alchymist:0
Trying to start the observer, we get an error
Erlang/OTP 22 [erts-10.7.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> :observer.start() 09:46:02: Error: Unable to initialize GTK+, is DISPLAY set properly? {:error, {{:einval, 'Could not initiate graphics'}, [ {:wxe_server, :start, 1, [file: 'wxe_server.erl', line: 65]}, {:wx, :new, 1, [file: 'wx.erl', line: 115]}, {:observer_wx, :init, 1, [file: 'observer_wx.erl', line: 107]}, {:wx_object, :init_it, 6, [file: 'wx_object.erl', line: 372]}, {:proc_lib, :init_p_do_apply, 3, [file: 'proc_lib.erl', line: 249]} ]}} iex(2)>
The trick is to mount the needed files and pass the correct value for the environment variable DISPLAY
.
docker run --rm \ -v $HOME/.Xauthority:$HOME/.Xauthority:rw \ -v /tmp/.X11-unix:/tmp/.X11-unix \ -e DISPLAY=$DISPLAY \ -ti alchymist:0
Starting the observer, we then succeed
Erlang/OTP 22 [erts-10.7.2.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1] [hipe] Interactive Elixir (1.10.4) - press Ctrl+C to exit (type h() ENTER for help) iex(1)> :observer.start() :ok iex(2)>