【Ubuntu】Flask, uWSGI, nginxでHello Worldする方法

2019年8月12日

当サイトはPR広告を利用しています。

この記事では、Flask, uWSGI, nginxそれぞれの役割とインストール方法を説明した後に、上の図のようにFlask, uWSGI, nginxを連携させてHello Worldする方法をコード付きで解説します。コードと設定ファイルには一行一行説明を記載しているので、内容理解にお役立てください。

著者環境

ubuntu: 18.04
python: 3.6.8

役割説明

まず今回利用するFlask, uWSGI, nginxそれぞれの役割について説明します。

Flaskとは

FlaskはPythonを使ってWebアプリを簡単に作成するための骨組み(フレームワーク)です。ウェブアプリに必要な機能の骨組みを持っているので、あとは自分が作りたい機能だけを骨組みの周りに肉付けする形で実装することでWebアプリが簡単に作れます。

nginxとは

読み方は「エンジンエックス」。Webサーバーの一つです。
Webサーバーの役割はブラウザなどクライアントからの要求に対して、要求にあったファイルを渡してあげること。

nginx以外にもWebサーバーは複数ありますが、nginxは特にサーバーの負荷分散機能に優れていて、大量アクセスを処理できるように設計されています。

PCの使用者数は年々増えてきているので、大量アクセスに対応可能なnginxは人気になっています。

uWSGIとは

uWSGIの説明に入る前に、理解の前提となるWSGIについて説明します。

WSGIは"Web Server Gateway Interface"の略称です。
公式サイトには以下のように説明がされています。

standard interface between web servers and Python web applications or frameworks,
to promote web application portability across a variety of web servers.

https://www.python.org/dev/peps/pep-0333/

和訳するとWSGIとは"WebサーバーとPythonのWebアプリケーションをつなぎ合わせてくれるもの“となります 。

この機能を果たすWSGIの一つがuWSGIです。今回の構成の中ではFlaskとnginxを結びつける働きをしてくれます。またuWSGIはFlaskを稼働させるアプリケーションサーバーでもあります。

完成形

上記のことを踏まえて以下のような構成でHello Worldを出力します。

clientはchromeやsafariなどのブラウザです。図でuWSGIとFlaskが近いのはuWSGIがFlaskを稼働させるアプリケーションサーバーでもあることを示すためです。

インストール

ここから先はvenvで作った仮想環境の中で操作をしていきます。
pythonの仮想環境について知りたい方は以下の記事を参考にしてください。

uWSGI

以下のコマンドを実行してインストールしてください。

# uwsgiのインストールに必要なものをインストール
$ sudo apt install python3-dev
$ pip install wheel

# uwsgiのインストール
$ pip install uwsgi

Nginx

以下のコマンドを実行してインストールしてください。

# nginxをaptで管理できるようにする(nginx.listの作成)
$ sudo sh -c 'echo "deb http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" > /etc/apt/sources.list.d/nginx.list'
$ sudo sh -c 'echo "deb-src http://nginx.org/packages/ubuntu/ $(lsb_release -cs) nginx" >> /etc/apt/sources.list.d/nginx.list'

# おそらくエラーになりますが確認したい内容がありますので以下のコマンドを実行
$ sudo apt update
# the public key is not available: NO_PUBKEY ???というエラーが出ると思うので???部分をコピー

# 正式なnginxをinstallするための公開鍵ダウンロード
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys ???の文字列

# 前準備が完了したのでインストール
$ sudo apt update
$ sudo apt install nginx

Flask

以下のコマンドを実行してインストールしてください。

## Flaskのインストール
$ pip install flask

実装

それではこれからコーディングに入ります。

以下のファイル構成のディレクトリを作ります。作る場所はどこでも問題ありません。

hello
   ├─ main.py  # Flaskのファイル
   └─ uwsgi.ini  # uWSGIの設定ファイル

Flask

main.pyに以下のコードを記載します。

from flask import Flask


app = Flask(__name__)


@app.route("/")
def hello():
    return "Hello World!"


if __name__ == "__main__":
    app.run()

記述したコードの意味は以下のページで詳しく解説しているので、不明な箇所がありましたら確認してみてください。

nginx

nginxの設定ファイルを編集します。ubuntuの場合、nginxの設定ファイルは/etc/nginxにあるnginx.confです。

ただし今回編集するファイルはこのファイルではありません。

