この記事では、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:app
:wsgi.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_name
に43.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.target | Linuxの「通常のマルチユーザーモード」(サーバー用途)この行があることで「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!
