🤷‍♀️

KH CoderをDocker for Macで動かす手順

2022/06/11に公開

KH CoderをMacのDockerで動かす手順です。
以下の神記事をほぼ全面的に参照させていただき、手元で動かなかった部分を直したり手作業が発生していた部分を減らすように修正したりしています。

https://qiita.com/ryos36/items/9802b5da6d80d8d73eb5

↑この記事がなければとても設定まで行きつけませんでした。。。ありがとうございます🙇

(0) 事前準備

開発環境の準備です。
すでにインストール済みの方はスキップしてください。

Dockerインストール

仮想環境作ってくれるやつ。以下公式サイトの手順に沿ってインストールして起動しておいてください。
https://matsuand.github.io/docs.docker.jp.onthefly/desktop/mac/install/

homebrewインストール

Macのパッケージ管理システム。以下の公式サイトに記載されているスクリプトをコンソール(ターミナル)で実行してください。

Mac
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

https://brew.sh/index_ja

(1) 各種セットアップ(初回のみ)

XQuartzインストール

ここからが本番です。まずはコンテナのGUIアプリを表示するためのXQuartz(X11)をインストールします。

Mac
$ brew install xquartz

上記インストール完了後、XQuartzを起動して、メニューの環境設定 > セキュリティ から ネットワーク・クライアントからの接続を許可 にチェックをつける。

設定を保存したあと、一度Macからログアウトしてログインしなおす。

ログイン後、環境変数$DISPLAYに値が入っていることを確認。

Mac
$ echo $DISPLAY
=> /private/tmp/com.apple.launchd.qeR8i7Bf4G/org.macosforge.xquartz:0

↑こんな感じで出力されればOK。

参考

https://obataka.com/docker-gui-firefox/
https://qiita.com/loftkun/items/37340745f211ea5d7ece

KH Coderインストール

Githubからリポジトリをclone

元記事のリポジトリをforkして修正したものを公開しているので、まずはそれをcloneしてきます。

Mac
$ git clone git@github.com:notsobad-jp/NL2E.git
$ cd NL2E

https://github.com/notsobad-jp/nl2e

KH Coderをインストール

リポジトリにsubmoduleとしてKHCoderが入っているので、それをupdateします。

Mac
$ git submodule init
$ git submodule update

設定ファイルをコピー

KHCoderの設定ファイルcoder.iniにMySQL接続情報などを設定する必要があるので、あらかじめ用意しておいたファイルをコピーしておきます。

Mac
$ cp coder.ini KHCoder/khcoder/config/coder.ini

(2) アプリケーションの起動

ここまでセットアップが完了したら、いよいよ実際にアプリを起動していきます。

Docker起動

まずはDockerの起動です。

Mac
$ xhost +
$ docker-compose up

xhost +でコンテナからホスト側のX11へのアクセスを許可しています。
セキュリティゆるめなので、作業終了後はxhost -で許可を取り消しておくといいかと思います。

docker-compose up実行後、Xeyesが起動して目玉がぎょろぎょろしてたら成功です。

かわいい。

KHCoder起動

続いて立ち上げたDockerコンテナに入り、その中でKHCoderを立ち上げます。

Mac
$ docker exec -it nl2e_nl2e_1 /bin/bash

コンテナに入れたら、KHCoderの起動スクリプトを実行します。

Docker
$ cd /KHCoder/khcoder/
$ /usr/bin/perl ./kh_coder.pl

無事KHCoderが起動したら、これで準備完了です🎉
お疲れさまでした。

(3) チュートリアルを試す

というわけでさっそくちゃんと使えるかチュートリアルをやってみます。
ここは元記事で紹介されているものと同じです。

https://qiita.com/ryos36/items/9802b5da6d80d8d73eb5#チュートリアルを試す

サンプルファイル用意

※ホスト側での作業です

Mac
$ 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を指定していたのですが、手元ではこれでは動かず。

docker-compose.yml
environment:
    DISPLAY: $DISPLAY

※ホスト側の$DISPLAYにはこんな感じ↓で値が入ってました。

Mac
$ echo $DISPLAY
$ => /private/tmp/com.apple.launchd.xxxx/org.xquartz:0

とりあえず192.168.0.1:0みたいにホストのIPアドレスを指定すれば動いたのですが、これだとIPが変わるたびに設定が必要になるので避けたい。

と思って調べてたら、host.docker.internalでホストのプライベートIPアドレスにアクセスできるらしい。
https://docs.docker.com/desktop/mac/networking/#use-cases-and-workarounds

というわけでこっちを使うように変えてみました。

docker-compose.yml
environment:
    DISPLAY: host.docker.internal:0

コンテナのIPアドレスを固定する

coder.iniでmysqlコンテナのIPアドレスなどを設定する必要があるんですが、毎回調べて設定するのは大変なので、コンテナのIPを固定するようにしました。

docker-compose.yml
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(リネームしました)に設定されているんだけど、クライアント・サーバ両方に設定が必要とのことで、サーバ側の設定がなくてエラーになっていたっぽい。

https://mita2db.hateblo.jp/entry/2020/01/13/163218

なのでサーバ側にも同じ設定を追加。

my.cnf
[client]
loose-local-infile=1

[mysqld]
loose-local-infile=1 # ここを追加
default_authentication_plugin=mysql_native_password
デバッグ方法

nl2eのコンテナからmysqlに接続して、local_infileが設定されてるか確認。

Docker
mysql> SHOW GLOBAL VARIABLES LIKE 'local_infile';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| local_infile  | ON    |
+---------------+-------+
1 row in set (0.08 sec)

ちゃんとONになってればOK。

感想

疲れました。

Discussion