※2016/2/7 以下を追記 ・Dockerfileを画像を保存できるように修正 ・起動スクリプトを追記 ・Octave4.0でsubmit関数実行時にエラーが出ることに対する対策を追記
背景
CouseraのMachine Learningのコースの課題をこなすためにOctave開発環境が必要になるのですが、公式wikiによるとEl CapitanではOctaveはもはやvagrantを使って仮想マシンで動かすことが推奨されているようです。しかしOctaveを使うためだけに仮想マシンを一つ作るのも憚られるものがあるので、dockerで使えないかを試してみました。
以下は2016/2/1時点の手順です。
手順
以下のような手順で構築可能でした。4, 8あたりで引っかかりましたがなんとかこれで起動するようになりました。
- Docker Toolboxをインストール
-
docker-machine create default --driver virtualbox
でvirtualbox上にdefaultという名前でdocker実行用の仮想マシンを構築 - 仮想マシンを
docker-machine stop default
で停止 -
ここからboot2docker.isoのPreRelease版を落として来て、defaultが使うisoファイル(~/.docker/machine/machines/default/boot2docker.iso)に上書きする。
- docker2dockerのバージョン1.9.1だとDockerイメージのビルド時に"Setting up ca-certificates-java"と表示され固まる問題が発生するため
-
docker-machine start default
で仮想マシンを起動 - xquartzをインストール
-
brew install socat
を実行- dockerからのX11でGUIを転送してxquartzで描画するためにsocatが必要
- xquartzをアプリケーションから起動した状態でターミナルから
printenv DISPLAY
を実行すると/private/tmp/com.apple.launchd.SblSCN3ZNz/org.macosforge.xquartz:0
のような値を返すはずなのでこれを確認- tmux上などで実行するとこのDISPLAY環境変数がセットされていないことがあるので注意
- 8を確認したターミナル上で
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\"
を実行し、ディスプレイ転送の準備をする - ターミナルを別に開き、下記のDockerfileを置いたディレクトリ下で
docker build -t wrist/octave .
を実行し、dockerイメージをビルド -
docker run --rm -e DISPLAY=192.168.10.10:0.0" -i -v /Users/wrist/work/octave/home:/root -t wrist/octave octave
を実行してコンテナを作成し、GUIが転送されて来れば成功- 192.168.10.10の部分はホストとなっているマシンのローカルIP
-
-v
でホストマシンのボリュームをdockerコンテナ上にマウント可能
起動スクリプト(2016/2/7追記)
上記手順ではXQuartzを実行した後にsocatを実行していますが、実はこれでは駄目っぽく、XQuartzを実行した時点で6000番ポートをXQuartzが使うようになるので、ややこしいですがターミナルでsocatを実行した後にXQuartzを起動する必要があるようです。
というわけでややこしいので以下のような起動スクリプトを書きました。docker-machineで作成したVM、socatプロセス、およびXQuartzプロセスがそれぞれ起動(存在)しているかを順番に確認して、起動してなければそれぞれ起動させ、その上でローカルのIPアドレスを調べてそのIPアドレスをDISPLAY環境変数にセットした上でdocker runでコンテナを起動させます。
#!/bin/bash
# vim:fileencoding=utf-8
machine_name="default"
container_name="wrist/octave"
local_home="${HOME}/work/octave/home"
docker_home="/root"
exec_command="octave"
count=`VBoxManage list runningvms | grep ${machine_name} | wc -l`
if [ $count = 0 ]
then
echo "[run octave] running docker-machine..."
docker-machine start ${machine_name}
docker-machine regenerate-certs -f ${machine_name}
fi
eval "$(docker-machine env ${machine_name})"
# run socat before XQuartz
count=`ps aux | grep socat | grep -v grep | wc -l`
if [ $count = 0 ]
then
echo "[run octave] running socat in background..."
socat TCP-LISTEN:6000,reuseaddr,fork UNIX-CLIENT:\"$DISPLAY\" &
fi
count=`ps aux | grep XQuartz | grep -v grep | wc -l`
if [ $count = 0 ]
then
echo "[run octave] open XQuartz..."
open -a XQuartz
fi
nics=`ifconfig | awk -F: '/^[a-z]/ && !/^lo/ { print $1 }'`
ipv4_detected=""
for nic in ${nics}; do
ipv4s=$(ifconfig ${nic} | awk '$1 == "inet" { print $2 }')
for ipv4 in ${ipv4s}; do
if [ -n "${ipv4}" ]
then
ipv4_detected=${ipv4}
break
fi
done
if [ -n "${ipv4_detected}" ]
then
echo "[run octave] docker run using display IP: ${ipv4_detected}"
docker run --rm -e DISPLAY=${ipv4_detected}:0.0 -i -t \
-v ${local_home}:${docker_home} \
${container_name} \
${exec_command}
break
fi
done
Dockerfile
※2016/2/7追記 画像を保存するためにoctave上でprint -dpng 'plot.png'
を実行する際にエラーが出るため、最後の2行を追記
FROM ubuntu:14.04
MAINTAINER Hiromasa OHASHI <stoicheia1986@gmail.com>
ENV DEBIAN_FRONTEND noninteractive
RUN apt-get -y install software-properties-common
RUN add-apt-repository ppa:octave/stable
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get install -y texinfo gnuplot octave liboctave-dev octave-info
# japanese environment
RUN apt-get install -y language-pack-ja-base language-pack-ja
RUN update-locale LANG=ja_JP.UTF-8 LANGUAGE="ja_JP:ja"
ENV LANG ja_JP.UTF-8
ENV LANGUAGE ja_JP:ja
ENV LC_ALL ja_JP.UTF-8
RUN apt-get install -y fonts-takao
RUN apt-get install -y xfig
RUN apt-get install -y epstool
Octave4.0でのsubmit関数のエラー(2016/2/7追記)
上記DockerfileだとOctave4.0が入りますが、4.0だと課題を送る時のsubmit関数を実行する際にエラーが出ます。下記リンクを参考に修正を施すことで実行できるようになります(下記記事では2箇所となっていますが、同様の記述があるmファイルを全て修正する必要があるようです)。
Machine Learning - Week2 Octave 4.0で課題をする時のエラー
また公式フォーラムにも上記現象のスレッドがあります。