nginx.confファイルには「include /etc/nginx/conf.d/*.conf;」という記述があります。この記述は「/etc/nginx/conf.dディレクトリ配下にある拡張子がconfファイルを読み込んで、そのファイルに記述されている内容も nginxの設定として反映しますよ」という意味を持っています。

そこで今回は「/etc/nginx/conf.d/uwsgi.conf」というuWSGIとの連携用nginx設定ファイルを新たに作成します。

server {
    listen       50000;
    location / {
        include uwsgi_params;
        uwsgi_pass unix:///tmp/uwsgi.sock;
    }
}

それでは記載した1行1行を解説していきます。

server { ~ }

特定のサーバーに対する接続時に、どのような処理をするのかを設定するブロックです。どのサーバーに対する接続かはlisten設定で、どんな処理をするのかはlocation設定で行います。他にも設定方法はありますが、代表的なものがこちらですので覚えておきましょう。詳細はこの後説明します。

listen

listenの後にある数字がこの設定と対応するポート番号です。"172.16.0.39:80″のようにIPアドレスとポート番号をセットで指定することが出来ますが、IPアドレスが省略されてポート番号のみ指定した場合にはlocalhostが対象となります。

今回の場合はlocalhostのポート番号50000にアクセスがきた時にlocationブロック内の設定にしたがって情報の処理がされます。

location

locationはリクエスト時に指定されたパス(URL)に対応して、nginxがどこに情報を引き継げば良いのかを設定します。

「location / {」の意味は「/で始まるパスが指定された時にはブロック内の処理をする」です。

全てのパスは/で始まるので、他にもっと詳細なlocationの設定をしている箇所がなければ、この箇所で処理することになります。例えば「location /home/{」という設定があり、/homeに対するアクセスがあった場合には「location / {」ではなく、「location /home/{」で指定された設定に従います。

locationについてもっと詳しく知りたい方には以下のサイトも確認してみてください。
nginx連載5回目: nginxの設定、その3 – locationディレクティブ

50000番ポートにきた時の設定をしているuwsgi.confにはこの一つのlocationしか存在しないため、全ての処理をこのlocationの設定に従って行うことになります。

include uwsgi_params;

uwsgi_paramsというファイルを読み込んで、このファイルに記述されている設定をnginx設定ファイル内で利用できるようにしています。この1行下にあるuwsgi_passは「include uwsgi_params」をすることによって初めて利用可能になります。

uwsgi_paramsというファイルはnginxのインストールと同時に作られ、nginxとflaskを連携させるために必要な色々な設定が記述されています。

uwsgi_pass unix:///tmp/uwsgi.sock;

uwsgiへの接続窓口を指定しています。

この記載によって、50000番ポートにアクセスがきた時には、localhostの/tmp/uwsgi.sock(uWSGI用の窓口)に処理を引き継ぐことにります。

スラッシュが3つに付いているのはローカルホストに対するアクセスを表しています。

参考ページ : 「file:///」でスラッシュが3つ並んでいる理由

実行

ここまでの設定を全て行った後、以下のコマンドを実行してnginxとuWSGIが起動させます。

# nginxを再起動させ、編集したファイルを読み込ませる。
$ sudo systemctl restart nginx

# uWSGIの起動
$ uwsgi --socket /tmp/uwsgi.sock --module main --callable app --chmod-socket=666

この状態で127.0.0.1:50000にwebからアクセスすればHello Worldが出力されるはずです。

ただuWSGIを起動する際、毎回複数のオプションを付けてコマンド実行するのは面倒だと思います。

そこで朗報です。今回uWSGI起動時にコマンドでオプションを書いていた部分をiniファイルとして保存することで、簡単に実行させることが出来るようになります。

uwsgi.ini

helloフォルダの直下にuwsgi.iniという名称でファイルを作って以下を記述してください。

[uwsgi]
socket = /tmp/uwsgi.sock
chmod-socket = 666
module = main
callable = app

それぞれの設定の意味を説明します。

  • socket
    nginxからの情報の受け渡し窓口となるソケットファイルを指定。
  • chmod-socket
    ソケットファイルの権限を設定します。今回はnginxがソケットファイルに対して読み込み書き込みが出来るように権限を設定しています。
  • module
    実行するファイルを指定します。
    今回Flaskアプリケーションを作成しているのはmain.pyなのでmainと指定。
  • callable
    実行可能なFlaskアプリケーションの名称を指定します。
    今回main.py内で「app = Flask(__name__)」と記述して、アプリケーションを作成していたので、アプリケーション名は変数名としているappを指定。

以下のように—iniオプションをuWSGI起動コマンド実行時に追加することで、iniファイルを読み込んでuwsgiを起動することが出来ます。

$ uwsgi --ini uwsgi.ini

上記のコマンドを実行した状態で127.0.0.1:50000にwebからアクセスすればHello Worldが出力されるはずです。

まとめ

以上でuWSGIとFlaskとnginxを連携させたHello World出力までの流れの解説は終了です。

なぜこれで動くのか、またなぜこのような構成にする必要があるのか、思い出せない点があれば最初から記事を読み直して完全に理解してもらえると嬉しいです。

参考にしたサイト

直近でおすすめの本

直近十数冊読んだ中で一番おすすめの本です。

人が行動をするに至るまでのステップを科学的に分析した上で、その結果を習慣と紐付けて解説してくれている本です。

悪い習慣を断ち、良い習慣を継続する方法を詳細に説明してくれています。習慣が人を作っているので、この本の内容を実践できれば人生を大きく好転させられる気がしました。

この本の最初の方に説明があるのですが、複利という考え方があり毎日1パーセントだけの増加でもそれが続くととてつもない倍率になります。これは投資でよく用いられる概念ですが、良い習慣は未来への投資なので習慣にもあてはまります。良い習慣を身に付けるのは早ければ早いほど良いです。

私はまず長時間YouTubeを見てしまう習慣を断って、直近の業務に役立つITの勉強を習慣として身に付けよう思います。

Pythonflask,nginx,uwsgi

Posted by ラプラス