【Amazon EC2 + Flask + Docker + SQLite】Amazon EC2上にFlaskプロジェクトをデプロイする方法

# はじめに
本記事ではAmazon EC2上にFlaskプロジェクトをデプロイする方法を解説します。基本的にはコピペで作業が完了するよう解説していきますので、とりあえずデプロイを体験してみたいという方は参考にしてください。

# 目次

1. [完成図](#完成図)
2. [Webサーバの作成](#webサーバの作成)
2. [ElasticIPの割り当て](#elasticipの割り当て)
2. [DBサーバの作成](#dbサーバの作成)
2. [Webサーバの設定](#webサーバの設定)
3. [参考文献](#)



# 完成図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/f055d2b2-134f-98b5-5530-bfc63c53c689.png)

Flaskプロジェクトをデプロイするための最小構成で構築予定です
サーバを立ち上げてそこにFlaskプロジェクトをデプロイします


# Webサーバの作成
### Webサーバとは
インターネットからリクエストを受け取り、ウェブページやその他のウェブリソースを提供するコンピュータやプログラムです
Webサーバの作成と書いてありますが、本節ではlinux環境(Amazon Linux2)を作成するところまで作業を進めて、後ほどlinuxにWebサーバの一つであるnginxをインストールしていきます


### Webサーバの作成手順
マネジメントコンソールの検索バーからEC2を起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/65ccad99-68eb-7d5d-8802-2bc4a631863a.png)

インスタンスを起動をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/6442b48f-4f2b-19ab-e972-e0c5aad35105.png)

名前にWebServerと記入
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/0fc935f8-2bfa-8f58-e376-73be1b4096c8.png)

AMIでAmazonLinux2を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/a7070e96-0244-247e-6d09-5eebf87d6ceb.png)

新しいキーペアの作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/24fae01b-17f3-8939-83eb-3ce8d98ea4aa.png)

鍵の名前をWebServerKeyにしてキーペアを作成をクリック（作成したサーバにアクセスするためのカギを作成しています）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/5e558af2-f9d6-2b8a-94b4-ad7e18a89a87.png)

ネットワーク設定の編集ボタンをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/1354f112-3c9f-3a3f-b969-5aecccbd6f43.png)

セキュリティグループの内容を以下の通り編集(今回はhttp通信と、Flaskプロジェクトへのアクセスに必要な5000番ポートの通信を許可しています。むやみに通信を許可するとセキュリティ上のリスクが増加しますので、通信の許可は最小限にしましょう)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/278404cf-dd0f-5f1c-0069-2b147fa46107.png)

ストレージ設定で容量を16GBに設定します（場合によっては必要ないですが、念のためデフォルトより多めに容量を確保しておきます。容量不足の際は後から変更も可能です）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/a257a4ae-1500-7966-a4af-066d5c0e3faf.png)

インスタンスを起動をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/48c12f03-f322-6de5-b537-d84f3a1cb300.png)

これでWebサーバの作成が完了しました。
この後作成したサーバにIPアドレスを割り振って接続をしていきます。

# ElasticIPの割り当て
### ElasticIPとは
静的なパブリックIPアドレスで、インターネットからFlaskプロジェクトにアクセスする際に使用します
インスタンスの停止や再起動に伴い、パブリックIPの内容が書き換わってしまうため、静的なパブリックIPであるElasticIPを割り振ります

### ElasticIPの割り当て手順
EC2の画面でElastic IPをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/d7659a56-80af-cd66-ce8b-1cdceae39ebb.png)

Elastic IPアドレスを割り当てるをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/9cf4df5e-1d52-6fbd-70a5-9f81c76f14fd.png)

割り当てをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/21d1b983-22ed-1d03-9563-b2ced6fcb2c7.png)

このElastic IPアドレスを関連付けるをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/169118ae-682a-a836-d30b-24e2063c3bc3.png)

