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の仮装完了を使用するには、WSGIDaemonProcess
でpython-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立てられます。
以上ありがとうございました。