Build and Use Dockerized Wolfram Engine + Jupyter Lab

Ubuntu Desktop環境構築 Part 27

公開日: 2023-03-09
更新日: 2023-08-05

  Table of Contents

Overview

What I did

  • Wolfram Language Engine v13.2.0をJupyter Lab経由でアクセスを提供してくれるDocker Imageの作成

Why I Need Docker Image?

  • Localで構築すると, 環境Pythonや分析環境用Pythonとの関係で使いたい場所でWolfram Language Engine用Jupyter Labが使えないケースがあった
    • 別のところで既にactivatedされており, 使いたいタイミングで使えないなど
  • PCをreplaceする際に, 毎回はじめから構築するのは手間がかかる

Prerequisites

本質的には以下のものはいらないですが, 用いたもの

  • jq command: command-line JSON processor
  • gpg command: ID, Password情報が格納されたファイルを暗号化/復号化するため

Usage

Dockerfileに基づき, docker imageのbuildが完了したあとの利用方法はCLIにて以下のコマンドを入力します

1
2
3
4
5
6
7
docker run \
  --rm \
  -ti \
  --publish 8888:8888 \
  --user $(id -u $USER):$(id -g $USER) \
  --volume $PWD:/home/docker/work \
  ryonak/wolfram-jupyterserver:latest

そうすると, Jupyter Labが自動的にカレントディレクトリで立ち上がり, カーネル選択の場面で Wolfram Language Engine v13.2.0が選択できるようになります

Docker containerを終了させたい場合は, Jupyter Labを停止するのと同じ要領で Terminalでctrl+cを入力します.

Make the Dockerfile

ユーザー要件

  • Wolfram Language EngineをJupyter Lab経由で使用したい
  • Jupyter Lab使用に伴うPythonについては大きなこだわりはないが, version指定ができるようにしたい

以上の要件から, Dockerfileには

  1. pyenvによるPython version指定
  2. Jupyter Labの設定
  3. Wolfram Language Engineの設定
  4. Wolfram Language EngineとJupyter Labの接続設定

の4つを明示的に取り組む必要があります. 幸いなことに, (3)と(4)については既に公開されたDocker ImageとGitHubで公開されているアプリがあるので 前者のDocker ImageをベースとしてDockerfileを構築し, Dockerfileの中で後者について設定すれば良いという形で対応しています.

Dockerfileの構成

REMARKS

詳細についてはRyoNakagami/wolfram_jupyterserverを確認してください.

wolframresearch/wolframengineをベースに今回はDockerfileを作成しています. 本件にはあまり関係ないですが, wolframresearch/wolframengineのベースOSはUbuntu 18.04 LTSとなっています.

Python関連パッケージのインストール

  • ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezoneの部分は, パッケージインストール時に地理的な地域を選択するように求める対話的なプロンプトが出てくる可能性に対する予防措置を実施しときます
  • gitの他のパッケージはpyenvインストールに必要なパッケージのみを入れています
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# install apt packages
ARG BASE_IMAGE=wolframresearch/wolframengine
FROM ${BASE_IMAGE} as base

USER root

