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

Nginx のインストール

以下のコマンドを実行して、Nginx をインストールします。

sudo dnf -y install nginx

# 起動
sudo systemctl start nginx


# 自動起動の有効化
sudo systemctl enable nginx

ファイアウォールの設定を行います。

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

ブラウザで、サーバーのIPアドレスのページにアクセスしページが表示されれば Nginx のインストールは完了しています。

Python、pyenv、venv の設定

Python、pyenv、venv のインストールや設定については、以下のページを参考にしてください。

仮想環境を作成し、その中で Flask アプリを稼働させます。

仮想環境は、「 home/user/myapp/flaskapp 」を仮想環境のディレクトリとします。

Flask と Waitressをインストールするには、以下のコマンドを実行します。

pip install flask waitress

Nginx をプロキシサーバーとして稼働

リバースプロキシとしての設定を「 proxy.conf 」に設定を行います。

/etc/nginx/conf.d/proxy.conf

server {
    listen 80;
    server_name example.com;

    location / {
        proxy_pass http://127.0.0.1:8000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

Flask アプリを起動

Flask アプリについては、以下のリンクを参考にしてください。

venv の仮想環境の中に入り、以下のコマンドを実行します。

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

ブラウザでサーバーのIPアドレス:8000/myappにアクセスし、ページが表示されれば完了です。

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 nginx

それでも表示されない場合は、一度 Linux を再起動してみます。

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 を実行し、内容を確認しポリシーの設定を登録していきます。設定の仕方はメッセージに記載されています。

その他の可能性

Python に関する制限が影響している可能性がある場合は、httpd_execmemなどの設定を確認し、無効になっている場合は有効にします。

sudo getsebool -a | grep httpd_execmem

# 無効になっている場合は、有効にする
sudo setsebool -P httpd_execmem on
sudo setsebool -P domain_can_mmap_files on