LoginSignup
14
16

More than 1 year has passed since last update.

Flask + uwsgi + NginxでAPIを実行する

Posted at

やりたいこと

  • Flask + uwsgi + Nginxの構成でAPIを動作させる

環境・MWのバージョン

  • Ubuntu20.04
  • Python 3.8.10
  • Flask 1.0.2
  • Nginx 1.18.0
  • uwsgi 2.0.20

今回使用する技術の概要

Flaskとは

Pythonの軽量フレームワークです。機能が少ない分リリース用のアーティファクトが軽量になる、習得が簡単であるなどのメリットがあります。

Djangoが中規模以上の開発に適しているのに対してFlaskは小規模な開発に向いています。(機能が限られたAPIをサブシステムとして構築する際に選択肢になるでしょう。)

uwsgiとは

Pythonのアプリケーションを動作させるためのアプリケーションサーバ用MWです。
機能が豊富で動作が速いことがメリットとして挙げられます。

uwsgiを使うにあたってはWSGIを理解しておく必要があります。

WSGIとは(Web Server GateWay Interface)の略で、Webサーバとアプリケーションサーバを繋ぐインタフェースの規格です。

uwsgiはこのWSGIに準拠したミドルウェアです。

Nginxとは

オープンソースのWebサーバ用MWです。
Apacheと比較して静的リソースの大量処理が得意な事やメモリ消費量が小さいことが特徴です。
(逆にApacheよりも動的リソースの処理が苦手です。)

作業手順

それぞれのMWが単体で動作することを確認した後、疎通確認をします。

  • Flaskの動作確認

    • インストールする
    • ビルトインサーバで動作確認する
  • Nginxの動作確認

    • インストールする
    • 静的ページを表示する
  • uwsgiの動作確認

    • インストールする
    • 動作確認する
  • Flask ⇔ uwsgi ⇔ Nginxの疎通確認

    • Nginxの設定
    • uwsgiの設定
    • 疎通確認

Flaskの動作確認

インストールする

※ Python3系がインストールされていることは前提とします。

以下のコマンドでFlaskをインストールします。
(Jinja2, itsdangerous, requests, WerkzeugはFlaskを動作させるために必要なパッケージです。)

$ pip install Flask==1.0.2 Jinja2==3.0.1 itsdangerous==2.0.1 requests==2.21.0 Werkzeug==2.0.1

正しくインストールされていることが確認できればOKです。

$ pip show flask

Name: Flask
Version: 1.0.2
Summary: A simple framework for building complex web applications.
Home-page: https://www.palletsprojects.com/p/flask/
Author: Armin Ronacher
Author-email: armin.ronacher@active-4.com
License: BSD
Location: /usr/local/lib/python3.8/dist-packages
Requires: Werkzeug, click, Jinja2, itsdangerous
Required-by: Flask-Testing, Flask-SQLAlchemy, Flask-RESTful, Flask-Migrate, flask-marshmallow, Flask-Mail, Flask-Login, Flask-JWT, Flask-JWT-Extended, Flask-Cors, Flask-Bcrypt, Bcrypt-Flask

ビルトインサーバで動作確認をする

サンプルプログラムのディレクトリ構成は以下の通りです。

/tmp/flask_sample/ # プロジェクトのルートディレクトリ
    ├── app
    │   └── __init__.py # アプリケーション本体とエンドポイントを記述する
    └── manage.py # アプリケーションを読み込んで起動する
/tmp/flask_sample/app/__init__.py

# Flaskで利用するパッケージをインポートする
from flask import Flask, jsonify

# アプリケーションオブジェクトを生成する
application = Flask(__name__)

# エンドポイントを作る(http://host/hello にリクエストするとJSONが表示される)
@application .route("/hello")
def hello():
    return jsonify({
        "message": "Hello World!"
    })
/tmp/flask_sample/manage.py
# appディレクトリからアプリケーションオブジェクトをインポートする。
from app import application

# Pythonスクリプトとして実行された場合、アプリケーションを実行する。
if __name__ == "__main__":
    application.run()

ここで、Flask単体の動作確認をします。

# プロジェクトのルートディレクトリに移動する
$ cd /tmp/flask_sample 
# ビルトインサーバを起動する
$ flask run

 * Environment: production
   WARNING: Do not use the development server in a production environment.
   Use a production WSGI server instead.
 * Debug mode: off
 * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

※ ビルトインサーバ起動時に警告が表示されますが一旦無視してOKです。

ブラウザから http://localhost:5000/hello にアクセスして以下のように表示されれば確認完了です。

image.png

