Flaskを使ってDocker、PythonでHello Flask

## はじめに
前回はDockerとPythonを使ってコンテナの中で"Hello World"をしてみました。
今回はPythonのWebフレームワークの一つであるFlaskを使ってHTMLページを表示します。
前回の記事は[こちら](https://qiita.com/Pitts7/items/d8046190775335fb7e47)

## Flaskとは
PythonのWebフレームワークの一つで、他のWebフレームワークよりもフレームワークの仕様に縛られることなく、アプリ開発が可能です。
他にもDjangoやBottleなどが有名です。

## 環境
```
macOS Ventura 13.0.1
Docker Desktop for Mac
Docker version 20.10.21
Docker Compose version v2.13.0
VS code
```

### ゴール
今回のゴールはFlaskでHTMLページを読み込んで、localhost上で表示することです。

## 構成
```
.
├── Dockerfile
├── docker-compose.yml
├── app.py
├── requirements.txt
└── templates
    └── index.html
```

## 作業ディレクトリの作成
初めに作業ディレクトリを用意します。

```
mkdir docker_python_flask && cd docker_python_flask
```

## Dockerfile
dockerコンテナをbuildするDockerfileを作成します。

```dockerfile:Dockerfile
FROM python:3.9.10

WORKDIR /

ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

COPY requirements.txt ./

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install -r requirements.txt

COPY . .
CMD ["flask", "run"]
```
Flaskを利用するために追加したコードを中心にみていきます。
※前回の記事で説明しているところは省きます。
```
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0
```
Dockerコンテナ内でflask runを使用するにはENVに環境変数を指定する必要があります。
```
COPY requirements.txt ./
```
requirements.txt をコピーし、Pythonの依存関係をインストールします。

```
pip install -r requirements.txt
```
設定ファイルrequirements.txtに従ってパッケージが一括インストールされます。

```
CMD ["flask", "run"]
```
CMDはDockerコンテナ内で実行するコマンドのことです。
CMDは起動時に一度実行されるのでコンテナそのものを動かすコマンドと考えましょう。

## docker-compose.yml

```yml:docker-compose.yml
version: '3.9'
services:
  python3:
    restart: always
    build: .
    container_name: 'python3'
    working_dir: '/'
    tty: true
    ports:
      - "8000:5000"
```
ymlファイルは前回からあまり変更はないです。
最後のポートはFlaskウェブサーバのデフォルトのポート：5000とLocalhostで公開するポート：８０００を繋いでいます。

## requirements.txt
Flaskのインストールを記述します。

```text:requirements.txt
flask
```
==などでパッケージのバージョンを指定できます。今回のように何も記載しない場合は最新バージョンとなります。

## app.py

```python:app.py
from flask import Flask, render_template

app = Flask(__name__)

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

if __name__ == '__main__':
    app.run()
```
1行目でFlaskとrender_templateをインポートしています。
render_templateとは、templatesフォルダから引数に指定したhtmlファイルを読み込む関数です。

```python
@app.route('/')
```
localhostのアクセス先を指定しています。
今回の場合は http://localhost:8000/ です。
```python
def index():
    return render_template('index.html')
```
http://localhost:8000/ にアクセスした時にindex.htmlを表示するという意味です。

## index.html
最後にapp.pyファイルが保存してある場所と同じディレクトリに「templates」という名前でフォルダを作成します。
作成したフォルダの中にindex.htmlファイルを用意します。
今回は画面に表示することを目的としているため、シンプルなHTMLファイルとなっています。

```html:index.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <title>Flask</title>
        <meta charset="utf-8"/>
    </head>
    <body>
        <h1>Hello Flask</h1>
    </body>
</html>
```

## 実行
実際に動かしてみましょう。
まずビルドします。
```terminal
docker-compose build
```
ビルドができたら、docker-compose upします。
前回はコンテナ内でPythonを起動していたため、
docker-compose up -dでオプションをつけていましたが今回はなしで行います。

```terminal
docker_python_flask % docker-compose up
[+] Running 1/0
 ⠿ Container python3  Created                                                                                      0.0s
Attaching to python3
python3  |  * Serving Flask app 'app.py'
python3  |  * Debug mode: off
python3  | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
python3  |  * Running on all addresses (0.0.0.0)
python3  |  * Running on http://127.0.0.1:5000
python3  |  * Running on http://172.24.0.2:5000
python3  | Press CTRL+C to quit
```
上記のようになりましたら、
http://localhost:8000/ にアクセスしてみましょう。

index.htmlに記述したことが表示されていると思います。

![スクリーンショット 2022-12-11 23.09.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2741139/2e1573a6-2cfe-2190-b6cd-ff318c8960a5.png)

## 最後に
今回は前回に引き続きDockerでPythonを使い、WebフレームワークのFlaskを使ってみました。
今後はDjangoも使ってみたいですし、機能も追加したいので少しずつ実装していきたいと思います。