みなさん、こんにちは。
以前、Linux環境でKH Coderを動かす記事を書きました。
前回は「ひとまずDockerでKH Coderを立ち上げる」ところまでをご紹介しました。
ただ、前回のガイドだと初回と2回目以降で起動手順が違っていたり、cpan install File::Copy::Recursive を手動で実行する必要があったり、do.sh のコンテナ名を書き換えたり……と、何かと手間が多かったんですよね。
最近、質的研究でKH Coderを何度も立ち上げる機会があったのですが、毎回この作業をするのがさすがにおっくうになってきました。そこで今後のためにも「もっとラクにならないか?」と思い、 Copilotに相談してみました!
Copilotとの相談で見えてきた改善案
相談してみた結果、面倒くささの根本原因は「初回セットアップ作業」と「普段の運用作業」がごちゃ混ぜになっていることだと整理できました。
そこで出てきた改善案がこちらです。
- 起動用と停止用のシェルスクリプトを作る
File::Copy::RecursiveをDockerfileに組み込んでcpan installを不要にする(本来はこちらが正攻法ですね!)- デスクトップランチャーを作って、アプリ一覧から起動できるようにする
- コンテナを常時起動したままにして、KH Coderだけを起動する
- 記事自体を「初回セットアップ編」と「普段の起動編」に分ける
さらに、修正版の Dockerfile と docker-compose.yml も提案してもらったので、この方向性をベースに進めることにしました。作業にあたり、本家リポジトリをForkして修正を反映していきます。
……が!実際に動かしてみると、相談時点では見えていなかったトラブルが次々と浮上してきました(笑)。
ここからは Claude Code を相棒にして本格的なデバッグを開始!今回はその試行錯誤のプロセスを詳しくまとめました。
※今回の修正内容はすべて GitHubリポジトリ (taoman26/NL2E) に反映済みです。
「説明はいいから早く使いたい!」という方へ
前提として Docker と Docker Compose V2 が必要です。Ubuntu 26.04 でDockerがインストール済みであれば Docker Compose V2 を追加インストールする必要はないのですが、 Ubuntu 22.04 の場合、以下のコマンドでセットアップが必要でした。
sudo apt install docker-compose-v2
あとは、次のコマンドを順番に実行するだけでOKです!
git clone https://github.com/taoman26/NL2E.git
cd NL2E
git submodule update --init --recursive
docker compose build
./do.sh
※初回の docker compose build はRのパッケージをソースからビルドするため、お使いの環境によっては数十分ほどかかります。2回目以降は ./do.sh だけでサクッと起動できますよ!
今回の修正内容まとめ
ハマったポイントと対処法を一覧にまとめました。
| 症状 | 原因 | 対処法 |
| 手順が多く、初回と2回目で操作が違う | File::Copy::Recursive を手動導入していた | Dockerfile に組み込み |
docker compose build がエラーになる | ビルド指定先に Dockerfile がない | docker-compose.yml の build パスを修正 |
| 毎回、起動と停止のコマンドを打つのが面倒 | 手順が自動化されていない | do.sh で一連の流れを自動化 |
| ローカルのファイルが開けない | コンテナ内のファイルしか見えない | ホストのディレクトリをマウント |
| 日本語ファイル名が文字化けする | コンテナのロケールが未設定 | LANG / LC_ALL を設定 |
| コンテナの時刻がUTCになっている | タイムゾーンが未設定 | ホストの時刻設定をマウント |
共起ネットワークで ggnetwork がないと言われる | R 3.6 では最新CRANから入らない | 過去のCRANスナップショットから導入 |
1. docker compose build のエラーを直す
まず、Copilotに提案された手順どおりに docker compose build を実行してみたところ、いきなりエラーで止まってしまいました。
failed to read dockerfile: open Dockerfile: no such file or directory
原因はCopilotが提案した docker-compose.yml の build: . という指定です。リポジトリ直下には Dockerfile がなく、実際は Docker/nl2e/ の下に配置されていたためでした。
そこで、以下のようにビルド先を正しいパスへ修正します。
nl2e:
build: ./Docker/nl2e
あわせて、Docker Compose V2 も必須となるので、Xubuntu 22.04 を使っている私は以下でインストールしました。
sudo apt install docker-compose-v2
2. do.sh で起動から停止までを一括自動化!
Copilotから出ていた「起動スクリプト作成」のアイデアを発展させて、アプリの停止まで全自動で行う仕組みにアップデートしました。
「コンテナを起動して、KH Coderを立ち上げて、使い終わったらコンテナを止めて……」という手動の繰り返しは地味にストレスですよね。そこで do.sh を書き換え、以下のフローをワンアクションで実行できるようにしました!
xhost +local:dockerでX11画面出力を許可docker compose up -dでコンテナを起動- MySQLの起動完了を待ち、初回のみ
khcoderデータベースを作成 - KH Coderを起動
- KH Coderを終了したら、自動的に
docker compose downでコンテナを停止
実行コマンドはこれだけです!
./do.sh
スクリプト内に trap 処理を仕込んでいるため、もし途中で Ctrl+C を押して強制終了した場合でも、コンテナが残らずキレイに停止してくれます。データベース作成もチェック処理を入れているので、2回目以降の起動時も安心です。
3. ローカル(ホスト側)のファイルを開けるようにする
初期状態だと、KH Coderのファイル選択ダイアログにはコンテナ内のファイルシステムしか表示されず、ホスト側にある分析データを読み込むことができません。
そこで、ホストのホームディレクトリをコンテナ内の /host にマウントするように設定を追加しました。
volumes:
- ${NL2E_DATA_DIR:-${HOME}}:/host
これでファイル選択画面から /host を開けば、ローカルのファイルを自在に読み書きできるようになります!
(例: ホストの ~/data/sample.xlsx は、コンテナから /host/data/sample.xlsx としてアクセスできます)
もし別のディレクトリを割り当てたい場合は、環境変数を指定して実行すればOKです。
NL2E_DATA_DIR=/path/to/data ./do.sh
※注意点として、コンテナがroot権限で動くため、KH Coder側からマウント先に新規作成・保存したファイルの所有者は root になります。必要に応じて chown などで所有権を調整してください。
4. 日本語ファイル名の文字化けを解消する
/host 経由でファイルを開こうとすると、日本語のファイル名が文字化けしてしまう問題が発生しました。
調査してみると、コンテナ内の LANG 環境変数が空で、ロケールが POSIX になっていました。元々の Dockerfile には update-locale LANG=ja_JP.UTF-8 という記述がありましたが、これは /etc/default/locale を書き換えるだけで、実行中プロセスの環境変数までは反映してくれません。
そこで Dockerfile に直接環境変数を追加して解決しました!
ENV LANG=ja_JP.UTF-8
ENV LC_ALL=ja_JP.UTF-8
日本語ロケール(ja_JP.utf8)自体はイメージ内にすでに含まれていたため、追加のパッケージ更新なしでスッキリ直せました。
5. コンテナの時刻をホスト(JST)に合わせる
コンテナ内の時刻がデフォルトの「UTC(協定世界時)」になっていたため、ホスト側のタイムゾーン設定を読み取り専用(ro)でマウントしました。
volumes:
- /etc/localtime:/etc/localtime:ro
- /etc/timezone:/etc/timezone:ro
コンテナ内で date コマンドを実行し、ホストと同じJST(日本標準時)で表示されることを確認!
イメージの再ビルドは不要で、コンテナを再起動するだけで即座に反映されます。(※なお、今回MySQL側のコンテナ設定は変更していません)
6. 共起ネットワークが描画できない(ggnetwork 不足)問題を解決
テキスト分析で大活躍する「共起ネットワーク」を表示しようとしたところ、ggnetwork が入っていないというエラーが出て描画できませんでした。
発生した原因
ベースイメージに含まれている R のバージョンが 3.6.3 と少し古めです。最新のCRANから ggnetwork を入れようとすると、依存関係にある statnet.common が R 3.6 に対応していないため、network → sna → ggnetwork と連鎖的にインストールが失敗していました。
しかも厄介なことに、Rの install.packages は失敗しても警告(Warning)を出すだけで処理が止まりません。そのため docker compose build 自体は正常終了してしまい、ビルド時にはエラーに気づけないという落とし穴がありました……!
対処法
2020年6月1日時点のCRANスナップショット(Posit Package Managerで公開されている過去アーカイブ)を指定してインストールするように変更したところ、無事に ggnetwork 0.5.8 が導入できました!
RUN Rscript -e 'install.packages("ggnetwork", repos = "https://packagemanager.posit.co/cran/2020-06-01")'
あわせてKH Coderのソースコードを洗い出し、不足していた以下のRパッケージも同じスナップショットからまとめて導入しています。
smacof(多次元尺度構成法)networkD3devEMFRSVGTipsDeviceldatuning
※ ldatuning のビルドには C言語のライブラリが必要だったため、apt のパッケージ指定に libgmp-dev と libmpfr-dev を追加しています。
さらに、今後同じような「サイレント失敗」を見逃さないよう、Dockerfile の最後にライブラリの読み込み確認を入れました!これで必要なパッケージが1つでも欠けていれば、ビルドがその場でしっかり止まってくれます。
RUN Rscript -e 'for (p in c("ggnetwork", "smacof", "networkD3", "devEMF", "RSVGTipsDevice", "ldatuning", "som", "topicmodels", "ggplot2")) library(p, character.only = TRUE)'
apt の層から再ビルドになるため時間は少々かかりますが、これで安心して使える環境が整いました。
既存環境の更新方法
今回の修正はすべてForkしたリポジトリにマージ済みです!すでに以前の環境を作成されている方は、リポジトリを更新してイメージを作り直してみてください。
git pull
docker compose build
ビルドが終われば、あとは ./do.sh を実行するだけで快適にお使いいただけます!
Linux環境でも使いやすいKH Coderを
今回は、Docker版KH Coderを実際に運用する中で直面した不便さやエラーを、以下のステップで1つずつ解消していきました。
File::Copy::RecursiveをDockerfileに組み込み、手動のcpan installを撤廃- ビルド先のパスを修正して
docker compose buildを正常化 do.shで起動から終了・コンテナ停止までをワンコマンドで自動化- ホストのディレクトリをマウントし、ローカルの分析データを開けるように改善
- ロケールを設定し、日本語ファイル名の文字化けを防止
- コンテナの時刻をホスト(JST)と同期
- 過去のCRANスナップショットを活用し、共起ネットワーク等の描画機能を復活
特に「install.packages の失敗がビルドエラーにならず見落とされる問題」は、DockerfileでR環境を構築する際にハマりやすいポイントです。ビルドの最終ステップに library() での読み込みチェックを入れておくのがおすすめです!
Linux環境で質的研究やテキストマイニングに取り組みたい方は、ぜひ試してみてください。
リポジトリ:taoman26/NL2E
本日も最後までお読みいただきありがとうございました。
それでは、よいテキストマイニングライフを!
今回のような技術検証、「うちではどうなんだろう?」と気になった方はいませんか。
ビューローみかみでは、構想段階の壁打ちからPoC・実装・現場導入まで、現場で「使い続けられる」ものづくりを支援しています。
技術顧問サービスでは、本記事のような技術的な質問・検証にも継続的にお答えしています。「相談したら契約」ということはありません。システムを作らない判断も含めて、率直にお話しします。
▶ 技術顧問サービスの詳細はこちら
気になることがあればお気軽にご相談ください。



