AWS EC2でFlaskアプリを公開する

AWS EC2でFlaskアプリを公開する プログラミング

この記事では、AWSのEC2(AmazonLinux2023)上でFlaskアプリを公開する方法を解説します。

環境構成

  • 仮想サーバー:EC2(AmazonLinux2023)
  • Webサーバー:Nginx(インストール済み、Basic認証)
  • Appサーバー:Gunicorn×Flask
[ クライアント(ブラウザ) ]
          ↓ HTTP/HTTPS
[ Nginx(Webサーバ) ]
          ↓ リバースプロキシ(転送)
[ Gunicorn(WSGIサーバ) ]
          ↓ WSGIプロトコル
[ Flask(Pythonアプリ) ]
  • Nginxは静的ファイル配信と、リクエストの振り分けを担当。
  • GunicornはPythonコード(Flask)を動かすサーバ。
  • NginxはGunicornにリクエストを渡し、Gunicornが処理した結果を返す。

VPCやサブネットの作成方法は、以下の記事の1~3を確認ください。

Nginxのインストール方法は以下を確認ください。


①Python環境の準備

sudo dnf install python3 python3-pip -y
  • Amazon LinuxにPython3とpip(パッケージ管理ツール)をインストール。
makedir myapp
cd myapp
python3 -m venv venv
  • Pythonの仮想環境を作成。
  • システムのPython環境と切り離して、アプリ専用の環境を作るため。
source venv/bin/activate
  • 仮想環境を有効化
  • これ以降のPythonコマンドやpipはこの仮想環境内のものを使う。
pip install flask gunicorn
  • Flask(Webフレームワーク)とGunicorn(WSGIサーバー)を仮想環境内にインストール。

②Flaskアプリの設置

例として、

/home/ec2-user/myapp/app.py に下記コードを作成。

from flask import Flask
app = Flask(__name__)

@app.route('/')
def hello():
    return 'Hello from Flask on Amazon Linux 2023!'
  • Flaskアプリの基本形。
  • /(トップページ)にアクセスがあったらメッセージを返す。

wsgi.pyはGunicornがFlaskアプリを起動するための入り口となるファイル。

from app import app

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

③Gunicornで起動テスト(推奨)

ローカル環境内(127.0.0.1)からのみFlaskに接続できるようにGunicornで起動します。

cd /home/ec2-user/myapp
source venv/bin/activate
gunicorn -w 4 -b 127.0.0.1:8000 wsgi:app
  • source venv/bin/activate:仮想環境を有効化。
  • gunicorn:Gunicorn起動コマンド。
  • w 4:ワーカー(並列処理数)を4つに設定。
  • b 127.0.0.1:8000:ローカルホスト(同サーバー)の8000番ポートでのみ待ち受けする入口。接続を許可するネットワーク。(0.0.0.0にしたら全ネットワークが接続可能)
  • wsgi:appwsgi.pyの中のappオブジェクトを使う指定。

動作確認

curl <http://127.0.0.1:8000/>
  • 端末からローカルで動いているFlaskにアクセスして結果を確認。

④Nginxの設定(リバースプロキシ)

/etc/nginx/conf.d/myapp.confに設定を書きます。

server {
    listen 80;
    server_name your-domain.com; **#EC2のIPアドレス**

    location / {
        proxy_pass <http://127.0.0.1:8000>; **#必須**
        proxy_set_header Host $host; #オプション
        proxy_set_header X-Real-IP $remote_addr; #オプション
    }
}
  • listen 80:HTTPの標準ポートで受ける。
  • server_name:アクセスを受けるドメイン名(ない場合はIPでもOK)。

💡サーバーネームは必須ではないが推奨
Nginx は 1つのIPアドレスで複数のサイトをホストできる「バーチャルホスト機能」があります。

  • example.com にアクセス → 1つ目の server ブロックが処理
  • api.example.com にアクセス → 2つ目が処理

という 「リクエストの Host ヘッダーに基づいた振り分け」 が可能になります。

⚠️サーバブロックの優先順位

  • ブラウザで http://43.207.120.123 にアクセスすると、Host ヘッダは 43.207.120.123
  • Nginx はまず server_name43.207.120.123 が完全一致する server ブロックを探す
  • 見つからなければ、デフォルトの server を使う
    • この「デフォルト」は、次のいずれかです:
      • listen 80 default_server; があるブロック
      • もしそれがなければ、最初に定義された listen 80 のブロック
  • proxy_pass:Nginxが受けたリクエストをGunicornへ転送する転送先。
  • proxy_set_header:クライアントが接続した際の元のリクエスト情報をGunicornに渡す設定。
sudo nginx -t
  • Nginxの設定ファイルが正しいかテスト。
sudo systemctl reload nginx
  • 設定変更を反映してNginxを再起動(停止せずに更新)。

⑤Gunicornをsystemdサービス化(常駐化)

/etc/systemd/system/myapp.serviceファイルを作成。

[Unit]
Description=Gunicorn for Flask app
After=network.target #ネットワークが有効になった後にこのサービスを起動する。

[Service]
User=ec2-user
Group=ec2-user
WorkingDirectory=/home/ec2-user/myapp
ExecStart=/home/ec2-user/myapp/venv/bin/gunicorn -w 4 -b 127.0.0.1:8000 wsgi:app
Restart=always

[Install]
WantedBy=multi-user.target
項目意味
User=ec2-userこのサービスを実行するLinuxユーザー(権限)。指定しないとroot権限で実行する可能性があり、脆弱性があった場合に危険
Group=ec2-user実行時のグループ
WorkingDirectory=/home/ec2-user/myapp作業ディレクトリ(この中でコマンドを実行)➡上記で作成したPythonの仮想環境
ExecStart=...実際に実行されるコマンド→ Gunicornを仮想環境内から起動
Restart=always落ちたときに自動再起動(安定性UP)
WantedBy=multi-user.targetLinuxの「通常のマルチユーザーモード」(サーバー用途)この行があることで「sudo systemctl enable myapp」でサーバー起動時にこのサービスも自動起動します。
  • systemdに「myapp」というサービスを登録。
  • サーバ起動時にGunicornも自動で起動。
  • Gunicornの実行ユーザー、作業ディレクトリ、実行コマンドを指定。
sudo systemctl daemon-reexec
  • systemdの設定を読み込み直す。
sudo systemctl enable myapp
  • OS起動時にサービスを自動起動する設定。
sudo systemctl start myapp
  • サービスを起動(Gunicornも起動)。

Appファイルを変更した場合の反映方法

sudo systemctl restart myapp

これで Gunicorn プロセスが再起動され、新しいコードが読み込まれて即反映されます


最終確認

  • ブラウザで http://<サーバーのIPまたはドメイン> にアクセス
  • Flaskアプリのメッセージが表示されればOK!

タイトルとURLをコピーしました