前回の記事で、PythonのWebアプリケーションフレームワークであるFlaskでHello Worldをローカル開発環境で確認するまでを紹介した。
今回、Raspberry Pi 3 Model B 上にWebサーバーを構築して、FlaskのWebアプリケーションを本番環境に公開するまでを紹介する。
Flaskの本番環境に関して
This launches a very simple builtin server, which is good enough for testing but probably not what you want to use in production. Flask公式
Flaskには組み込みサーバーがあり、特別な環境構築を行うことなく、Webサーバーを立ち上げることができる。ただし、この組み込みサーバーを本番環境でも使用することは推奨されていない。
そこで、通常のWebサーバーであるApacheやNginxを用いて、FlaskのWebアプリケーションを公開する。Flaskは、WebサーバとアプリケーションをつなぐインターフェースであるWerkzeugを基にしており、WSGI(Web Server Gateway Interface)に準拠してWebサーバーと通信することができる。そのため、今回の本番環境は、このような構成図になる。
FlaskはWSGI(Web Server Gateway Interface) を用いているため、直接ApacheやNginxのWebサーバーと通信することができない。そのため、「uWSGI」を使うことが通例になっている。
uWSGIとNginx間の通信は、高速で安定した通信が可能な「Socket」を用いた。
環境構築
ゼロから環境構築を順番に行っていく。
- Pipenvで仮想環境構築する
- uWSGIの動作確認をする
- Flaskの組み込みサーバーでHelloWorldを表示する
- uWSGIを通してFlaskのサイトをブラウザに表示する
- Nginxの動作確認をする
- Nginxのバーチャルホストの設定を行う
- uWSGIの設定ファイルを作成する
- NginxとuWSGIを接続して、動作確認をする
- 自動起動を設定する
1. Pipenvで仮想環境構築する
まずは、仮想環境にFlaskとuWSGIをインストールする。
$ pip3 install --upgrade pip # pipを最新版にアップグレードする $ pip3 install pipenv # pipenvをインストールする $ export PATH=$PATH:/home/pi/.local/bin # PATHを追加する $ mkdir ./flask-test # flask-testディレクトリを作成 $ cd ./flask-test # flask-testディレクトリに移動 $ pipenv install --python 3.7.3 #3.7.3で仮想環境構築 $ pipenv install uwsgi # 仮想環境にuwsgiをインストール $ pipenv install flask # 仮想環境にflaskをインストール $ pipenv shell #仮想環境を実行
2. uWSGIの動作確認をする
flask-testディレクトリ直下に、test.pyを作成してください。
def application(env, start_response): start_response('200 OK', [('Content-Type','text/html')]) return [b"Hello World uWSGI"]
次に、以下のコマンドでuWSGIを起動する。
(flask-test)pi$ uwsgi --http :8000 --wsgi-file test.py
オプション | 概要 |
---|---|
--http:8000 | ポート8000を使用して、HTTPプロトコル通信をする。 |
--wsgi-file test.py | WSGIサーバーでtest.pyを実行する。 |
http://127.0.0.1:8000 にアクセスして、「Hello World uWSGI」が表示されていれば、ブラウザがuWSGIを通してPythonのプログラム(test.py)にアクセスできた事を意味する。
3. Flaskの組み込みサーバーでHelloWorldを表示する
次に、Flaskの組み込みサーバーでFlaskのサイトが実行できるか動作確認を行う。 flask-testのディレクトリ直下に、app.pyを作成してください。
from flask import Flask app = Flask(__name__) @app.route("/") def hello(): return "Hello world Flask" if __name__ == "__main__": app.run()
以下のコマンドで、Flaskの組み込みサーバーを起動してください。
(flask-test)pi$ python app.py
http://127.0.0.1:5000にアクセスして、「Hello World Flask」が表示されていれば、ブラウザを通して、HTTP通信でFlaskの組み込みサーバーにアクセスできた事を意味する。
4. uWSGIを通してFlaskのサイトをブラウザに表示する
以下のコマンドを実行してください。
(flask-test)pi$ uwsgi --http :8000 --wsgi-file app.py --callable app
http://127.0.0.1:8000にアクセスして、「Hello World Flask」が表示されていれば、uWSGIを通してFlaskのサイトをブラウザに表示することができたことになる。
5. Nginxの動作確認をする
一度、仮想環境からログアウトして、Nginxをインストールする。
(flask-test) pi $exit #exitして仮想環境から出る pi$ sudo apt install nginx pi$ sudo /etc/init.d/nginx start [ ok ] Starting nginx (via systemctl): nginx.service.
起動が成功したら http://127.0.0.1:80 にアクセスする。 正常に動作していた場合、「Welcome to nginx!」のページが表示され、ブラウザとWebサーバの連携が確認できる。
6. Nginxのバーチャルホストの設定を行う
NginxでuWSGIを介して、FlaskのWebアプリケーションを公開するための設定を行う。
# Virtual Host Configs include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*;
nginx.confの設定ファイルには、上記のような記載があり、以下の2つのフォルダを参照している。
- /etc/nginx/conf.d : 既存のファイルなし
- /etc/nginx/sites-enabled/ : defaultのファイルのみ
/etc/nginx/sites-enabled/defaultに基本設定が記載されている。バーチャルホストに関しては、以下の記載がある。
# Virtual Host configuration for example.com # # You can move that to a different file under sites-available/ and symlink that # to sites-enabled/ to enable it.
sites-availableに設定ファイル実体を配置して、sites-enabledに設定ファイルへのシンボリックリンクを張るのが通例のようだ。
sites-available、sites-enabledのフォルダ直下には、同じdefaultファイルが存在する。コピーを作成して、ファイル名を変更する。
$ cd /etc/nginx/sites-available
$ sudo cp default ./app_nginx.conf
defaultファイルを編集しても問題ないが、ほとんどの設定を削除して、以下のような設定ファイルとしてください。/var/www/に80番ポートでアクセスしたときに、uWSGIに接続するような設定にする。
# Virtual Host configuration for example.com server { listen 80; server_name example.com; location / { include uwsgi_params; uwsgi_pass unix:/tmp/uwsgi.sock; } }
uwsgi.sockはソケットファイルであり、勝手に作られるので特に用意しておく必要はない。NginxはuWSGIに接続する際に、UNIXソケットを間に噛ませて通信する。これにより、ポート番号を消費せずに済む。
シンボリックリンクを設定する。
$ cd /etc/nginx/sites-enabled/ $ sudo ln -s /etc/nginx/sites-available/app_nginx.conf app_nginx.conf
最後に、/etc/nginx/sites-enabled/にはdefaultファイルが存在するので、.confファイルのみが有効になるようetc/nginx/nginx.confを編集する。
# Virtual Host Configs include /etc/nginx/conf.d/*.conf; include /etc/nginx/sites-enabled/*.conf; #ここを編集する
7. uWSGIの設定ファイルを作成する
flask-testフォルダ直下に、myapp.iniを作成し、uWSGIの設定を行う。
flask-test |- app.py |- test.py |- myapp.ini
[uwsgi] module = app callable = app master = true processes = 1 socket = /tmp/uwsgi.sock chmod-socket = 666 vacuum = true die-on-term = true chdir = /home/pi/flask-test # フォルダのディレクトリを指定する
8.NginxとuWSGIを接続して、動作確認をする
uWSGIサーバーを以下のコマンドで立ち上げる。
$ uwsgi --ini myapp.ini
別のターミナルを開いて、nginxを起動する
$ sudo /etc/init.d/nginx start
http://127.0.0.1:80 にアクセスし、「Hello World Flask」を確認することができれば、本番環境の構築ができたことになる。
9. 自動起動を設定する
systemctlを用いて、自動起動できるよう設定を行っておく。 systemctlに登録するために、/etc/systemd/system/内にuwsgi.serviceファイルを作る。
[Unit] Description = uWSGI After = syslog.target [Service] ExecStart = /home/pi/.local/bin/uwsgi --ini /home/pi/flask-test/myapp.ini #ファイルのパスを指定する Restart=always KillSignal=SIGQUIT Type=notify StandardError=syslog NotifyAccess=all [Install] WantedBy=multi-user.target
systemctlのコマンドは以下の通りである。
$ systemctl status uwsgi //status確認 $ systemctl start uwsgi // uWSGI開始 $ systemctl stop uwsgi // uWSGI停止認証を求められるので、Raspberry Piのユーザーパスワードを入力する。
最後に、自動起動の設定を行う。
$ systemctl enable uwsgi
これで、電源再起動をしても、自動で起動するようになった。 Nginxは自動でsystemctl に登録されており、再起動しても自動で立ち上がるようになっていた。
まとめ
今回は、Raspberry Pi上で、Flask + uWSGI + NginxでWebアプリケーションを公開する方法を紹介した。Raspberry Piでなくても、基本的にはLinuxで同様な動作をするはずである。
それでは、ステキな開発ライフを。