SHELL [ "/bin/bash", "-c" ]
ENV TZ=Asia/Tokyo
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone && \
    apt-get -qq -y update && \
    apt-get -qq -y install \
      software-properties-common \
      wget curl \ 
      make nodejs build-essential libssl-dev zlib1g-dev libbz2-dev \
      libreadline-dev libsqlite3-dev wget curl llvm libncurses5-dev \
      libncursesw5-dev xz-utils tk-dev libffi-dev liblzma-dev git && \
    apt-get -y autoclean && \
    apt-get -y autoremove && \
    rm -rf /var/lib/apt/lists/*

Jupyter Lab実行スクリプトの準備

rootユーザーの段階でJupyter Lab実行スクリプトを作成し, そのオーナーをdockerに譲渡しておきます

1
2
printf '#!/bin/bash\n\njupyter lab --no-browser --ip 0.0.0.0 --port 8888\n' > /docker/entrypoint.sh && \
chown -R docker /docker 

/docker/entrypoint.shは以下のようにlogin shellの段階で自動的に実行する設定する際に用います.

1
CMD ["/docker/entrypoint.sh"]

pyenv & Jupyter Labのインストール

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# Use C.UTF-8 locale to avoid issues with ASCII encoding
ENV LC_ALL=C.UTF-8
ENV LANG=C.UTF-8

ENV PATH=/home/docker/.local/bin:"${PATH}"

USER docker

ENV HOME=/home/docker
ENV PYENV_ROOT=$HOME/.pyenv
ENV PATH=$PYENV_ROOT/shims:$PYENV_ROOT/bin:$PATH
ARG PYTHON_VERSION=3.11.4
RUN git clone https://github.com/pyenv/pyenv.git ~/.pyenv && \
    pyenv install $PYTHON_VERSION && \
    pyenv global $PYTHON_VERSION &&\
    python -m pip install --upgrade pip &&  \
    pip install --no-cache-dir \
    nodejs \
    jupyterlab \
    jupyterlab_code_formatter \
    jupyterlab-git \
    lckr-jupyterlab-variableinspector \
    jupyterlab_widgets \
    ipywidgets \
    import-ipynb

Wolfram engin Jupyter Kernelのインストール

  • Wolfram engin Jupyter Kernelのインストール
  • WolframscriptによるJupyterへのkernel追加を実施
1
2
3
4
5
6
7
8
9
10
11
WORKDIR /home/docker
ARG WOLFRAM_ID
ARG WOLFRAM_PASSWORD
RUN git clone https://github.com/WolframResearch/WolframLanguageForJupyter && \
    cd WolframLanguageForJupyter/ && \
    wolframscript \
        -activate \
        -username "${WOLFRAM_ID}" \
        -password "${WOLFRAM_PASSWORD}" && \
    wolframscript -activate && \
    ./configure-jupyter.wls add

Docker image size

1
2
3
% docker images          
REPOSITORY                     TAG       IMAGE ID       CREATED        SIZE
ryonak/wolfram-jupyterserver   latest    980caz0a9e6a   5 hours ago    7.29GB

wolframresearch/wolframengine時点で6.0GB近くのサイズがあるのである程度の大きさは仕方ないと 諦めています.

Build shell script

ImageのBuildは以下のコマンドを実行するだけで基本的には足ります.

1
2
3
4
5
6
7
# Docker Build
docker buildx build . \
    --file Dockerfile \
    --build-arg BASE_IMAGE=wolframresearch/wolframengine \
    --build-arg WOLFRAM_ID=$WOLFRAM_ID \
    --build-arg WOLFRAM_PASSWORD=$WOLFRAM_PASSWORD \
    --tag ryonak/wolfram-jupyterserver:latest

ただしWOLFRAM_ID, WOLFRAM_PASSOWRDの設定が必要で新たにBuildが必要になる機会は少ないとは思いますが 平文で毎回毎回入力するのも億劫なのでgpgで一旦account情報を格納したJSONを暗号化し, そこから情報を読み取る形のshellscriptを作成しました.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/bash
# AUTHOR: RyoNak

set -e

# Variable
FILE=$1

# Functions
gpg_decode() {
    gpg -dq $FILE
}

# Extract config
if [[ "${FILE: -4}" == ".gpg" ]]; then
    WOLFRAM_ID=$(gpg_decode |jq -r '.WOLFRAM_ID');
    WOLFRAM_PASSWORD=$(gpg_decode |jq -r '.WOLFRAM_PASSWORD');
else
    WOLFRAM_ID=$(jq -r '.WOLFRAM_ID' $FILE);
    WOLFRAM_PASSWORD=$(jq -r '.WOLFRAM_PASSWORD' $FILE);
fi


# Docker Build
docker buildx build . \
    --file Dockerfile \
    --build-arg BASE_IMAGE=wolframresearch/wolframengine \
    --build-arg WOLFRAM_ID=$WOLFRAM_ID \
    --build-arg WOLFRAM_PASSWORD=$WOLFRAM_PASSWORD \
    --tag ryonak/wolfram-jupyterserver:latest

アカウント情報を格納したGPG JSON FILE(またはJSON FILE)を上記のシェルスクリプトの引数と指定した上で実行すれば Docker image buildが実施できます.

JSONファイルのgpg化は以下のコマンドでできます

1
% gpg -e -r <your-id> <暗号化したいファイル>

Column: jq -rの意図

上記のWolfram account情報を格納したJSONファイルは

1
2
3
4
{
    "WOLFRAM_ID":"your Wolfram ID",
    "WOLFRAM_PASSWORD":"your Wolfram ID password"
}

という構成をしています. ここからkeyに対応したvalueを取得したい場合は jqコマンドを以下のように使用します:

1
2
3
4
5
% jq '.WOLFRAM_ID' <JSON FILE PATH>
"your Wolfram ID"

% jq -r '.WOLFRAM_ID' <JSON FILE PATH>
your Wolfram ID

上記の例でわかるように, -rまたは--raw-outputは文字列中のダブルクォートエスケープを解除することができます.

Example

Appendix: Jupyer LabでWolfram Language kernelを選択できるようにする

WolframResearch / WolframLanguageForJupyterを用いることでWolfram Language kernelをJupyterで選択できるようになります.

事前にwolframscriptによるActivationが完了していないと実行できないことに注意が必要です. 設定自体は

1
2
3
% git clone git@github.com:WolframResearch/WolframLanguageForJupyter.git
% cd ./WolframLanguageForJupyter
% ./configure-jupyter.wls add

で終了. Removeしたい場合は

1
2
% cd ./WolframLanguageForJupyter
% ./configure-jupyter.wls remove

References

Dockerfile

Respositories



Share Buttons
Share on:

Feature Tags
Leave a Comment
(注意:GitHub Accountが必要となります)