はじめに
最近、ちまちまとdiscord上で動くchatbotを作っているのですが、やっぱり公開サーバーで動かさないと日常的に使えないのでHerokuにデプロイすることにしました。
ただ、無料枠のHerokuで動かそうとするといろいろと解決しないといけない課題が多くてひたすら逃げていたのですが、ようやく重い腰を上げてデプロイしたので、手順をメモがてら残してみたいと思います。
必要な要件
- python (3.5以上)
- mecab+mecab-ipadic
- FFmpeg
- open-jtalk
を使っているのでこれらが動かせる環境が必要。
Herokuでpython+mecabの環境づくりは下記の記事を参考にしました。
herokuでpython+django+scikit-learn+mecab(1)
ffmpegの環境づくりはこちらを参考にしました。
DiscordBotでyoutubeの音声をボイスチャットに流す
いざ、構築
condaとherokuの複数のビルドパックを使うのでheroku-buildpack-multiでアプリを作成する必要があります。気になるのはこのリポジトリがメンテナンスを終了していることでしょうか。
This buildpack is no longer actively maintained. The associated functionality exists natively on the Heroku platform. Please refer to https://devcenter.heroku.com/articles/buildpacks and https://devcenter.heroku.com/articles/using-multiple-buildpacks-for-an-app for documentation.
まず、ローカルでリポジトリを作ります。
$ git init
$ heroku create --buildpack https://github.com/heroku/heroku-buildpack-multi
使用するビルドパックは以下の通りです。
https://github.com/Sashimimochi/conda-buildpack.git
https://github.com/sunny4381/heroku-buildpack-linuxbrew.git
https://github.com/jonathanong/heroku-buildpack-ffmpeg-latest.git
https://github.com/Crazycatz00/heroku-buildpack-libopus.git
scikit-learn
などのCコンパイラを必要とするライブラリも使いたいのでcondaのビルドパックがいるのですが、pythonのバージョンを固定したいので以下のリポジトリをforkして自前で用意することにしました。
https://elements.heroku.com/buildpacks/teamupstart/conda-buildpack
minicondaのバージョン一覧はこちらから見れます。
https://repo.continuum.io/miniconda/
ちなみに、ものによっては、以下のような最近のpipでは廃止されたオプションが付いていてビルドエラーを起こすので注意。
pip install -r requirements.txt --exists-action=w --allow-all-external | indent
- https://github.com/heroku-python/conda-buildpack/issues/36
- https://stackoverflow.com/questions/57546079/no-such-option-allow-all-external-when-deploying-a-django-app-to-heroku-wit
上記の.buildpacks
でheroku-buildpack-linuxbrew
を入れたのでbrew
が使えるようになっています。brew
で入れたいパッケージを.cellar
で指定します。
mecab
mecab-ipadic
open-jtalk
conda
およびpip
でインストールするライブラリはconda-requirements.txt
やrequirements.txt
に書いておきます。
Herokuにmecab-pythonをインストールしようとすると案の定、エラーが出ました。
herokuでpython+django+scikit-learn+mecab(1)では手動でインストールしていましたが、今回は、python3系を使うわけですし、mecab-python3ならはいったので、代わりにこちらを入れます。
Heroku mecabインストール時にエラー
あとはパスを指定してデプロイします。
$ heroku config:add LD_LIBRARY_PATH=/app/.linuxbrew/lib
$ heroku config:set MECAB_PATH=/app/.linuxbrew/lib/libmecab.so
$ git add .
$ git commit -m 'initial'
$ git push heroku master
滞りなく、一連のデプロイが進んで無事うまくいったように思えたのですが、最後のメッセージであえなく撃沈。
-----> Compressing...
! Compiled slug size: 3009.8M is too large (max is 500M).
! See: http://devcenter.heroku.com/articles/slug-size
! Push failed
https://devcenter.heroku.com/articles/slug-compiler#slug-size
上記のメッセージにもある通り、Herokuの無料枠のストレージサイズが500MBなのでデプロイ時にこの範囲内に収める必要があります。
容量を食っているのが、機械学習モデルだったので、Herokuでこれを動かすにはモデルのサイズを圧縮しておく必要がありました。
中でも一番のファイルサイズが大きいのがWord2Vecだったので、こちらのライブラリを使ってモデルサイズを圧縮しました。
50,000語程度にまで絞れば約60MBまで圧縮できます。
https://github.com/yagays/minify_w2v
重要語は以下から選択しました。
日本語を読むための語彙データベース Ver. 1.1
その他にもcacheを削除するなどいろいろ工夫の余地はありそうです。
これでリポジトリの容量をかなり圧縮できました。
大量のライブラリを使ってしまったせいで、これでもデプロイ時にpip install
までしてしまうと上限の500MBを超えてしまったので、起動時にpip install
が走るようにしておきました。
bot: bash run.sh
pip install -r requirements.txt
python app.py
以上で、なんとか無事に動きました。
トラブルシューティング
Herokuリポジトリにログイン
Herokuにログインしてマニュアル操作するときは以下のようにすればログインしてbash
コマンドが使えます。
heroku run bash
ログの確認
デプロイ後にアプリケーションのログが見たければ以下のコマンドで確認できます。
$ heroku logs