Dream Driven Development。夢を形にしよう!

Elixir開発環境としての Dockerとノード間通信

Elixir開発環境としての
Dockerとノード間通信


関数型言語は何度も挫折してきましたが、Elixirは若干その敷居を下げてくれた気がします。(モナドとか出てこないし)
今回はDockerのelixirイメージを使って開発環境を作成しますが、若干手を加えてElixir特有のノード間通信(コンテナ間通信)を簡単に試せる環境にします。
今回作成するのは以下のような環境です。
elixir docker環境
早速作りましょう!

elixir docker環境の変更

dockerにあるelixirイメージを走らせるだけであれば

$ docker run -it --rm elixir bash

ですみます。
ですが、これだといくつか不便な点があります。

ということで、elixir向けdockerfileを作り、起動コマンドもすこし変更します。

elixir 向け docker file

elixir_dockerfileとして作成。

FROM elixir
LABEL maintainer="hassyheisaku"
ENV USER_NAME heisaku
ENV UID 1000
RUN useradd -m -u ${UID} ${USER_NAME}

ENV HOME /home/${USER_NAME}

ENV TZ Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone

WORKDIR ${HOME}
USER ${USER_NAME}

ユーザとしてheisakuを追加したのがメインポイントです。
ビルドしておきます。

$ docker build -t myelixir -f elixir_dockerfile .
$ docker images
REPOSITORY                   TAG          IMAGE ID       CREATED         SIZE
myelixir                     latest       5597fe573818   20 hours ago    1.3GB
elixir                       latest       6fac7ad41d86   2 weeks ago     1.3GB
:

もともとのelixirイメージが結構大きいですね。。

docker networkの作成

dockerのコンテナ同士をつなぐためにdocker networkを作成しておきます。これによるブリッジ接続でコンテナ同士がつながります。

$ docker network create elixirnet
$ docker network ls
NETWORK ID     NAME                     DRIVER    SCOPE
bf3721881a89   elixirnet                bridge    local
:

起動コマンド

Volumeのマウント、docker networkへのアタッチ、ホスト名指定を行います。

$ docker run -it -v /home/heisaku/elixir:/work -h hoge --network elixirnet --rm myelixir bash 
#host名hogeの場合

-v volumeのマウント(ホスト側:コンテナ側)
-h host名指定
–network 作成したdocker networkを指定

Elixirコンテナ間接続

コンテナ1 Hoge

#ホスト名 hoge をつける
$ docker run -it -v /home/heisaku/elixir:/work -h hoge --network elixirnet --rm elixirheisaku bash 
#ここからコンテナ内
heisaku@hoge:~$ hostname -i
172.18.0.2
heisaku@hoge:~$ iex --sname hoge --cookie hogecookie 
# cookieで両方のコンテナのiexに同じ文字列を与える {#a6}
iex(hoge@hoge)1>

コンテナ2 Fuga

#ホスト名 fuga をつける
$ docker run -it -v /home/heisaku/elixir:/work -h fuga --network elixirnet --rm elixirheisaku bash 
#ここからコンテナ内
heisaku@fuga:~$ hostname -i
172.18.0.3
heisaku@fuga:~$ iex --sname fuga --cookie hogecookie
#コンテナ1 への接続
iex(fuga@fuga)1> Node.connect :"hoge@hoge" 
true
iex(fuga@fuga)2> Node.list
[:hoge@hoge]
iex(fuga@fuga)3>

接続できた!

再びコンテナ1 Hoge

コンテナ2でiex起動・接続後

iex(hoge@hoge)1> Node.list
[:fuga@fuga]
#↑↑↑↑コンテナ2から接続があったのでコンテナ1でも認識できている
#関数で相手側を呼び出せているか確認
iex(hoge@hoge)2> func = fn -> IO.inspect Node.self end
#Function<45.65746770/0 in :erl_eval.expr/5>
iex(hoge@hoge)4> Node.spawn(:"hoge@hoge", func)
:hoge@hoge
#PID<0.120.0>
iex(hoge@hoge)3> Node.spawn(:"fuga@fuga", func)
:fuga@fuga
#PID<11237.122.0>

動きました!

まとめ

Elixirのように分散環境を意識したプログラミング言語の場合は、このようにコンテナで環境作成するとはかどりますね。

オチは?

|

お気に入りサイト