KH CoderをDocker for Macで動かす手順
KH CoderをMacのDockerで動かす手順です。
以下の神記事をほぼ全面的に参照させていただき、手元で動かなかった部分を直したり手作業が発生していた部分を減らすように修正したりしています。
↑この記事がなければとても設定まで行きつけませんでした。。。ありがとうございます🙇
(0) 事前準備
開発環境の準備です。
すでにインストール済みの方はスキップしてください。
Dockerインストール
仮想環境作ってくれるやつ。以下公式サイトの手順に沿ってインストールして起動しておいてください。
homebrewインストール
Macのパッケージ管理システム。以下の公式サイトに記載されているスクリプトをコンソール(ターミナル)で実行してください。
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
(1) 各種セットアップ(初回のみ)
XQuartzインストール
ここからが本番です。まずはコンテナのGUIアプリを表示するためのXQuartz(X11)をインストールします。
$ brew install xquartz
上記インストール完了後、XQuartzを起動して、メニューの環境設定
> セキュリティ
から ネットワーク・クライアントからの接続を許可
にチェックをつける。
設定を保存したあと、一度Macからログアウトしてログインしなおす。
ログイン後、環境変数$DISPLAY
に値が入っていることを確認。
$ echo $DISPLAY
=> /private/tmp/com.apple.launchd.qeR8i7Bf4G/org.macosforge.xquartz:0
↑こんな感じで出力されればOK。
参考
KH Coderインストール
Githubからリポジトリをclone
元記事のリポジトリをforkして修正したものを公開しているので、まずはそれをcloneしてきます。
$ git clone git@github.com:notsobad-jp/NL2E.git
$ cd NL2E
KH Coderをインストール
リポジトリにsubmoduleとしてKHCoderが入っているので、それをupdateします。
$ git submodule init
$ git submodule update
設定ファイルをコピー
KHCoderの設定ファイルcoder.ini
にMySQL接続情報などを設定する必要があるので、あらかじめ用意しておいたファイルをコピーしておきます。
$ cp coder.ini KHCoder/khcoder/config/coder.ini
(2) アプリケーションの起動
ここまでセットアップが完了したら、いよいよ実際にアプリを起動していきます。
Docker起動
まずはDockerの起動です。
$ xhost +
$ docker-compose up
xhost +
でコンテナからホスト側のX11へのアクセスを許可しています。
セキュリティゆるめなので、作業終了後はxhost -
で許可を取り消しておくといいかと思います。
docker-compose up
実行後、Xeyesが起動して目玉がぎょろぎょろしてたら成功です。
かわいい。
KHCoder起動
続いて立ち上げたDockerコンテナに入り、その中でKHCoderを立ち上げます。
$ docker exec -it nl2e_nl2e_1 /bin/bash
コンテナに入れたら、KHCoderの起動スクリプトを実行します。
$ cd /KHCoder/khcoder/
$ /usr/bin/perl ./kh_coder.pl
無事KHCoderが起動したら、これで準備完了です🎉
お疲れさまでした。
(3) チュートリアルを試す
というわけでさっそくちゃんと使えるかチュートリアルをやってみます。
ここは元記事で紹介されているものと同じです。
サンプルファイル用意
※ホスト側での作業です
$ mkdir KHCoder/works
$ cd KHCoder/works
$ wget https://khcoder.net/tutorial_data_3x.zip
$ unzip -x tutorial_data_3x.zip
テストファイルの読み込み
KHCoderのアプリで、プロジェクト
>新規
を選択し、分析対象ファイルとして/KHCoder/works/tutorial_jp/kokoro.xls
を選択。
デフォルトでChasen
になってるのをMecab
に変更して、「OK」をクリック。
前処理する
前処理
>前処理の実行
だいぶ時間がかかります。
結果を表示してみる
ツール
>抽出語
>共起ネットワーク
を選んでグラフ描画すると、それっぽい結果が表示されました。
やったね。
🚨 トラブルシューティング
この環境でKHCoderを使う際は、常に以下の状態にしておく必要があります。
- XQuartzを起動しておく
- xhostのアクセスを許可しておく
- Dockerを起動しておく
一度成功してもしばらく経ってから再度使うときはどれかが準備できてなかったりするので、以下のようなエラーが出たら再度起動状況を確認してみてください。
💩 Error: No such container
$ docker exec -it nl2e_nl2e_1 /bin/bash
$ => Error: No such container: nl2e_nl2e_1
コンテナ名が一致していない。
このエラーが出る場合はコンテナ名のアンスコをハイフンに変えてあげてください。
nl2e-nl2e-1
みたいな感じ。
💩 Error response from daemon: Container xxxx is not running
$ docker exec -it nl2e-nl2e-1 /bin/bash
$ => Error response from daemon: Container xxxx is not running
こんなエラーが出るときは、コンテナが動いてないです。
docker-compose up
し忘れた(してたのを止めちゃった)という場合は、もう一度Dockerを起動してください。
それでも直らない場合は次の項目を参照。
💩 Error: Can't open display: host.docker.internal:0
Dockerを起動してる画面で、よく見たらこんなエラーが出てる場合。
$ docker-compose up
$ =>...
$ => nl2e-nl2e-1 | Error: Can't open display: host.docker.internal:0
$ => nl2e-nl2e-1 exited with code 1
nl2eコンテナの起動に失敗しています。
一番ありがちな原因は、XQuartzが起動していないことなので、一度docker-compose down
で止めて、XQuartzを起動してから再度upしてください。
それでもだめなときはxhostの許可ができてないかもなので、もう1回許可してあげたらどうですかね。
$ xhost +
(参考)修正した箇所の備忘メモ
環境変数$DISPLAYの修正
オリジナルでは環境変数DISPLAYにホスト側の$DISPLAYを指定していたのですが、手元ではこれでは動かず。
environment:
DISPLAY: $DISPLAY
※ホスト側の$DISPLAYにはこんな感じ↓で値が入ってました。
$ echo $DISPLAY
$ => /private/tmp/com.apple.launchd.xxxx/org.xquartz:0
とりあえず192.168.0.1:0
みたいにホストのIPアドレスを指定すれば動いたのですが、これだとIPが変わるたびに設定が必要になるので避けたい。
と思って調べてたら、host.docker.internal
でホストのプライベートIPアドレスにアクセスできるらしい。
というわけでこっちを使うように変えてみました。
environment:
DISPLAY: host.docker.internal:0
コンテナのIPアドレスを固定する
coder.ini
でmysqlコンテナのIPアドレスなどを設定する必要があるんですが、毎回調べて設定するのは大変なので、コンテナのIPを固定するようにしました。
services:
nl2e:
...
networks:
nl2e_net:
ipv4_address: '171.20.0.2'
mysql:
...
networks:
nl2e_net:
ipv4_address: '171.20.0.3'
networks:
nl2e_net:
driver: bridge
ipam:
driver: default
config:
- subnet: 171.20.0.0/24
IPは固定したことで、あらかじめ用意しておいたファイルで上書きすればよくなったので、設定のためにKHCoderを再起動したりするプロセスをスキップできました。
(ほんとはファイルコピー自体もDockerのcommandに入れておいたらなおよさそうだけど)
ついでにnetwork_mode: "host"
の設定もなくしています。
my.cnfにlocal-infileの設定を追加
途中までうまくいってたときに、いざファイルを読み込もうとするとエラーが出てしまった。
Loading local data is disabled; this must be enabled on both the client and server sides
MySQL8.0からセキュリティが厳しくなったせいみたい。
元記事でも対応されていてmy.cnf
(リネームしました)に設定されているんだけど、クライアント・サーバ両方に設定が必要とのことで、サーバ側の設定がなくてエラーになっていたっぽい。
なのでサーバ側にも同じ設定を追加。
[client]
loose-local-infile=1
[mysqld]
loose-local-infile=1 # ここを追加
default_authentication_plugin=mysql_native_password
デバッグ方法
nl2eのコンテナからmysqlに接続して、local_infile
が設定されてるか確認。
mysql> SHOW GLOBAL VARIABLES LIKE 'local_infile';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile | ON |
+---------------+-------+
1 row in set (0.08 sec)
ちゃんとON
になってればOK。
感想
疲れました。
Discussion