Nginxの動作確認

インストールする

以下のコマンドでインストールします。

$ sudo apt-get update
$ sudo apt-get -y install nginx

静的ページを表示する

インストール後、Nginxを起動してブラウザで動作確認します。

$ service nginx start

デフォルトページが表示されれば完了です。

uwsgiの動作確認

インストールする

bash
$ apt-get update

# 各種依存パッケージをインストールする
$ apt-get install -y build-essential python-dev pip

# pipでuwsgiをインストールする
$ pip install uwsgi

動作確認する

$ cd /tmp/flask_sample
$ uwsgi --http=0.0.0.0:8000 --wsgi-file=/tmp/flask_sample/manage.py --callable=application

--wsgi-fileオプションでwsgiから動作させるファイルを指定し、--callableオプションでアプリケーションオブジェクトを指定します。

このとき必ずプロジェクトのルートディレクトリ(今回の場合は/tmp/flask_sample)に移動します。
理由は、manage.pyが相対インポートでapplicationオブジェクトを参照できるようにするためです。

ブラウザから http://localhost:8000/hello にアクセスして画像のように表示されれば成功です。

image.png

ここまで完了したら一旦各MWの動作確認は完了です。

Flask ⇔ uwsgi ⇔ Nginxの疎通確認

ここからはいよいよNginx・uwsgi・Flaskを組み合わせて動かします。

Nginxの設定

まずはクライアントのリクエストを受け付けるWebサーバとしてNginxの設定を変更します。

/etc/nginx/conf.d下にuwsgi.confを作成し、以下の内容を記述します。

/etc/nginx/conf.d


server {
   # 80番ポートを開放する
   listen 80;
   
   # "/"から始まるURIに{}内の設定を適用する
   location / {
       
       # uwsgiのパラメータを読み込む
       include uwsgi_params;
       # uwsgiとの通信に用いるソケットファイルを指定する(パスは任意)
       uwsgi_pass unix:///tmp/uwsgi.sock;
   }
}

続いて、uwsgi.confの設定がNginxに読み込まれるよう ```/etc/nginx/nginx.confの設定を変更します。

/etc/nginx/nginx.conf
# ファイルの真ん中あたりにあります

    # /etc/nginx/conf.d下の拡張子.confのファイルを全て読み込む
    # ※ 前項のuwsgi.confもここで読み込まれます
    include /etc/nginx/conf.d/*.conf;

    # この記述をコメントアウトする
    #include /etc/nginx/sites-enabled/*;

uwsgiの設定

続いてuwsgiの設定をします。
先ほどはuwsgiコマンドにオプションを指定して実行していました。しかし、設定項目が多くなると
毎回オプションを指定するのが面倒ですし、設定ミスも増えます。

そこで、設定ファイルでオプションを指定する方法を取りましょう。

/tmp/flask_sample下にwsgi.iniを作成します。
ディレクトリ構成は以下のようになります。

/tmp/flask_sample/
├── app
│   └── __init__.py
├── manage.py
└── wsgi.ini # 新規追加ファイル

/tmp/flask_sample/wsgi.iniを次のように編集します。

[wsgi]

# wsgiの実行時にプロジェクトのルートディレクトリに移動する
chdir = /tmp/flask_sample

# wsgiで動作させるファイルのパス
wsgi-file =  /tmp/flask_sample/manage.py

# アプリケーションオブジェクトの変数名
callable = application

# ソケットファイル
socket = /tmp/uwsgi.sock

# ソケットファイルの権限
chmod-socket = 666

# root権限で実行する
master = true

chdirでプロジェクトのルートディレクトリに移動しないと相対インポートが正しく動かない可能性があるので忘れずに設定します。(インターネット上の記事では全てのファイルを1つのディレクトリに配置しているため、chdirが省略されていることが多いです。しかし、実際のプロジェクトではそのようなケースは稀なのでchdirを指定するのが無難でしょう。)

疎通確認

ここまでの設定で、サーバのルートディレクトリにリクエストが来ると/tmp/uwsgi.sockに繋げる⇒
uwsgi.sockからmanage.pyが呼び出されてFlaskアプリケーションが実行される という処理が行われるようになりました。

以下のコマンドでwsgiを起動しましょう。

$ uwsgi --ini /tmp/flask_sample/wsgi.ini

ブラウザから http://localhost:8000/hello にアクセスしてレスポンスが表示されれば動作確認完了です。

参考資料

Nginx support

Flask+uWSGI+NginxでWSGIを試してみる

Install | NGINX

The uWSGI project

14
16
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
14
16