サイトをFreeBSD11+python3.6+Bottleで作り直すメモ(11)-nginxとuWSGIで公開してみる
- 公開日: 2018/11/14(水) 19:21[JST]
- 更新日: 2023/01/02(月) 19:26[JST]
FreeBSDのポリシーが変わって2018年10月いっぱいでFreeBSD 10-Releaseは終了したとのことなのでタイトル変更。
これまではBottleが内蔵していたWebサーバで動作確認を行っていたが性能がいまいちなので実運用するなら適当なWSGIサーバを使ってね、とマニュアルにも書かれているので検討してみる。基本的にはh_kabocha氏によるBottle + uWSGI+ Nginx Quick Tutorialのやり方をそのまま使わせて頂いた。ここではFreeBSD環境特有の箇所のみ記載する。
nginx、uwsgi共にpkgでインストール可能。python3.6の場合はuwsgi-py36というパッケージをインストールすればよいようだ。(uwsgiというパッケージもある)。また、FreeBSDの場合は(他のサーバ系パッケージと同様)必要に応じてサーバを動作させるユーザとグループを作ってくれる(nginxについてはもとから用意されていたwww:wwwを利用、uwsgiについてはuwsgi:uwsgiを作成してくれる)。
uwsgiの設定ファイルのデフォルトは/usr/local/etc/rc.d/uwsgiを見る限り/usr/local/etc/uwsgi/uwsgi.iniなのでそこを編集。socketも特にしていてなければ/tmp/uwsgi.sockになるようだ。
まず、Bottleで動かすサイトのソースコードを開き、先頭に下記のコードを追加する。
from bottle import default_app
そして、末尾の
run(host='IPアドレス', port=ポート番号, debug=True, reloader=True)
を、以下のように変更する。
if __name__ == '__main__': run(host='IPアドレス', port=ポート番号, debug=True, reloader=True) else: application = default_app()
(2018/11/17追記)正式公開まではバグフィックスの為にソースの先頭にfrom bottle import debugを追加し、application = default_app()の前にdebug(mode=True)を入れてデバッグモードにしておいた方がよさそう。これが無いとpythonコードのエラーがすべて"Internal Server Error"になってしまって原因が特定できない。(追記終わり)
次に、/usr/local/etc/uwsgi/uwsgi.iniを作成する。単純に下記のようにした。
[uwsgi] chdir = アプリのコードが保存されているディレクトリ file = アプリのファイル名
続いて、/usr/local/etc/nginx/nginx.confを編集。まず、httpセクションの中に下記を追加する。
upstream _bottle { server unix:/tmp/uwsgi.sock; }
そして、http→server→location / セクションを以下のように変更する。
location / { include uwsgi_params; uwsgi_pass _bottle; }
最後に、/etc/rc.confにnginx_enable="YES"とuwsgi_enable="YES"を追加してuwsgiとnginxを起動すれば完了。
複数のBottleアプリを使いたい場合(例えばコンテンツ表示用のものとコンテンツ編集用のものを別のポートで動かしたい時)は、uWSGIのエンペラーモードを利用する。FreeBSDの場合は/etc/rc.confにuwsgi_emperor="YES"を追加する。各アプリのiniファイルは/usr/local/etc/uwsgi/vassals/に移し、socket=/tmp/ソケット名.sockという行を追加する。ソケット名はアプリ毎に違うものを用意する。で、/usr/local/etc/uwsgi/uwsgi.iniは、wapa5pow氏のApacheにかわるwebサーバ: uWSGIパフォーマンスチューニングという記事を参考に以下のようにしてみた(なお、uwsgi自体は、エンペラーモードならuwsgi.iniが無くてもFreeBSDが適当なパラメータを設定してくれる)。また、環境変数LANGを正しく設定していないとSimpleTemplateの起動でこけるのでこれも設定。
[uwsgi] max-requests = 6000 max-requests-delta = 300 env = LANG=ja_JP.UTF-8
さらに/usr/local/etc/nginx/nginx.confの方はupstreamセクションとserverセクションをソケット毎に用意する。
(2020/6/10追記) uWSGIではiniファイル中に logto = ログファイルのパス でログを記録できるが、実運用する時にログを記録すると膨大な量となったのでログは記録しないほうがよさそう。アクセスログはNginxでもとれるわけだし。(追記終わり)
(2023/1/2追記) FreeBSDのアップグレードにあたってuwsgiを更新したら色々とはまったので記録しておく。
pkg upgrade -f したらuwsgiがエラーで起動できなくなった
エラーログを追っかけたところ、uwsgiが参照するpythonのバージョンが3.9になっていた
py39-pipでパッケージをインストールしようとするが、プロキシエラーでパッケージをダウンロードできない
どうやらpy39-pipはシステムのプロキシ設定を無視するようだ。
pip-3.9 --proxy=サーバアドレス:ポート番号 install 〜 としたら大抵のパッケージをインストールできたがcryptographyのみインストールできない。 --proxy オプションは再帰的にpipが実行される場合は適用されないらしい
環境変数 PIP_PROXY=http://サーバアドレス:ポート を指定することでこの問題は回避できた。が、今度はcryptographyのビルドエラー。Rustが必要とのこと
pkgでrustをインストールしたが別のビルドエラー。rustはrustでプロキシを指定する必要がある
~/.cargo/config というファイルに、以下の内容を記述することでようやくcryptographyをインストールできた
[http] proxy = "http://サーバアドレス:ポート"
(追記終わり)