【Raspberry Pi】Apache+WSGI+Python Flaskを使ってhttpsでWebアプリケーションを公開する


概要

Raspberry PiでPythonのFlaskフレームワークを用いたWebアプリを公開する。
その際、WSGIを用いてApacheと連携させることでSSLにも対応させる。

はじめに

この記事は、Raspberry Piの初期設定、ドメインの取得、Apache2の導入、ポート開放、SSL証明書の取得等が済んでいる前提の記事です。
お済みでない方は、先にそちらの設定を行うことを推奨します。

使用環境

  • Raspbian 10.7
  • Apache 2.4.38
  • Python 3.7.3
  • Flask 1.0.2

環境構築

次のコマンドでmod_wsgiをインストールします。
Pythonのバージョンが2以下の方はインストールするものが違うので注意してください。

$ sudo apt-get install libapache2-mod-wsgi-py3

Pythonのバージョンが2以下の場合

$ sudo apt-get install libapache2-mod-wsgi

PythonにFlaskフレームワークがインストールされていない方はインストールします。

$ sudo pip3 install Flask

Flaskアプリケーションの用意

ファイル構成

Flaskアプリケーションのファイル構成は以下のようにしました。

└ var/
  └ www/
    └ flask/
      ├ app.py
      ├ app.wsgi
      └ templates/
        └ test.html

サンプルの作成

app.py
#!/usr/bin/ python3
# -*- coding: utf-8 -*-

# Flaskフレームワークのインポート
from flask import Flask
# テンプレートエンジンのインポート
from flask import render_template

# Flaskインスタンスの作成
app = Flask(__name__)

# ルーティング
@app.route('/')
def index():
    return render_template('test.html')

# アプリ起動時の実行内容
if __name__ == '__main__':
    app.run()
app.wsgi
#!/usr/bin/ python3
# -*- coding:utf-8 -*-

import sys

# パスの指定
sys.path.insert(0, '/var/www/flask')
from app import app
application = app
test.html
<html>
  <body>
    <h1>Hello Flask!</h1>
  </body>
</html>

サンプルの動作確認

コマンドを入力してアプリが正常に動くか確認します

$ python3 /var/www/flask/app.py

最後にRunning on http://127.0.0.1:<ポート番号>/ (Press CTRL+C to quit)と出れば成功です。
そのまま別のターミナルを開き、以下のコマンドを入力して正常にhtmlが取得できるか確認します。

$ curl localhost:<ポート番号>

test.htmlの内容が取得できれば成功です。CTRL+Cを押して一度アプリを終了します。

Apache2の設定

/etc/apache2/sites-available/に次のファイルを作成します。
root権限で行ってください。

flask_wsgi.conf
# コードの簡単化のためIfModuleは使わない

# http通信をhttps通信にリダイレクトする
<VirtualHost *:80>
    RewriteEngine On
    RewriteCond %{HTTPS} off
    RewriteRule ^(.*)$ https://%{HTTP_HOST}/$1 [R=301,END]
</VirtualHost>

# https通信の設定
<VirtualHost *:443>
    ServerName <サーバの名前>
    ServerAdmin <管理者のメールアドレス>

    DocumentRoot /var/www/flask

    WSGIDaemonProcess app user=<ユーザー名> group=<ユーザーグループ> threads=5
    WSGIScriptAlias / /var/www/flask/app.wsgi

    ErrorLog ${APACHE_LOG_DIR}/error.log
    CustomLog ${APACHE_LOG_DIR}/access.log combined

    SSLEngine on

    SSLCertificateFile <SSL証明書 fullchain.pemのパス>
    SSLCertificateKeyFile <SSL証明書 prevkey.pemのパス>

    <FilesMatch "\.(cgi|shtml|phtml|php)$">
        SSLOptions +StdEnvVars
    </FilesMatch>
    <Directory /usr/lib/cgi-bin>
        SSLOptions +StdEnvVars
    </Directory>

    <Directory /var/www/flask/>
        WSGIProcessGroup app
        WSGIApplicationGroup %{GLOBAL}
        WSGIScriptReloading On

        Require all granted
        Options FollowSymLinks
        AllowOverride All
    </Directory>
</VirtualHost>

次に、以下のコマンドを入力してコンフィグを有効にします。

$ sudo a2ensite flask_wsgi

/etc/apache2/sites-enabledを確認して他のコンフィグファイル(000-default.conf等)が有効になっていないか確認します。サーバー名が明確に分かれていない場合、競合する可能性があるので以下のコマンドで無効にします。

$ sudo a2dissite <他のコンフィグファイル>

以上ができたら、Apacheを再起動します。

$ sudo service apache2 restart

エラーなく再起動できたら、ブラウザを開き確認します。
test.htmlの内容がブラウザで正常に取得出来たら成功です。お疲れ様でした。

参考