はじめに
ドキュメントをMarkdownで書く文化が浸透していれば全文検索可能なドキュメントサーバを構築するのはさほど困難ではないであろう。
が、問題はそうでないことである。
技術者ならMarkdownを使うかと思いたいが同僚やお付き合いのあるシステムベンダーを見てもそんな人は皆無に等しくほぼワードやエクセル、PDFという形でアウトプットしてくる。
そういう場合に布教活動を行うのも手だがMS Office文書などが取り扱えるサービスが構築できるならそのほうが手っ取り早いし皆に喜んでもらえる。
オンプレで構築するオンラインストレージサーバとしてはNextcloudが有名でオフィス文書を扱うためにOnlyOfficeと組み合わせたり、全文検索するためにElasticSearchを導入する方法は紹介されているものの、いかんせん情報が細切れだったり古かったりして簡単には動かなかった。
そこで公式イメージを元にゴニョゴニョしたらなんとかできたので紹介したい。
セットアップ
Nextcloudのインストール
上記レポジトリからクローン
git clone https://github.com/higebobo/docker-nextcloud.git
データベースサーバの接続情報などは.envを作成・編集して変更できるがそのままデフォルト情報(Makefileの冒頭に記述)でビルドできる。
(GNU Makeが使えない場合はMakefileのタスクを参照してコマンドラインから実行すればよい)
make up
しばらくすると完了するのでブラウザでNextcloudにアクセスする(デフォルトではhttp://localhost:8080)
ユーザ名やパスワードは適当に入力して「ストレージとデータベース」をクリック
環境変数で設定したデータベースの情報を入力。最後のホストのところはlocalhost
とか入れずにdb
とすること(docker-composeで指定したデータベースのサービス名)。
次にアプリをインストールする。
「推奨アプリをインストール」をクリックしてしばらく待つと完了。
OnlyOfficeの設定
Nextcloudのインストールが完了したのでOnlyOfficeの設定を行う。
ダッシュボードからやってもできるのだろうが、公式イメージで提供されているスクリプトを利用(Makefileのタスク参照)。
make onlyoffice
出力結果
+ docker exec -u www-data app-server php occ --no-warnings config:system:get trusted_domains
+ grep -q nginx trusted_domain.tmp
+ cat trusted_domain.tmp
+ wc -l
+ TRUSTED_INDEX=1
+ docker exec -u www-data app-server php occ --no-warnings config:system:set trusted_domains 1 --value=nginx
System config value trusted_domains => 1 set to string nginx
+ rm trusted_domain.tmp
+ docker exec -u www-data app-server php occ --no-warnings app:install onlyoffice
onlyoffice 7.3.0 installed
onlyoffice enabled
+ docker exec -u www-data app-server php occ --no-warnings config:system:set onlyoffice DocumentServerUrl --value=/ds-vpath/
System config value onlyoffice => DocumentServerUrl set to string /ds-vpath/
+ docker exec -u www-data app-server php occ --no-warnings config:system:set onlyoffice DocumentServerInternalUrl --value=http://onlyoffice-document-server/
System config value onlyoffice => DocumentServerInternalUrl set to string http://onlyoffice-document-server/
+ docker exec -u www-data app-server php occ --no-warnings config:system:set onlyoffice StorageUrl --value=http://nginx/
System config value onlyoffice => StorageUrl set to string http://nginx/
+ docker exec -u www-data app-server php occ --no-warnings config:system:set allow_local_remote_servers --value=true
System config value allow_local_remote_servers set to string true
管理画面からOnlyOfficeの設定が確認できる。
全文検索の設定
ダッシュボード>アプリからFull Text
を検索
以下を組み込む
- Full text search
- Full text search - Elasticsearch Platform
- Full text search - Files
ダッシュボード>設定から「全文検索」の設定画面を表示
以下を設定
- 検索プラットフォーム: Elasticsearch
- サーブレットのアドレス: http://elasticsearch:9200/
- インデックス: nextclud(任意の名称)
- アナライザトークナイザ: kuromoji_tokenizer
検索インデックスの作成
make index
出力結果
Options: []
Memory:
┌─ Indexing ────
│ Action:
│ Provider: Account:
│ Document:
│ Info:
│ Title:
Options: []
...略
┌─ Results ────
│ Result: 30/30
│ Index: files:18
│ Status: ok
│ Message: {"_index":"nextcloud","_type":"_doc","_id":"files:18","_version":1,
│ "result":"created","_shards":{"total":2,"successful":1,"failed":0},"_seq_no":
│ 29,"_primary_term":1}
└──
┌─ Errors ────
│ Error: 0/0
│ Index:
│ Exception:
│ Message:
│
│
└──
## x:first result ## c/v:prec/next result ## b:last result
## f:first error ## h/j:prec/next error ## d:delete error ## l:last error
## q:quit ## p:pause
エラーが0/0となっているので成功しているが最初ここが30/30とかになってうまく行かなかった。
その場合は
make index-init
とか
make index-reset
とかすると幸せになれるかもしれない。
なお、インデックスの作成は文書の登録のたびに実行する必要があるのでバッチで組み込むなどして定期実行するようにする。
動作確認
右上の検索アイコンからself-hosted
と入力してみる(なぜこのキーワードなのかは後述)。
そしてこちらが編集可能の画面
今回の例としては初期に組み込まれている文書から検索したが、日本語の検索ももちろんできる。
試しに「レンタル」という文字が入力されているエクセル文書をアップロードしてインデックス作成後に検索すると正しく検索できている。
なお、オフィス文書を表示するときに「ONLYOFFICEに接続できません。管理者に相談してください」と出る場合はonlyoffice-server
の起動に時間がかかっているのでしばらく待って再度アクセスする。
最後に
docker-composeを利用することで複数のサービス(Nginx/Nextcloud(PHP)/Mariadb/OnlyOffice/ElasticSearch/Kibana)のインストールが一発でできるのがこの上なく便利であるし移植性も高い。
以前はこういうのを一つ一つインストール・設定(さらに動作確認)していたので新規に構築するときやサーバを更新・移転する場合など極めて気が重くなる作業だった。
最後にdocker-compose.yamlを掲載しておく。
私は極力ポートは開けないし、今回はkibanaも重たくなるので利用しないのでコメントアウトしているが好みに応じて活用してもらえればよいかと思う。
version: "3.7"
services:
app:
image: nextcloud:23.0-fpm-alpine
container_name: ${APP_CONTAINER}
restart: always
environment:
- extra_params="--o:ssl.enable=false"
depends_on:
- db
- onlyoffice-document-server
- elasticsearch
volumes:
- "$PWD/data/web:/var/www/html"
db:
image: mariadb:10.7-focal
container_name: ${DB_CONTAINER}
command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW --innodb-file-per-table=1 --skip-innodb-read-only-compressed
restart: always
volumes:
- "$PWD/data/db:/var/lib/mysql"
#ports:
# - ${MYSQL_PORT}:3306
environment:
MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD}
MYSQL_PASSWORD: ${MYSQL_PASSWORD}
MYSQL_DATABASE: ${MYSQL_DATABASE}
MYSQL_USER: ${MYSQL_USER}
onlyoffice-document-server:
image: onlyoffice/documentserver:7.0
container_name: ${DOC_CONTAINER}
restart: always
volumes:
- "$PWD/data/log/onlyoffice:/var/log/onlyoffice"
- "$PWD/data/onlyoffice:/var/www/onlyoffice/Data"
nginx:
image: nginx:1.21
container_name: ${WEB_CONTAINER}
restart: always
ports:
- "${WEB_PORT}:80"
#- "${SSL_PORT}:443"
volumes:
- "$PWD/config/nginx.conf:/etc/nginx/nginx.conf"
- "$PWD/data/web:/var/www/html"
elasticsearch:
build: ./elasticsearch
container_name: ${SEARCH_CONTAINER}
restart: always
environment:
- discovery.type=single-node
# ports:
# - "${SEARCH_PORT}:9200"
# #- "${ELASTICSEARCH_NODE_PORT}:9300"
# kibana:
# image: docker.elastic.co/kibana/kibana:7.17.0
# container_name: ${MONITOR_CONTAINER}
# restart: always
# depends_on:
# - "elasticsearch"
# ports:
# - "${MONITOR_PORT}:5601"
elasticsearch/Dockerfile (kibanaを使う場合はelasticsearchとバージョンは合わせること)
FROM docker.elastic.co/elasticsearch/elasticsearch:7.17.0
RUN elasticsearch-plugin install --batch ingest-attachment &&\
elasticsearch-plugin install --batch analysis-kuromoji &&\
elasticsearch-plugin install --batch analysis-icu