FlaskアプリをApacheで動かす

# 1. 概要
仮想マシンでWebサーバを作り、flaskで作ったアプリを動かす。

# 2. 前提
- VMwareにAlmaLinuxがインストールされていること

※インストールされていない場合は以下のリンクの手順でインストールしてください。

https://qiita.com/hosoya17/items/0e0c0a7437a01c3bc22d

# 3. 事前準備
- VMwareで作成したLAMP_SVの起動
- TeraTermでLAMP_SVにSSH接続する(見やすい環境で操作したい人向け)
- rootユーザにログインする

https://qiita.com/hosoya17/private/afb1ca1b17bfb67020cc

# 4. 環境構築

### 4-1. Pythonのインストール
```bash
yum update
```
```bash
dnf install python39
```
※ `python3.9`ではなく`python39`が正しい。

### 4-2. pipのインストール
```bash
dnf install python3-pip
```

### 4-3. 開発ツールのインストール
```bash
dnf groupinstall "Development Tools"
dnf install python3-devel
dnf install httpd-devel
```

### 4-3. venvの設定
仮想環境を作成
```bash
python3 -m venv venv
```

仮想環境をアクティブにする
```bash
source venv/bin/activate
```

### 4-4. 各種ライブラリインストール
インストールするライブラリ
- flask
- Jinja2
- SQLAlchemy(使用する方のみ)

```bash
pip3 install flask Jinja2 flask-sqlalchemy mod_wsgi
```
ライブラリがインストールできたか確認する。
```bash
pip3 list
```
仮想環境から抜ける。
```bash
deactivate
```

### 4-4. Apacheのインストール
```bash
dnf install httpd
```

### 4-5. wgetのインストール
```bash
dnf install wget
```

### 4-6. mod_wsgiのインストール
mod_wsgiをソースからダウンロードする。
```bash
wget https://github.com/GrahamDumpleton/mod_wsgi/archive/4.9.0.tar.gz
tar xzf 4.9.0.tar.gz
cd mod_wsgi-4.9.0
./configure --with-python=/usr/bin/python3
make
make install
```

pip3でもインストールする。
```bash
pip3 install mod_wsgi
```


### 4-7. 設定ファイル
ディレクトリを作成する。
```bash
mkdir /var/www/practice
```

Apacheの設定
```bash
vi /etc/httpd/conf.d/practice.conf
```

practice.confの内容
※`ServerAlias`はご自分のLAMP_SVのIPアドレスに
```conf
<VirtualHost *:80>
    ServerName localhost
    ServerAlias 192.168.0.23

    WSGIDaemonProcess practice user=apache group=apache threads=5
    WSGIScriptAlias / /var/www/practice/app.wsgi

    <Directory /var/www/practice/flaskr>
        WSGIProcessGroup practice
        WSGIApplicationGroup %{GLOBAL}
        Require all granted
    </Directory>

    ErrorLog /var/log/httpd/practice_error.log
    CustomLog /var/log/httpd/practice_access.log combined
</VirtualHost>
```

app.wsgiファイルの作成
```bash
vi /var/www/practice/app.wsgi
```

app.wsgiの内容
```python
import sys
import logging
import os
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/var/www/practice/")

from flaskr import app as application
```

mod_wsgi-expressを使用して、Apacheの設定ファイルを自動生成する。
```bash
mod_wsgi-express install-module > /etc/httpd/conf.modules.d/02-wsgi.conf
```

Apacheを起動する。
```bash
systemctl start httpd
```

ファイアウォールを停止させる。
```bash
systemctl stop firewalld
```

SELinuxを無効化する。
`/etc/selinux/config`ファイルを開く
```bash
vi /etc/selinux/config
```

SELINUXの行を以下のように変更し上書き保存する。
```bash
SELINUX=disabled
```

システムを再起動する。
```bash
reboot
```

再起動後、SELinuxの状態を確認する。
```
getenforce
```
Disabledと表示されれば成功。

# 5. Visual Stdio CodeからSSH接続する
これからPythonやhtmlなどのコーディングになる。
コーディングはVisual Stdio Codeで行うことを推奨する。
接続方法は以下のリンクから。

https://qiita.com/hosoya17/private/bcf49ea1d238871cd943


# 6. コーディング

コーディングの前にflaskをインストールする。
```bash
pip3 install flask
```

`/var/www/practice`に以下のディレクトリ構造でディレクトリやファイルを作成する。
```
└── flaskr/
    ├── templates/
    │   └── index.html
    ├── __init__.py
    ├── main.py
    └── db.py
```

各ファイルの内容は以下の通り。
```python:\_\_init__.py
from flask import Flask
app = Flask(__name__)
import flaskr.main
```

```python:main.py
from flaskr import app
from flask import render_template

@app.route('/')
def index():
    return render_template(
        'index.html'
    )
```

```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>テスト</title>
</head>
<body>
    <p>テストだよ！</p>
</body>
</html>
```

`db.py`には何も記述しなくて良い。いずれ使用することになる。

apacheを再起動する
```bash
systemctl restart httpd
```

ブラウザにサーバのIPアドレスを入力し、以下の様に表示されたら成功。
![index_html.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3885685/fd72833b-5b1b-6fa6-8367-dbfc54364a0d.png)

# 7. セッションを使用する場合
localhostでは`__init__.py`に以下の様に記述していたかと思う。

```python:\_\_init__.py
from flask import Flask
app = Flask(__name__)

import flaskr.main

import os
app.secret_key = os.urandom(24)

from datetime import timedelta
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1)
```

しかし、Apacheの場合はsecret_keyを固定値にしないとすぐにセッションが切れてしまう為、`app.wsgi`と`__init__.py`を以下の様にする必要がある。

```python:app.wsgi
import sys
import logging
import os
logging.basicConfig(stream=sys.stderr)
sys.path.insert(0, "/var/www/travel_plan/")

# 以下を追記
os.environ['SECRET_KEY'] = "任意の値を設定"

from flaskr import app as application
```

```python:__init__.py
from flask import Flask
app = Flask(__name__)

import flaskr.main

import os
# app.secret_key = os.urandom(24)を以下に変更
app.secret_key = os.getenv('SECRET_KEY')

from datetime import timedelta
# 以下を追記
app.config['SESSION_COOKIE_HTTPONLY'] = True
app.config['SESSION_COOKIE_SAMESITE'] = 'Lax'
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1)
```

# 8. おまけ
プログラムをGitで管理したい方は以下のリンクから設定してください。

https://qiita.com/hosoya17/items/7333e760f490bbc7336f

また次回以降、起動手順やエラーログの確認方法、データベースの使用方法については以下のリンクをご覧ください。

https://qiita.com/hosoya17/items/76a3a4e4593b1d16a184

# 参考記事
[VMwareにAlma Linuxをインストールし、Flaskアプリをデプロイ（後編）](https://qiita.com/nikorasu277/items/2986b6e246aaf8a8a909)

[Flask + mod_wsgi + Apache でWEBアプリを作る(HelloWorld編)](https://qiita.com/NAKA_G/items/f34738df364af8cbd58e)