インスタンスでWebServerを選択して関連付けるをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/a2511c1b-28f3-7abc-4809-288dbf901176.png)

これでElasticIPの割り当ては完了です
これによりサーバにアクセスする際に使用するIPアドレスを固定化することができます



# Webサーバの設定
### サーバの接続

tera termを使って先ほど作成したサーバに接続します
以下の手順を順に実行してください

tera termを起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/f8d0a7bc-2715-e8ec-53af-69e5adf7de59.png)

tera termをインストールしていない場合は以下のサイトからインストールしてください（Amazon Linux2023にも接続できるようtera term5.0 beta1のインストール先を貼っています。5.0より前のものではAmazon Linux2023にアクセスできません。）

https://github.com/TeraTermProject/osdn-download/releases/tag/teraterm-5.0_beta1

EC2で作成したWebServerにチェックを入れてパブリックIPv4アドレスをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/74dff9ee-ad36-e3ee-d98e-c301dd927250.png)

tera termのホストにパブリックIPv4アドレスを貼り付けてokをクリック(本記事の公開後このIPアドレスは削除しております)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/3ad2d8a0-7717-44b8-66e8-6ce8355fa982.png)

ユーザ名に「ec2-user」と入力し秘密鍵にWebServerKey.pemを選択してokをクリック(ec2-userはデフォルトで作成されているユーザの名前です)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/ce094cb6-0572-e4e2-d25a-b2314ab9020d.png)

鳥が羽ばたけば接続成功です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/31b008c8-0c2a-9a97-73e8-2388b7431f4e.png)

これ以降サーバに接続する際はこの手順を踏んでください

### プログラムの配置

Flaskプロジェクトのデプロイに必要な作業を進めます
以下の手順を順に実行してください

以下のコマンドを実行(システムのすべてのパッケージを最新のバージョンに更新します)
```
sudo yum update -y
```
実行画面
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/79ba8306-5ec4-f583-d111-be712ce567bd.png)

以下のコマンドを実行(python3.8をインストールします。途中で何かを聞かれたらyキーを押してエンターをクリックしてください)

```
sudo amazon-linux-extras install python3.8
```

実行画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/1d6685e6-666d-4fe1-3412-c3e49405a8cc.png)

以下のコマンドを実行(zipファイルを解凍するパッケージをインストール。flaskプロジェクトをzip形式で転送して解凍する際に使用します)

```
sudo yum install unzip
```

実行画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/1fb1e6de-fe56-43fc-d291-4243a6f0ea59.png)

以下のコマンドを実行(venvという名前の仮想環境を作成)

```
python3.8 -m venv venv
```

実行画面(以下の通りlsコマンドを使って、venvというフォルダが作成されていることを確認してください)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/d9549a1b-2bb3-7436-0e2b-5ce7a40748cb.png)


Flaskプロジェクトをzipにしてtera termにドラッグアンドドロップ→okをクリック（Flaskプロジェクトは直下にapp.pyがあるようなディレクトリ構成にしてください）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/ae8de3b4-eeef-3272-1909-3e30960b4fc7.png)

Flaskプロジェクトを実行している環境で以下のコマンドを実行してrequirements.txtを作成(Flaskプロジェクトを実行する際に必要なモジュール一覧を生成します。今アクセスしているサーバではなくご自身がFlaskプロジェクトを作成して実行している環境下で実行してください)
```
pip freeze -> requirements.txt
```

同様の方法でrequirements.txtもドラッグアンドドロップしてサーバに転送

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/ae8de3b4-eeef-3272-1909-3e30960b4fc7.png)

lsコマンドを実行してFlaskプロジェクトとrequirements.txtファイルが存在することを確認してください(本記事ではchapter5.zipという名前でFlaskプロジェクトを作成しています)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/a7d98424-b87e-2f66-45e3-792505a96af2.png)

以下のコマンドを実行(zipファイルを解凍します。ファイル名はご自身の環境に合わせて読み替えてください)

