LoginSignup
1
3

More than 3 years have passed since last update.

OpenGrok+Dockerで、ダウンタイムがほぼ無いソース検索を作る

Last updated at Posted at 2019-09-09

まえおき

OpenGrok+Dockerで、使い捨てソース検索エンジンをつくる
https://qiita.com/YusukeIwaki/items/3f855202e9c00247d5c7

OpenGrokの公式Dockerイメージでソース検索サーバーを立てる
https://qiita.com/YusukeIwaki/items/ccf7dab6b1a284bbff26

と、Docker+OpenGrokでのソース検索サーバを建てるネタは放出してきたんだけども、
実のところ今までのソース検索は「30分に1度、インデックス再構築のために、4分くらいダウンタイムが発生する」という、大きな欠点があったことは伝えていなかった。

自分用のソース検索だったらそれでよかったんだけど、周りに使ってもらい始めると、30分に1回「なんかおかしいんですけど」って言われるリスクと戦わないといけないので、いい加減対処しようってなった。
ということで、今回はその欠点を解決した版を紹介しようと思う。

なぜダウンタイムが発生するのか

雑に絵で説明しよう。理由は2つある。

いままでの構成はこう。ソースコードはホスト側にあって、それをbindfsでDocker側にマウントする&Docker側でインデックスが保持される。

Slice.png

これだと、ソースコードを最新化するタイミングでまずインデックスと実ソースが微妙に不整合な状態になる。「検索結果には出てくるのに、実際に見に行くと最新ソースでは消されていたのでなくなっていた」みたいなことが起きる。

Slice.png

そんで、次に最大の問題であるダウンタイムが発生する。まだ出来上がってないインデックスを外からHTTPでアクセスしに来ちゃうからだ。
Slice.png

Dockerらしく、裏でインデックス作って、できあがったら差し替えればいいじゃない?

ソースコードも全部コンテナに押し込めてしまえば、
Slice.png

こんな感じで、裏でdocker buildしておいて、インデックス生成までdocker buildでやってしまって
Slice.png

イメージのビルドが終わったら、あとは好きなタイミングで、古いコンテナをstopして新しいコンテナをrunすれば、せいぜい2〜3秒程度のダウンタイムで済むんじゃないか?という発想。
Slice.png

公式Dockerイメージでは無理である

Oracle公式のopengrokのイメージは、docker runしたタイミングで初めてインデックス生成が行われる。
先に書いたように、HTTPを受け付けるにもかかわらずインデックスが出来上がってない状態、みたいなのが少なからずできてしまうので、これをそのまま使うことはできない。

仕方がないので、自前で用意することにした。
https://github.com/YusukeIwaki/docker-opengrok-alpine

https://github.com/oracle/opengrok/wiki/How-to-setup-OpenGrok の手順を参考にしつつ、
公式OpenGrokイメージの https://github.com/oracle/opengrok/blob/master/Dockerfilehttps://github.com/oracle/opengrok/tree/master/docker を斜め読みして作成した。
Alpine Linuxの apk add --no-cache ctags だとuniversal-ctagsじゃなくて古いほうのctagsが入るので、universal-ctagsを自前でビルドしないといけないのが微妙に厄介。
他は割とすんなり理解できるだろう。

裏でイメージをビルドする君をつくる

イメージのビルドスクリプトは、

  • 最新のdevelopブランチでも変更がないなら、全部キャッシュを効かせたい
  • 最新のdevelopブランチが変更されているなら、git cloneの直前まではキャッシュを効かせ、それ以降はビルドしたい

のようにする。

Dockerfileでgit clone を使う際にキャッシュをADDで回避
https://qiita.com/sawanoboly/items/ac559c43b9662304931a

で書かれているように、ADDでorigin/developのコミットハッシュを書いたファイルをコンテナに送り込むといい。
GitHub APIを使うでもいいし、

git ls-remote git@bitbucket.org:YusukeIwaki/some_repository.git refs/heads/develop | cut -f1 > origin_develop.sha1.txt

みたいな感じで愚直にファイルを作るでもいいと思う。

ビルド自体は、シンプルに docker build -t some-source-search . するだけ。

コンテナを差し替える君をつくる

雑だが、

docker ps | grep "0.0.0.0:8080" | cut -f1 -d' ' | xargs --no-run-if-empty docker stop | xargs --no-run-if-empty docker rm
docker run -d -p 8080:8080 some-source-search

こんな感じでいける。

Rundeckでジョブ管理すると楽

  • docker buildが終わり次第、コンテナの差し替えを行う
  • 日中のインデックス更新は30分に1回おこなう
  • ログは3日間分くらいは残しておきたい

などなど、cronで管理するのはいやなので、Rundeckにまかせてしまう。
https://www.rundeck.com/open-source

セットアップ方法は、ぐぐればでてくるので省略。

まとめ

切り替えは雑ですが、イミュータブルデプロイみたいなかんじの構成にすることで、かなり快適にソース検索ができるようになります。

公式OpenGrokイメージが似たようなDockerfileを提供してくれたら、もっとみんな幸せになるんじゃないかなぁ...。

1
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
3