Dockerコンテナ上に構築された環境にVSCodeからリモートアクセスしてデバッグまでできるそうなので、Elixirで試してみました。なお、せっかくなのでErlang、Elixirのバージョンは2019/10/1時点で最新のものを使っていきたいと思います。
環境
- Windows 10 Pro 64bit
- VSCode 1.38.1
- Docker Desktop for Windows 2.1.0.3
- Docker Engine 19.03.2
事前準備
こちらを参考に以下をインストールしました。
- VSCodeのインストール
- VSCodeのリモート開発の拡張機能インストール
- Dockerのインストール
Dockerfileの作成
-
作業用ディレクトリを作り、VSCodeで開きます。
-
F1キーを押してコマンドパレットを開き、
Remote Containers: Add Development Container Configuration Files...
を実行します。
-
ベースとなる開発環境を選択しますが、DockerFileを編集するので何でも良いです。とりあえず
Ubuntu 18.04 & Git
を選択します。
-
作業用ディレクトリに
.devcontainer
ディレクトリが作成され、devcontainer.json
とDockerfile
が自動生成されますので、Dockerfile
をElixir環境用に変更します。-
Elixri1.9.1のDockerfileの内容をコピーして自動生成された
Dockerfile
に上書きします。 - Elixri1.9.1のDockerfileから以下の箇所を変更しました。
- LANGUAGE、LC_ALLの追加
- mix local.hexの実行を追加
- iexの起動の削除
-
Elixri1.9.1のDockerfileの内容をコピーして自動生成された
FROM erlang:22
# elixir expects utf8.
ENV ELIXIR_VERSION="v1.9.1" \
- LANG=C.UTF-8
+ LANG=C.UTF-8 \
+ LANGUAGE=C.UTF-8 \
+ LC_ALL=C.UTF-8
RUN set -xe \
&& ELIXIR_DOWNLOAD_URL="https://github.com/elixir-lang/elixir/archive/${ELIXIR_VERSION}.tar.gz" \
&& ELIXIR_DOWNLOAD_SHA256="94daa716abbd4493405fb2032514195077ac7bc73dc2999922f13c7d8ea58777" \
&& curl -fSL -o elixir-src.tar.gz $ELIXIR_DOWNLOAD_URL \
&& echo "$ELIXIR_DOWNLOAD_SHA256 elixir-src.tar.gz" | sha256sum -c - \
&& mkdir -p /usr/local/src/elixir \
&& tar -xzC /usr/local/src/elixir --strip-components=1 -f elixir-src.tar.gz \
&& rm elixir-src.tar.gz \
&& cd /usr/local/src/elixir \
&& make install clean \
+ && cd $HOME \
+ && mix local.hex --force
- CMD ["iex"]
コンテナにリモート接続し、拡張機能を有効化する
ここまで出来たらコンテナを立ち上げ、VSCodeからリモート接続します。
-
VSCodeの左下の
リモートウィンドウを開く
を押すとリモート機能に関するメニューが出てくるので、Remote-Containers: Reopen in Container
を選択します。そうすると、コンテナのビルドが行われリモート接続が完了します。
-
ターミナルを表示し、
elixir -v
を実行してバージョンを確認します。Erlang/OTP:22、Elixir:1.9.1がインストールされていることが確認できました。
-
リモートコンテナでは、ローカル環境でインストールしていた拡張機能が適用されていないため、Elixir関連の以下の拡張機能を有効にしておきます。インストールしたら再読み込みします。
- vscode-elixir
- ElixirLS
- ElixirFormatter
Elixirでコードを動かす
とりあえずHelloWorldが動くことを確認します。
-
mix new hello
で動作確認用プロジェクトを作成します。ターミナルを表示しcd hello
を行いHelloプロジェクトのディレクトリへ移動します。 - VSCodeのエクスプローラーから
hello/lib/hello.ex
を選択して開きます。Helloモジュールにhello
関数ができているため、関数名をworld
に変更します。docも併せて変更しておきます。変更が終わったら保存します。
defmodule Hello do
@moduledoc """
Documentation for Hello.
"""
@doc """
Hello world.
## Examples
- iex> Hello.hello()
+ iex> Hello.world()
:world
"""
- def hello do
+ def world do
:world
end
end
- ターミナルで
iex -S mix
を実行し、プロジェクトのモジュールをiexで開きます。Hello.world
で:wold
が返ってくることが確認できました。Ctrl + C
を2回押してiexを終了します。
ブレークポイントを張ってデバッグする
デバッグが可能であることを確認します。
-
launch.json
にデフォルトのデバッグ構成が追加され開かれます。projectDir
が${workspaceRoot}
になっており、このままではmix.exsが見つからないためエラーとなるので、{workspaceRoot}/hello
に変更します。
-
hello/lib/hello.ex
を開き、デバッグ確認用のコードを追加します。
defmodule Hello do
@moduledoc """
Documentation for Hello.
"""
@doc """
Hello world.
## Examples
iex> Hello.world()
:world
"""
def world do
+ x = 1
+ x = 2
:world
end
end
-
hello/test/hello_test.exs
のテストコードが自動生成されたままとなっているので、関数名を変更します。変更した行にブレークポイントを設定します。
defmodule HelloTest do
use ExUnit.Case
doctest Hello
test "greets the world" do
- assert Hello.hello() == :world
+ assert Hello.world() == :world
end
end
- デバッグウィンドウを開き、デバッグ構成で
mix test
を選択した上でデバッグを開始します。ブレークポイントで止まっていることが確認できました。また、デバッグ確認用のコードがステップ実行できることも確認できました。
所感
コンテナなのでローカル環境に影響が無い。コーディングはVSCodeの機能を活用できる。ローカルのディレクトリをマウントしているため、コンテナを終了しても成果物が残り続ける。結構良い感じなのではないでしょうか。次はコンテナ内でビルドする必要があるためにコーディングが中々捗らなかったElixirをAWS Lambdaで動かすための環境を整えたいと思います。