XREAでFlaskを動かす方法 (CGI)

はじめに

XREAのレンタルサーバにFlaskを設置した時の忘却録です。

このページでは、Flaskが最低限動作する環境を構築することが目標です。

公式のチュートリアルと違うところは、XREAはWSGIできないのでWSGIサーバでWSGIアプリケーションとして動かさず、CGIスクリプトとして動かすところです。

環境を構築

Flaskが動作する環境を構築するために、まずはXREAサーバにssh接続し、Pythonの仮想環境を作成します。仮想環境の中でpipコマンドを使ってFlaskをインストールしていきます。

ssh接続する

XREAのマニュアル / SSHの利用(Mac)をよく読んでssh接続します。

接続するとrbashが立ち上がっています。詳しくないんだけどrbashは制限付きbashらしい。rbashだといつものコマンドが使えなくて不便なのでbashと打ち込みbashを起動します。bash-4.4$と表示されたら、いつも通りのコマンドが使えるようになります。

[your_id@server ~]$ echo $SHELL
/bin/rbash
[your_id@server ~]$ bash
bash-4.4$

Pythonのバージョンを確認する

XREAの仕様のページを見ると、/usr/bin/python3.6が使えると書いています。sshからpythonと打った後にキーボードのTabキーを押すと、pythonから始まるコマンドがリスト表示されます。このリストの中にpython3.9があるので、python3.9までは使えそうです。

bash-4.4$ python[Tab]
python                    python3-config            python3.8
python2                   python3.6                 python3.8-config
python2-config            python3.6-config          python3.8-x86_64-config
python2.7                 python3.6m                python3.9
python2.7-config          python3.6m-config         python3.9-config
python3                   python3.6m-x86_64-config  python3.9-x86_64-config

Python3.9の仮装環境を構築する

ホームディレクトリに移動します

bash-4.4$ cd /virtual/your_id

以下のコマンドでpy39flaskという名前の仮想環境を作ります。そうしたらlsコマンドでカレントディレクトリにpy39flaskが作成されたことが確認できます。(下の例ではpy39flaskディレクトリだけを書いてます。実際には他のファイルやディレクトリがあります。)

bash-4.4$ python3.9 -m venv py39flask
bash-4.4$ ls
py39flask

py39flask環境に入ります。

bash-4.4$ source py39flask/bin/activate

Pythonのバージョンを確認しておきます。Pythonのバージョンが3.9なら成功です。

(py39flask) bash-4.4$ python --version
Python 3.9.16

Flaskをインストールする

さっそくFlaskをインストールしたいところですが、pipをバージョンアップしておきます。私の環境ではpip-20.2.4からpip-24.0にバージョンアップされたようです。

(py39flask) bash-4.4$ python -m pip install --upgrade pip
Collecting pip
  Downloading pip-24.0-py3-none-any.whl (2.1 MB)
     |████████████████████████████████| 2.1 MB 3.0 MB/s 
Installing collected packages: pip
  Attempting uninstall: pip
    Found existing installation: pip 20.2.4
    Uninstalling pip-20.2.4:
      Successfully uninstalled pip-20.2.4
Successfully installed pip-24.0

いよいよFlaskのインストールです。pip install Flaskを実行するとFlaskが仮想環境にインストールされます。秒で終わります。

(py39flask) bash-4.4$ pip install Flask
Collecting Flask
  Downloading flask-3.0.2-py3-none-any.whl.metadata (3.6 kB)
Collecting Werkzeug>=3.0.0 (from Flask)
  Downloading werkzeug-3.0.1-py3-none-any.whl.metadata (4.1 kB)
Collecting Jinja2>=3.1.2 (from Flask)
  Downloading Jinja2-3.1.3-py3-none-any.whl.metadata (3.3 kB)
Collecting itsdangerous>=2.1.2 (from Flask)
  Downloading itsdangerous-2.1.2-py3-none-any.whl.metadata (2.9 kB)
Collecting click>=8.1.3 (from Flask)
  Downloading click-8.1.7-py3-none-any.whl.metadata (3.0 kB)
Collecting blinker>=1.6.2 (from Flask)
  Downloading blinker-1.7.0-py3-none-any.whl.metadata (1.9 kB)
Collecting importlib-metadata>=3.6.0 (from Flask)
  Downloading importlib_metadata-7.0.1-py3-none-any.whl.metadata (4.9 kB)
Collecting zipp>=0.5 (from importlib-metadata>=3.6.0->Flask)
  Downloading zipp-3.17.0-py3-none-any.whl.metadata (3.7 kB)
Collecting MarkupSafe>=2.0 (from Jinja2>=3.1.2->Flask)
  Downloading MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (3.0 kB)
