はじめに
この記事の背景
JuliaをDocker Containerの中で動かしていると,そのままではPlotsを表示することが出来ない.これはJulia特有のことではなく,一般にコンテナの内部で動くプログラムからGUI表示をすることはそのままの設定では出来ない.
この記事では,Docker Containerで動くJuliaでPlotをホスト側に表示するために必要な設定をまとめる.コンテナ内でJuliaのPlotを行い,その結果をx forwardingによってホスト側で表示する.そのためのコンテナ側の環境変数の設定とホスト側の用意について述べる.
本記事ではエディタにVS Codeを用い,その拡張機能Remote-Cointainersを利用してコンテナ内でVS Codeを開いて開発できるようにしようと思う.Remote-Cointainersを使うと,あたかもローカルで作業しているかのようにコンテナで作業が出来てVS Codeの強力な開発機能を使える.
この記事はこんな人向け!
- Julia公式のDocker imageに基づいたコンテナ環境でJuliaを使いたい!
- コンテナ内で
Plots.jl
を使いたい! - ホスト側にプロットした結果をGUIで表示したい!
- VS CodeのRemote-Cointainersの拡張機能を使いたい!
実行環境
- Windows 10 Pro 20H2 / Windows 10 Home 20H2
- Docker Desktop Version 3.2.2
- Visual Studio Code Version 1.54.3
- Extension: Remote - Containers v0.165.0
事前用意
前提事項
前提事項としてDocker DesktopとVS Codeはインストールされているものとします.インストール方法は他の資料を参考にしてもらえると幸いです.
Remote -Containersのインストール
Remote-Cointainersは,Dockerコンテナ内でVS Codeを開いて開発を行うことが出来るようにするVS Codeの拡張機能です.インストールは簡単です.
- VS CodeのEXTENSIONS: MARKETPLACEで
remote-containers
を検索する. - Remote-Containersをインストールする
設定ファイルの用意
以下に示すような構成でファイルを用意してください.
開発を行うフォルダの中に以下の示すような構成でフォルダとファイルを作ります.
(directory you specify)
│ plottest.jl
│
├─.devcontainer
│ devcontainer.json
│ Dockerfile
│
└─.tmp
-
plottest.jl
: プロットのテストを行うファイルです. -
.devcontainer
: Remote - Containersの設定ファイルやコンテナの作成に関連したファイルを置くフォルダです.-
devcontainer.json
: Remote -Containersの設定ファイルです. -
Dockerfile
: Dockerイメージの基となるファイルです.
-
-
.tmp
: ソケットファイルが格納されるフォルダです.
これらのファイルについての詳しいことは,後ほど述べます.
Dockerfile
の用意
Dockerfile
は,必要なアプリやパッケージと環境設定を記述したファイルです.このファイルを基にしてコンテナが作られます.今回はDockerfile
の中に,Plots.jl
のインストールとホスト側でプロットの結果を表示するための設定を記述します.以下のようなDockerfile
を用意します.
# Get official docker image fo julia
FROM julia
# set username as `root`
USER root
# update package list
RUN apt-get update
# install git and x11-apps for x11 test
RUN apt-get install -y git x11-apps
# Required package for GR backend of Plots
# https://gr-framework.org/julia.html#installation
RUN apt-get install -y libxt6 libxrender1 libxext6 libgl1-mesa-glx libqt5widgets5
# Install `Plots.jl and precompile it`
RUN julia -e 'using Pkg; Pkg.REPLMode.pkgstr("add Plots;precompile");using Plots'
# Configuration for x11 forwarding
ENV DISPLAY host.docker.internal:0.0
ENV XDG_RUNTIME_DIR /workspaces/Julia-programing/.tmp
ENV LIBGL_ALWAYS_INDIRECT 1
Dockerfileでポイントとなるのは次の部分です.
-
RUN apt-get install -y libxt6 libxrender1 libxext6 libgl1-mesa-glx libqt5widgets5
Plots.jl
のバックエンドGR
が依存するパッケージをインストールしておく.詳細はここを参照してください. -
RUN julia -e 'using Pkg; Pkg.REPLMode.pkgstr("add Plots;precompile");using Plots'
Plots.jl
をインストールします.パッケージモードを呼び出してインストールを行います.この時プリコンパイルも同時に行います. -
ENV DISPLAY host.docker.internal:0.0
コンテナ側に接続先(ホスト側)のXサーバーを教えてあげる環境変数です.これによりコンテナ側がどのディスプレイを使えばよいのかがわかります.
x11-apps
はXサーバーの動作確認のために入れます.gitはおまけで入れています.
devcontainer.json
の用意
devcontainer.json
は,VS codeの拡張機能Remote-Containersを使ってコンテナを立ち上げてVS codeで開発する際の設定などを書いておくファイルです.以下のようなファイルを用意します.
{
"name": "Julia dev container",
// specify your workspace
"context": "..",
"dockerFile": "Dockerfile",
"settings": {
// use bash as terminal
"terminal.integrated.shell.linux": "/bin/bash",
// set path of git
"git.path": "/usr/bin/git"
},
// user name of container
"remoteUser": "root",
// specify vs code extentions you will use on remote
"extensions": [
"julialang.language-julia"
]
}
extensions
の部分に,リモート環境で使いたいVS Codeの拡張機能を書いておくと,VS Codeでコンテナを開くときにインストールされます.今回はJuliaの拡張機能を追加します.ほかにリモート環境で使いたい拡張機能を書いておけば,インストールされます.このファイルに書く内容は,VS Codeで拡張機能のページを開いたとき,下の図の赤枠の部分に表示されます.
ホスト側にXサーバー(VcXsrv)をインストール
デフォルトではコンテナ側でGUIを使えないので,ホスト側にXサーバーを立ち上げて,コンテナ側のGUIを表示できるようにする必要がある.Xサーバーはリモート環境のGUIの表示を行うための機能を提供するソフトという認識で問題なさそうです.
今回は__VcXsev__というXサーバーを用います.公式ページからインストーラをダウンロードします.インストール時に特に弄る必要はなく,デフォルトで選択されているままでインストールすれば問題ありません.
コンテナとXサーバーの起動
VS codeでイメージをビルドしてコンテナの中に入る
VS codeで開発フォルダを開き,コマンドパレットを開きます.Remote-Cointainers: Rebuild and Reopen in Container
を選択します.
VS Codeの左下の緑色のアイコンをクリックしてReopen in Container
を選択しても良いです.
これでイメージをビルドしてコンテナを立ち上げることが出来ます.ビルドにはそこそこ時間がかかります.ビルドが終わってコンテナが立ち上がると,VS Codeでコンテナ内にアクセスできます.開発フォルダがコンテナ環境で開かれて,ターミナルもコンテナ環境のものを使えます.拡張機能も使えるので,非常に開発しやすいです.
Xサーバーを立ち上げる
インストールしたVcXsrvを起動して,コンテナからのGUI描画を受け付けられるようにします.スタートメニューからXLaunch
を選択します.
Display settingsの画面が出てきます.ここではMultiple Windowsを選択します.
Client startupの画面が出てきます.ここではStart no clientを選択します.
Extra settingsが出てきます.何も弄らなくても問題なく表示できます.色々検索してみると,Disable access controlにチェックを入れる例が多く出てきます.
この記事によれば,アクセスコントロールを無効にすると誰でもXサーバーにアクセスできてしまうようです.必要が無ければチェックを外しておいた方が良いのかもしれません.
最後に完了を押せば,Xサーバーの準備は完了です.Xサーバーのインジゲーターがタスクバーに現れると思います.
コンテナ環境からプロットGUIをホストに表示する
Xサーバーの動作確認
コンテナの環境変数DISPLAY
が適切に設定されて,ホスト側のXサーバーが正常に動作しているかを確認します.
Dockerfile
でx11-apps
をインストールしました.これはXアプリケーションを集めたものです.これらを実行して,コンテナ内からホスト側に表示できるかどうかをテストします.
コンテナ内で,コマンドxeyes
を実行します.すると以下のような眼玉が現れます.この目玉はカーソルを追いかけるように動きます.これが確認出来たら,コンテナ内からGUIが表示できていることになります!
root@xxxxxxxxxx:# xeyes
ちなみにx11-apps
にはほかにも面白いXアプリケーションがあります.詳しくはここを参照してください.
プロットの表示テスト
さて,Xサーバーの動作が確認出来たら,いよいよJuliaでプロットします.コンテナ内でコマンドjulia
を実行して,JuliaのREPLモードに入ります.以下のようにランダムな値を100個生成してプロットします.
julia> using Plots
julia> plot(rand(100))
上手くいけば,以下のようにウィンドウが表示されてグラフが表示されるはずです.おめでとうございます!
テストスクリプトplottest.jl
を作って実行しても表示されます.ここでスクリプトでプロットを表示するためには関数gui()
を忘れないようにしてください.プログラムが終了するとプロットが消えてしまうのでsleep()
を使っています.(詳細:Plotドキュメンテーション)
using Plots
# plot
plot(rand(100))
# display plot
gui()
sleep(10)
参考資料
今回の記事の参考にさせていただいた資料です.先人の試みに感謝!