この記事は #NervesJP Advent Calender 2021 の24日目2日目です(大幅に超過してスンマセン
1日目の記事は @mnishiguchi さんの「Nerves電子ペーパーでHello world」でした.
Elixir/Erlangバージョンの組合せ問題
世俗派関数型言語Elixir(by @kikuyutaセンセ)は,関数型言語の老舗本舗であるErlang VMの上でイゴいています.ElixirもErlangもそれぞれ活発に開発が進んでいてバージョンアップを繰り返しています.
そうなるとバージョンの組合せは無限に爆発していってお姉さん困っちゃうわけですが,それでは皆さんのプロジェクトではどの組合せを使うのが良さそうでしょうか??
ホストに環境構築する場合
とりあえずElixirを使いたい!最新版でええんやでっ!という方は,brew
なりapt
なりでさくっと入れてもらったら良いかと思います.
ホストに所定の組合せを構築したい場合は asdf
がだんぜんオススメです.
詳しい解説は #NervesJP Advent Calender 2021 19日目の @torifukukaiou さんによるawesome!!な記事を読むと良いです.
Dockerで環境構築する場合
速攻で使うにはDocker Hubにある Elixir Official Image を使えば良いでしょう.
サクッと最新版を docker run
して bash を起動して,いろいろバージョンを調べてみました.
root@b1e975b797c2:/# mix local.hex
Are you sure you want to install "https://repo.hex.pm/installs/1.13.0/hex-1.0.1.ez"? [Yn] Y
* creating root/.mix/archives/hex-1.0.1
root@b1e975b797c2:/# mix hex.info
Hex: 1.0.1
Elixir: 1.13.1
OTP: 24.2
Built with: Elixir 1.13.0 and OTP 22.3
root@b1e975b797c2:/# uname -a
Linux b1e975b797c2 5.10.76-linuxkit #1 SMP Mon Nov 8 10:21:19 UTC 2021 x86_64 GNU/Linux
root@b1e975b797c2:/# cat /etc/issue
Debian GNU/Linux 11 \n \l
Officialなので安心ではありますが,ここで気になるのが,
- 任意の組合せは用意できない.Erlangは固定化されてしまう.
- OSはDebianがデフォ,あと -slim と -alpine はある.でも他は選べないし,OSバージョンも指定できない.
というところです.
無限にある組合せをぜんぶサポートするのは無理ですし,対象プロジェクトによっては特定の組合せでイゴかないこともありえます(とはいっても実際にそんなの体験したことは無いですが:D
対象の開発プロジェクトや依存ライブラリがCIテストの対象としている組合せとか推奨している組合せとかを使っておくのが心理的に安心安全というわけです.
ちなみに,みんな大好き!Nervesの執筆時点な最新版v1.7.13では,
- Erlang/OTP 24.1.5
- Elixir 1.12.3-otp-24
に乗っかっておきたいところです.
そしてNerves v1.7.13でのCIテスト対象になっているのは,
を紐解くと,下記の全5バージョンの組合せになっていました.
<snipped...>
jobs:
build_elixir_1_13_otp_24:
docker:
- image: hexpm/elixir:1.13.1-erlang-24.1.7-alpine-3.14.2
<snipped...>
build_elixir_1_12_otp_24:
docker:
- image: hexpm/elixir:1.12.3-erlang-24.1.5-alpine-3.14.2
<snipped...>
build_elixir_1_11_otp_23:
docker:
- image: hexpm/elixir:1.11.4-erlang-23.3.4-alpine-3.13.3
<snipped...>
build_elixir_1_10_otp_23:
docker:
- image: hexpm/elixir:1.10.4-erlang-23.3.4-alpine-3.13.3
<snipped...>
build_elixir_1_9_otp_22:
docker:
- image: hexpm/elixir:1.9.4-erlang-22.3.4.18-alpine-3.13.3
<snipped...>
workflows:
version: 2
build_test:
jobs:
- build_elixir_1_13_otp_24
- build_elixir_1_12_otp_24
- build_elixir_1_11_otp_23
- build_elixir_1_10_otp_23
- build_elixir_1_9_otp_22
おっ hexpm/elixir
ってこれなんぞ??というのが,今回の記事の発端です.
(なお本記事のNerves成分は以上でっす!
hexpm/elixir!(とは??
みんな大好きHexの開発チームであるBob
さんが公開されているものです.
- hexpm/elixir - Docker Image | Docker Hub
じゃなかった,Bob
さんってリポジトリ名みたい:D
- hexpm/bob: The Builder
現時点のDocker Tagsのページは4098までありました.
1ページあたり25タグ表示なので,4097*25+8 = 102,433タグ!!
最新の 1.13.1
で "Filter Tags" しても69ページまであります!(無限に課金してそう,,,
ちなみにもちろん Erlang単体のDocker image もご用意されています.
どの組合せが使えるの??
どのElixir x Erlangの組合せを docker build
しているのか,リポジトリのコードからは定義されていると思わしき箇所は見つけられませんでした.
README#Docker-images には,
Docker images for Bob's Elixir and Erlang builds are built periodically. Bob checks for new Elixir and Erlang releases every 15 minutes and builds images for any new versions it discovers.
15分ごとにリリースチェックしてるぜ!などと申しております
どうもそれぞれのGitHub tags/releasesをほとんどぜんぶビルドしている気がしなくもない,,, 探検隊の情報を求めます.
いちお分かったこととして,アーキテクチャは "amd64" と "arm64" の2種類,OSは "alpine" 2種類 "ubuntu" 5種類 "debian" 6種類 の計13種類を回しているようです.
defmodule Bob.Job.DockerChecker do
@erlang_tag_regex ~r"^(.+)-(alpine|ubuntu|debian)-(.+)$"
@elixir_tag_regex ~r"^(.+)-erlang-(.+)-(alpine|ubuntu|debian)-(.+)$"
@archs ["amd64", "arm64"]
# TODO: Automate picking the OS versions
@builds %{
"alpine" => [
"3.14.3",
"3.15.0"
],
"ubuntu" => [
"groovy-20210325",
"focal-20210325",
"bionic-20210325",
"xenial-20210114",
"trusty-20191217"
],
"debian" => [
"bullseye-20210902",
"buster-20210902",
"stretch-20210902",
"bullseye-20210902-slim",
"buster-20210902-slim",
"stretch-20210902-slim"
]
}
<snipped...>
要するにどんだけ組合せあるか分かんないんだけど,,, これだけあれば安心ですねっ!!
イゴかしてみる
最新版と思わしき 1.13.1-erlang-24.2-ubuntu-focal-20210325
のタグを試してみました.
せっかくなので Ubuntu focal (20.04) を指定しています.
$ docker run -it --rm hexpm/elixir:1.13.1-erlang-24.2-ubuntu-focal-20210325 /bin/bash
root@ef3e34f05207:/# mix local.hex
Are you sure you want to install "https://repo.hex.pm/installs/1.13.0/hex-1.0.1.ez"? [Yn] Y
* creating root/.mix/archives/hex-1.0.1
root@ef3e34f05207:/# mix hex.info
Hex: 1.0.1
Elixir: 1.13.1
OTP: 24.2
Built with: Elixir 1.13.0 and OTP 22.3
root@ef3e34f05207:/# uname -a
Linux ef3e34f05207 5.10.76-linuxkit #1 SMP Mon Nov 8 10:21:19 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
root@ef3e34f05207:/# cat /etc/issue
Ubuntu 20.04.2 LTS \n \l
かなり嬉しいのが docker image のサイズです.公式のイメージと比較してみましょう.
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
elixir 1.13.1 b032b26101ec 33 hours ago 1.3GB
hexpm/elixir 1.13.1-erlang-24.1.7-ubuntu-focal-20210325 f6e2d9dafd82 9 days ago 183MB
1.3GB vs 183MB となりました.なんと約1/10です!!
もちろんそのぶん自分勝手に使うにはいろいろ入れないといけないですが,ベースのサイズは小さいほうに限りますよねぇ.
RclexのDocker環境に使ってみる
Rclexとは,Elixirでロボット向けのROS 2/DDS通信ができるすごいやつです(てきとー
詳しいことはそのうち別の記事で紹介できればです〜
$\huge{May\ the\ BEAM\ be\ with\ your\ Robots!!}$
をRclexでやるには,やっぱりElixir/ErlangとROS 2の環境を同時に整えないといけません.どちらもそれなりに大変です.
Alchemist視点でRclexの環境をホスト上(正確にはAzure VM上ですが)に構築してお試しする方法は,またもや @torifukukaiou さんが5日目の記事にまとめてくださっています!!
ここまでやるのはメンドいですよね〜 あとGitHub Actionsで素敵にCI回したいし.
それと,ROS 2はUbuntuに強く依存していて,さらにROS 2のdistribution(version)に対応したUbuntuのバージョンを揃えないといけません.最新LTSのFoxyであればUbuntu focal (20.04)になります.
てなことで,この hexpm/elixir をベースとしてRclex向けのDocker環境を仕立ててみました.
### FIXME according to the target version
# base image
FROM hexpm/elixir:1.12.3-erlang-24.1.5-ubuntu-focal-20210325
# Set Ubuntu Codename
ENV UBUNTU_CODENAME focal
# Set ROS_DISTRO environment
ENV ROS_DISTRO foxy
# force error about debconf
ENV DEBIAN_FRONTEND noninteractive
# update sources list
RUN apt-get clean
RUN apt-get update
# install additonal packages
RUN apt-get install -y git sudo build-essential
# install AStyle to format C code (NIFs)
RUN apt-get install -y astyle
### install ROS START
### https://docs.ros.org/en/foxy/Installation/Ubuntu-Install-Debians.html
# Set locale
RUN apt update && apt -y install locales
RUN locale-gen en_US en_US.UTF-8
RUN update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
RUN export LANG=en_US.UTF-8
# Setup Sources
RUN apt update && apt install -y curl gnupg2 lsb-release
RUN curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
RUN echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu ${UBUNTU_CODENAME} main" | tee /etc/apt/sources.list.d/ros2.list > /dev/null
# Install ROS 2 packages
RUN apt update
RUN apt install -y ros-${ROS_DISTRO}-ros-base
# Install ROS 2 packages
RUN apt install -y python3-colcon-common-extensions
# Setup ROS environment in shell
RUN echo 'source /opt/ros/${ROS_DISTRO}/setup.sh' >> ~/.bashrc
### install ROS END
# cleanup
RUN apt-get -qy autoremove
# install hex and rebar
RUN mix local.hex --force
RUN mix local.rebar --force
# check version
RUN . /opt/ros/${ROS_DISTRO}/setup.sh && env | grep ROS
RUN mix hex.info
hexpm/elixir のUbuntu向けな特定バージョンを BASE
にして,Installing ROS 2 via Debian Packagesを RUN
しまくっているだけです(あと詳しくはコメント読んでください
最初の3構文をいろいろ変えたらいろいろバージョン派生できるので,とっても便利になりました!
こんな感じでROS 2(Ubuntu) x Elixir x Erlangの組合せを計10種類用意できて,RclexのGitHub Actionsに登録しています1.Elixir x ErlangはNervesのバージョン組に乗っかっています.
- foxy-ex1.13.1-otp24.1.7
- foxy-ex1.12.3-otp24.1.5 [latest]
- foxy-ex1.11.4-otp23.3.4
- dashing-ex1.12.3-otp24.1.5
- dashing-ex1.11.4-otp23.3.4
- dashing-ex1.10.4-otp23.3.4
- dashing-ex1.9.4-otp22.3.4.18
- galactic-ex1.13.1-otp24.1.7
- galactic-ex1.12.3-otp24.1.5
- galactic-ex1.11.4-otp23.3.4
余談:ros official image使えよ??
あんさんROSも Docker Official Image 出してるの知らへんの?いや知ってますとも〜
当初はこれを BASE
にしてイメージ作っていたんですが,erlang-solutions_2.0_all.deb
の挙動がおかしかったりイメージがでかくなったりいろいろありましてね,,, 詳しく気になる方はこのあたり見てください.
おわりに
ということでこの記事では Bob
さんが素敵に働いてくれている hexpm/elixir を紹介しました.
なんといってもベースのイメージが小さいし,OSもある程度の選択肢があるし,Nerves勢だけじゃなくElixir/Erlang勢やPhoenix勢にも意外と知られていない優良情報と言っても過言ではないような気がします(なにごと
それでは皆さん,よいDocker x Elixirライフを〜
#NervesJP Advent Calender 2021 の3日目は @torifukukaiou さんの「elixir-desktop/desktop のandroidサンプルをイゴかす」です!(でした!!
-
GalacticはRclexでまだ対応できておらず,正確にはGitHub Actionsでまだ使えていません. ↩