Downloading flask-3.0.2-py3-none-any.whl (101 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 101.3/101.3 kB 2.4 MB/s eta 0:00:00
Downloading blinker-1.7.0-py3-none-any.whl (13 kB)
Downloading click-8.1.7-py3-none-any.whl (97 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 97.9/97.9 kB 16.5 MB/s eta 0:00:00
Downloading importlib_metadata-7.0.1-py3-none-any.whl (23 kB)
Downloading itsdangerous-2.1.2-py3-none-any.whl (15 kB)
Downloading Jinja2-3.1.3-py3-none-any.whl (133 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 133.2/133.2 kB 43.4 MB/s eta 0:00:00
Downloading werkzeug-3.0.1-py3-none-any.whl (226 kB)
   ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 226.7/226.7 kB 40.9 MB/s eta 0:00:00
Downloading MarkupSafe-2.1.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (25 kB)
Downloading zipp-3.17.0-py3-none-any.whl (7.4 kB)
Installing collected packages: zipp, MarkupSafe, itsdangerous, click, blinker, Werkzeug, Jinja2, importlib-metadata, Flask
Successfully installed Flask-3.0.2 Jinja2-3.1.3 MarkupSafe-2.1.5 Werkzeug-3.0.1 blinker-1.7.0 click-8.1.7 importlib-metadata-7.0.1 itsdangerous-2.1.2 zipp-3.17.0

インストールされたパッケージを確認します。ふ〜んて感じです。

(py39flask) bash-4.4$ pip list flask
Package            Version
------------------ -------
blinker            1.7.0
click              8.1.7
Flask              3.0.2
importlib-metadata 7.0.1
itsdangerous       2.1.2
Jinja2             3.1.3
MarkupSafe         2.1.5
pip                24.0
setuptools         50.3.2
Werkzeug           3.0.1
zipp               3.17.0

フォルダ構成

それではFlaskアプリを作っていきます。

Flaskが動作する最小限のフォルダ構成になります。http://yourdomain.com/にアクセスするとHello World!が表示されます。

(1)~(4)のファイル内容については下で説明しています。

パーミッションは、、app.pyが755、それ以外は644です。

DocumentRoot/
├ .htaccess  ---(1)
├ index.html ---(2)
└ flask_app/
  ├ static/
  ├ templates/
  ├ .htaccess ---(3)
  └ app.py ---(4)

(1) .htaccess

この.htaccessファイルは、Apacheのmod_rewriteモジュールを使用して、リクエストされたURLを再書き換えています。具体的には、クライアントからのリクエストがあった場合に、そのリクエストされたファイルが存在しない場合に、URLを/flask_app/app.py/にリダイレクトします。また、クエリ文字列も保持したままリダイレクトを行います。

ようするにhttp://yourdomain.com/にアクセスするとapp.pyが実行されるようになります。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ /flask_app/app.py/$1 [L,QSA]
RewriteEngine On
mod_rewriteの有効化を指示します。
RewriteCond %{REQUEST_FILENAME} !-f
リクエストされたファイルが存在しない場合にのみ、以降のRewriteRuleを適用する条件を指示します。-fはファイルが存在するかどうかをチェックする条件です。
RewriteRule ^(.*)$ /flask_app/app.py/$1 [L,QSA]
リクエストされたURLを再書き換えします。^(.*)$は任意の文字列にマッチする正規表現です。そして、/flask_app/app.py/$1にマッチした文字列を置き換えます。$1は正規表現でキャプチャされた部分を示します。[L,QSA]はRewriteRuleのオプションで、Lは最後のルールとして処理し、QSAは既存のクエリ文字列を保持することを意味します。

(2) index.html

XREAはDocumentRootにindex.htmlやindex.cgiなどを置いておくルールだったハズです(うろ覚え)。このindex.htmlは無くてもFlaskは動きますが XREAルールに遵守して置いてます。

内容は単純で、http://yourdomain.com/にリダイレクトします。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width,initial-scale=1.0">
  <meta http-equiv="refresh" content="5;url=/">
  <title>Redirecting...</title>
</head>
<body>
  <p style="margin-top:10em;text-align:center;">
  Redirecting to <a href="http://yourdomain.com/">http://yourdomain.com/</a></p>
</body>
</html>

(3) .htaccess

この.htaccessファイルは、Apacheの設定を変更しています。具体的には、ExecCGIオプションを有効にし、.cgiおよび.pyのファイルをCGIスクリプトとして実行するためのハンドラを追加しています。つまり、.cgiと.pyのファイルを実行可能なCGIスクリプトとして扱うようにApacheに指示しています。

Options +ExecCGI
AddHandler cgi-script .cgi .py
Options +ExecCGI
ExecCGIオプションを有効にします。これにより、CGI (Common Gateway Interface) スクリプトを実行することが許可されます。
AddHandler cgi-script .cgi .py
.cgiおよび.py拡張子のファイルに対して、cgi-scriptハンドラを追加します。これにより、Apacheは.cgiおよび.pyのファイルをCGIスクリプトとして認識して、実行します。

(4) app.py

よくあるFlask入門用コードにチョイ足しした感じのコードです。

これでhttp://yourdomain.com/にアクセスするとHello Flaskが表示されます。

注意点です。

#!/virtual/your_id/py39flask/bin/python

# FlaskをCGIで動かすためのハンドラ
from wsgiref.handlers import CGIHandler
# Flask関連
from flask import Flask

app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello Flask"

if __name__ == "__main__":
    CGIHandler().run(app)

最後に

以上でFlaskが動くようになりました。Google検索にはマジ感謝です。Flaskをレンタルサーバで動かす解説記事はたくさんありますが、このページも誰かの参考になってくれれば幸いです。

私は以上のようにFlaskをXREAに設置しました。このページもFlaskで表示しています。

なかなか面白いシステムで興味深いです。フル機能搭載のフレームワークよりもシンプルなものが好きです。

今回Flask設置において勉強になったことをこのページにまとめています。よかったら見てみてください。


since 2006