```
unzip chapter5.zip
```

実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/6c78e4ea-5ed0-d9a0-0a02-4ae9c1cec29c.png)

以下のコマンドを実行(仮想環境に入ります)

```
source ~/venv/bin/activate
```

実行例(カーソル行にvenvと表示されていることを確認してください)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/42fce558-d5c2-a63b-2063-fc82e8b7174f.png)

以下のコマンドを実行(Flaskプロジェクトを実行するために必要なモジュール一式をインストールします。プラットフォームの違いによってエラーが発生する可能性があります。適宜requirements.txtの内容を書き換えてご対応ください)

```
pip install -r requirements.txt
```

実行例(エラーメッセージが表示されていないことを確認してください)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/ccf614cb-01c9-f589-174f-3b5091638406.png)

### サーバのインストール

以下のコマンドを実行(Webサーバのインストールを行います。途中で何かを聞かれたらyキーを押してエンターキーを押してください)

```
sudo amazon-linux-extras install nginx1
```

実行画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/8c85253d-fa6e-1cc6-7bd1-aa734b48cb51.png)


以下のコマンドを実行(WebサーバとFlaskプロジェクトの橋渡しを行う)

```
pip3 install gunicorn
```

実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/35f6e63e-d314-6304-e34e-eb4d870639c3.png)

### アプリケーションの実行設定

cd venvでchapter5フォルダ(Flaskプロジェクトフォルダ)に移動してvi wsgi.pyコマンドを実行してwsgi.pyファイルを以下の通り編集(app.pyのcreate_app関数を実行するように設定しています。ご自身の環境に合わせて書き換えてください)

```python:wsgi.py
from app import create_app

app = create_app()

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

cat wsgi.pyコマンドを使って正しくファイルが作成されていることを確認してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/c0e9ce10-6ac1-5f8b-1625-1bae3377989d.png)

lsコマンドを使って画像の通りchapter5フォルダの中にapp.pyとwsgi.pyとその他必要なファイルが配置されていることを確認してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/5564d87c-4238-8986-8a6c-205998383d29.png)

以下のコマンドを実行(Webサーバの設定ファイルを編集)
```
sudo vi /etc/nginx/nginx.conf
```

以下の通りhttpの中のserver { }の中身を編集してください

```nginx.conf
    server {
        listen       80;
        listen       [::]:80;
        server_name  _;
        root         /usr/share/nginx/html;

        # Load configuration files for the default server block.
        include /etc/nginx/default.d/*.conf;

        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;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        error_page 404 /404.html;
        location = /404.html {
        }

        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
        }
    }
```

以下のコマンドを実行(Webサーバを自動起動する設定)

```
sudo systemctl enable nginx.service
```

実行例
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/c5822d19-d352-beb9-ea80-916c40dd9630.png)


以下のコマンドを実行(Webサーバを起動)

```
sudo systemctl start nginx.service
```

実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/8bbc890f-056d-d262-b8c8-0b54ae5654dd.png)

以下のコマンドを実行(Webサーバの状態を確認するコマンドです。サーバの状態がactiveになっていることを確認してください。)

```
sudo systemctl status nginx.service
```

実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/4b3b40fc-246a-593a-1809-e5dc769c2093.png)


以下のコマンドを順に実行(Flaskプロジェクトで使用するDBを作成するコマンド)
```
flask db init
```
```
flask db migrate
```
```
flask db upgrade
```

実行例

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/ddab1ffd-e61e-260e-44ff-575eb59c94aa.png)

以下のコマンドを実行(gunicornを起動します)

```
gunicorn --bind 0.0.0.0:5000 wsgi:app
```

ブラウザからElasticIP:5000にアクセスして作成したアプリケーションにアクセスできればokです

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3287818/304a0b1e-b025-da29-7900-e2c816c78f65.png)

お疲れさまでした。これで作業は完了です。