重いライブラリを使用したPythonスプリプトをAPIとして使いたかったときの話 ②

· 1572 words · 4 minute read

FlaskでAPI立てる続きです。awsのEC2にデプロイする手順を載せていきます。PythonプログラムをApacheで動かすためにmod-wsgiを用いて実装していきます。swgiは「Web Server Gateway Interface」の略らしく、Pythonとwebサーバのインターフェースとして動くモジュールのようですどうやら。


前回の振り返り 🔗

前回は、重いライブラリを使用したPythonスプリプトをAPIとして使いたかったときの話 ①に書いてあります。OpenCVを使った画像処理をPythonプログラムで実行するのに、aws LambdaでなくEC2を立てることにしたというところまで話し、後半部分では主にFlaskのディレクトリ構造やモジュールの実装について書きました。

root/
 ├ config/
 │ ├ development.json
 │ ├ production.json
 │ └ staging.json
 ├ package/
 │ └ ... 画像処理Pythonパッケージ(これをAPIにしたかった)
 ├ src/
 │ ├ module/
 │ │ └ ... アプリケーションモジュール(コントローラ的な処理)記述用
 │ ├ script/
 │ │ └ ... ビジネスロジック記述用
 │ └ config.py
 ├ app.py
 ├ requirements.txt
 ├ staging.wsgi
 └ production.wsgi

今回は本番Apache環境で必要な、production.wsgi(staging.wsgi)から載せていきたいと思います。


実装したこと 🔗

  • Pythonパッケージのアプリ化(API)
    • Flask + mod-wsgiライブラリを利用
  • aws EC2環境構築
    • 必要パッケージイストール
    • 依存ライブラリのインストール
    • Apache設定

環境 🔗

  • python 3.7.9

  • pip 21.2.4

  • amazon Linux 2

  • Apache 2.4.48

手順 🔗

2, mod-wsgi設定ファイル作成 🔗

production.wsgi

import os
import sys

sys.path.append('/app/xxxxx')

os.system('source /app/xxxxx/venv/bin/activate')
os.environ['FLASK_ENV'] = 'production'
os.environ['APP_ROOT_PATH'] = '/app/xxxxx'

from app import app as application

staging.wsgi

import os
import sys

sys.path.append('/app/xxxxx')

os.system('source /app/xxxxx/venv/bin/activate')
os.environ['FLASK_ENV'] = 'staging'
os.environ['APP_ROOT_PATH'] = '/app/xxxxx'

from app import app as application

後で設定するApacheファイルにこのファイルのパスを書くのですが、どうやらAphacheロード時にこのファイルを最初に読み込むようです。あらかじめ指定したい環境変数や、venvのコマンドなどを書いています。


3, EC2環境構築 🔗

$ sudo su -

# 必要パッケージインストール(適宜修正してください)
$ yum install httpd httpd-devel git gcc python3-devel mesa-libGL-devel -y

$ vi /etc/httpd/conf.d/vhost.conf

vhost.confに以下の内容を書きます。

(本番環境)

<VirtualHost *:80>
  ServerName xxxxx.com

  LoadModule wsgi_module /app/xxxxx/venv/lib/python3.7/site-packages/mod_wsgi/server/mod_wsgi-py37.cpython-37m-x86_64-linux-gnu.so
  WSGIDaemonProcess xxxxx-app user=xxxxx-user group=xxxxx-user threads=5 python-home=/app/xxxxx/venv
  WSGIScriptAlias / /app/xxxxx/production.wsgi

  WSGIScriptReloading On

  <Directory /app/xxxxx>
    WSGIProcessGroup xxxxx-app
    WSGIApplicationGroup %{GLOBAL}
    Order deny,allow
    Allow from all
    Require all granted
  </Directory>
</VirtualHost>

EC2はALBを利用したロードバランサまでHTTPS通信のあれを使っているため、Apache側で開くポートは80としています。 Python周りのインストールを全てvenvで行っているため、パスをそちらで通してます。 git cloneしているアプリファイル群は/app/xxxxxとします。アプリルート直下でvenvを作成しているので上のようなパスになります。 venvの仮装完了を使用するには、WSGIDaemonProcesspython-homeにvenvのパスを指定する必要があります。

$ exit
$ cd

$ mkdir modules && cd modules
$ git clone https://github.com/xxxxx/xxxxx-app.git

$ cd
$ mkdir release && cd release
$ vi xxxxx_release.sh

xxxxx_release.shに以下の内容を書きます。

xxxxx_release.sh

#!/bin/sh
rsync -a --delete /home/xxxxx-user/modules/xxxxx-app/ /app/xxxxx/

cd /app/xxxxx

python3 -m venv venv --clear
source venv/bin/activate

pip3 install -r requirements.txt

sudo systemctl restart httpd.service

これで/app/xxxxx/にgit cloneされたコード群がsyncされ、venv環境に必要なPythonパッケージがインストールされます。 Apacheがリロードすることで設定が反映されます。

EC2のIPまたは紐付けたドメインにアクセスして、This is root.が表示されていればOK。Pythonがちゃんと動いているか確認してください。


まとめ 🔗

Python + Flask + Apache + venv + EC2 のAPI構築手順について2回に分けてまとめました。サーバ環境構築は色々と謎のエラーと遭遇するので詰まることも度々あります。今回の実装もvenvのPythonをどうしても使いたかったのでwsgiの設定周りで試行錯誤してました。サクッととまではいかないですが、Pythonプログラムで気軽にAPI立てられます。

以上ありがとうございました。