行政書士ボット

機械学習で進化する行政書士Gyobot Blog

2017年10月16日1:52(約783日前)

Bottleで作成したWebアプリケーションを本番環境に適用する

開発

Bottleで開発を進めるもデプロイの仕方がわからず

Gyobotは開発言語にPython、WebフレームワークとしてDjangoを採用していますが、開発当初は軽量かつ手軽なBottleを使用していました。DBを使用するなどの予定がなければ、フレームワーク自体がPythonファイル1枚で構成されているため、設置方法がわかりやすく、とりあえずWeb上で動かしたいという場合や初心者(自分もですが)にオススメのフレームワークです。
Bottleには標準で開発用Webサーバーが付属しているため開発環境ではこのBottle付属のWebサーバーを使いました。本番もBottle付属のWebサーバーでいいだろうくらいの気持ちでデプロイしましたが、不安定すぎて本番環境では使い物になりませんでした。ちなみに開発環境では実行ファイルに以下のようなrun関数を記述します。

run(host='localhost', port=8080, debug=True)

本番公開について調べ進めると開発時には手軽にデバッグできる付属のWebサーバーを使って、本番運用はApacheやnginxといったパフォーマンス重視のWebサーバーを使用するのが一般的とわかりました。

PythonでWebサーバーとWebアプリを接続するインターフェースが必要

Pythonファイルは単純にWebサーバーのルートに置いただけでは動作しません。最初このあたりの概念がよくわかりませんでした。
Pythonにおいて付属Webサーバー以外のWebサーバーでWebアプリケーション動作させるためには、WSGIというフィンターフェース仕様にそった情報のやり取りが必要なようです。
その情報のやり取りを可能にするためにアダプタと呼ばれるファイルが必要で、WebサーバーにApacheを使用している場合はmod_wsgiを利用します。

Bottleをmod_wsgiを使ってApatche上で動かす

具体的な作業内容は以下になります。
以下はインストールされている前提です。

動作環境

  • CentOS7.3.6
  • Apache2.4.6
  • Python3.6.2
  • bottle 0.12.13
  • venv(仮想環境名)env

mod_wsgiのインストール

(env)$ yum install -y zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline-devel tk-devel
(env)$ yum install -y httpd-devel python-devel gcc
(env)$ yum install -y mod_wsgi

yumでmod_wsgiと必要なモジュールをインストールしています。

mod_wsgiのインストール先を見つける

(env)$ python3.6 -c "import sys; print(sys.path)"
['', '/usr/lib64/python36.zip', '/usr/lib64/python3.6', '/usr/lib64/python3.6/lib-dynload', '/var/www/html/env/lib64/python3.6/site-packages', '/var/www/html/env/lib/python3.6/site-packages']

venvでenvという仮想環境を構築しているので/var/www/html/env/lib64/python3.6/site-packagesにあります。さらに調べ進めると…

(env)$ cd /var/www/html/env/lib64/python3.6/site-packages/mod_wsgi/server
(env)$ ll
total 1048
-rw-r--r-- 1 root root   1558 Sep 11 16:18 apxs_config.py
-rw-r--r-- 1 root root   3563 Mar 31  2016 environ.py
-rw-r--r-- 1 root root 128159 Aug 29 18:28 __init__.py
drwxr-xr-x 4 root root     57 Sep 11 16:18 management
-rwxr-xr-x 1 root root 932872 Sep 11 16:18 mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so
drwxr-xr-x 2 root root     98 Sep 11 16:18 __pycache__

これで/var/www/html/env/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.soにあることがわかりました。この情報を使用するので控えておきます。

Apacheの設定

次にwsgi.confという名前でApacheの設定ファイルを追加します。

(env)$ cd /etc/httpd/conf.d
(env)$ vim wsgi.conf

wsgi.confの記述内容は以下になります。

#bottle用 wsgi.conf
LoadModule wsgi_module /var/www/html/env/lib64/python3.6/site-packages/mod_wsgi/server/mod_wsgi-py36.cpython-36m-x86_64-linux-gnu.so

WSGIDaemonProcess myapp user=hoge group=hoge
WSGIProcessGroup myapp
WSGISocketPrefix /var/run/wsgi
WSGIScriptAlias / /var/www/html/adapter.wsgi



  Options ExecCGI MultiViews Indexes
  MultiViewsMatch Handlers

  AddHandler wsgi-script .py
  AddHandler wsgi-script .wsgi

  DirectoryIndex index.html index.py

  Order allow,deny
  Allow from all


ポイントは2行目のLoadModuleの行と7行目のWSGIScriptAliasの行です。2行目は先ほど見つけたmod_wsgiのインストール先で、7行目がこれから作成するアダプタファイルの場所になります。
またmod_wsgiには組み込みモードとデーモンモードがありますが、今回はデーモンモードで利用しています。組み込みモードの方が設置が容易ですがアプリケーションが正常に動作しませんでした。アプリケーションが正常動作しない場合はmod_wsgiをデーモンモードで動作させることをオススメします。

アダプタファイルの作成

wsgi.confで指定した場所にアダプタファイルadapter.wsgiを作成します。

import sys, os
dirpath = os.path.dirname(os.path.abspath(__file__))
sys.path.append(dirpath)
os.chdir(dirpath)
import bottle
import python_file_name
application = bottle.default_app()

Djangoではプロジェクト作成時にwsgiを設定するwsgi.pyが作成されますが、Bottleでは自分で作成する必要があります。
"python_file_name"の箇所はご自身のpython実行ファイル名です。

Webアプリケーションファイルをアップロード

Webアプリケーションをアップロードしますが、ここでpython実行ファイルのrun関数をコメントアウトするのを忘れないようにしましょう。自分はこれで結構はまりました。

#run(host='localhost', port=8080, debug=True)

最後にapacheをリスタートしてWebアプリケーションにアクセスしてみてください。

まとめ

Pythonの教則本などでは開発環境の構築やプログラム自体については詳しく書かれていますが、Bottleで本番環境で動作させることに言及されているものが見つけられなかったので、簡易WebフレームワークのBottleとはいえデプロイに苦労しました。
動作しない場合はSElinuxなどセキュリティ周りやポート、所有者や実行権限をいじってみるのも有効だと思います。

関連記事