VirtualBox, pyenv, Flask, waitress, Apache proxy を使ったデプロイ - AlmaLinux

ディレクトリ構成

ディレクトリ構成

  • home
    • user # ユーザーのホームディレクトリ
      • myapp
        • flaskapp
          • .gitignore
          • bin # venv のファイル
          • flaskapp # Flask アプリ
          • include
          • ...

flaskappに Flaskアプリについては、以下のページを参考にしてください。

Python の設定

home/user/myapp/flaskappを仮想環境にしてFlaskアプリを稼働させます。

Python は、pyenv の local コマンドを使い myapp ディレクトリ内を pyenv でインストールした Python に設定しています。

また、「 home/user/myapp/flaskpp 」を venvで仮想環境を作成し、Flask や Waitress をインストールします。

pyenv や venv については、以下を参考にしてください。

Apache の設定

Apache をプロキシサーバーとして接続する設定をします。/etc/httpd/conf/httpd.confに、以下の内容を追加します。

/etc/httpd/conf/httpd.conf

<VirtualHost *:80>
  ProxyPass / http://localhost:8000/
  ProxyPassReverse / http://localhost:8000/
</VirtualHost>

ファイアウォールの設定

sudo firewall-cmd --add-service=http --zone=public --permanent
sudo firewall-cmd --permanent --zone=public --add-port=8000/tcp
sudo firewall-cmd --reload

ファイアウォールの設定を行った後、以下のコマンドを実行しアプリを起動してみます。

waitress-serve --listen=127.0.0.1:8000 app:app

サーバーのIPアドレスが「 192.168.11.5 」の場合、ブラウザから「 192.168.11.5:8000/myapp 」にアクセスします。

モジュールが見つからないというエラーが出た場合、パスを追加する必要があります。

接続ができているのにページが表示されない場合は、SELinux でブロックされている可能性が高いです。

以下のコマンドを実行し、SELinux を permissiveにします。ページが表示されれば、SELinux が原因のため設定を変更します。

sudo setenforce 0

Flask アプリが認識されない場合

Pythonがモジュールを認識できない場合は、環境変数 PYTHONPATH を設定します。

export PYTHONPATH=/home/user/myapp/flaskapp

もしくは、Pythonスクリプト内で明示的にパスを追加する方法があります。

flaskapp/app.py

import logging
import datetime
from flask import Flask, request
from waitress import serve

# 以下の2行を追加
import sys
sys.path.append('/home/user/myapp/flaskapp')

from flaskapp import create_app

# `werkzeug` のロガーを取得
log = logging.getLogger('werkzeug')
log.setLevel(logging.INFO)  # INFOレベルでリクエストを記録
log.addHandler(logging.StreamHandler())  # コンソール出力を有効化

app = create_app()

@app.after_request
def log_response(response):
    current_time = datetime.datetime.now().strftime("%d/%b/%Y %H:%M:%S")
    log_message = f'{request.remote_addr} - - [{current_time}] "{request.method} {request.path} HTTP/1.1" {response.status_code} -'
    log.info(log_message)
    return response

if __name__ == '__main__':
    serve(app, host='127.0.0.1', port=8000)

SELinux の設定

SELinux が原因で接続できない場合、Apacheが外部のネットワークに接続できるように設定を変更してみます。以下のコマンドを実行します。

sudo setsebool -P httpd_can_network_connect 1

また、8000番ポートがブロックされている場合は、以下のコマンドを実行します。

sudo semanage port -m -t http_port_t -p tcp 8000

一度、Apache を再起動してページが表示されるか確認します。

sudo systemctl restart httpd

Apache をプロキシサーバーとして起動する

Apache をプロキシサーバーとして接続する設定をします。/etc/httpd/conf/httpd.confに、以下の内容を追加します。

/etc/httpd/conf/httpd.conf

<VirtualHost *:80>
  ProxyPass / http://localhost:8000/
  ProxyPassReverse / http://localhost:8000/
</VirtualHost>

Waitress をデーモン化する

Systemdユニットファイルの作成して、Waitressをデーモン化します。

まず、/etc/systemd/system/waitress.serviceという名前でユニットファイルを作成します。

以下の設定はディレクトリ構造が以下の場合の設定内容です。

ディレクトリ構成

  • home
    • user
      • myapp
        • bin # WorkingDirectory
        • flaskapp # Environment
          • flaskapp

/etc/systemd/system/waitress.service

[Unit]
Description=Waitress Flask App
After=network.target

[Service]
Type=simple
User=user
Group=user
WorkingDirectory=/home/user/myapp/flaskapp
Environment="PATH=/home/user/myapp/flaskapp/bin"
ExecStart=/home/user/myapp/flaskapp/bin/waitress-serve --port=8000 flaskapp.app:app
Restart=always

[Install]
WantedBy=multi-user.target

/home/user/myapp/flaskapp/bin/waitress-serveのファイルには、実行権限がついている必要があります。以下のコマンドを実行してファイルの実行権限を確認します。

ls -al /home/user/myapp/flaskapp/bin/waitress-serve

systemdデーモンの再読み込み ユニットファイルを追加・変更した場合は、以下のコマンドでsystemdに再読み込みさせます。

sudo systemctl daemon-reload
sudo systemctl enable waitress
sudo systemctl start waitress
sudo systemctl status waitress

waitress のステータスがfailedとなっている場合、SELinux を一度permissiveにして、エラーが解消されるか試してみます。

エラーが解消されれば、SELinux が原因の為、エラーを解消していきます。

journalctl -xe | grep SELinuxを実行し、エラーを確認します。

5月 21 21:06:19 localhost.localdomain setroubleshoot[980]: SELinux により、/usr/bin/lsmd による getattr アクセスが、ファイル /usr/bin/passt-repair で拒否されました。 完全な SELinux メッセージを見るには、sealert -l 96302691-bdb1-45bb-acdb-1fc739f33f20 を実行します

上記のようなログがあった場合、sealert -l 96302691-bdb1-45bb-acdb-1fc739f33f20 を実行し、内容を確認しポリシーの設定を登録していきます。設定の仕方はメッセージに記載されています。