ディレクトリ構成
- 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 が原因のため設定を変更します。
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
/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 を実行し、内容を確認しポリシーの設定を登録していきます。設定の仕方はメッセージに記載されています。