ハッカソン個人備忘録⑲：FastAPI + MySQLアプリをFargate ＋ RDSで安定稼働させるための構成変更まとめ

## はじめに

FastAPI を使ってアプリケーションを開発していると、開発環境では Docker Compose を使って MySQL と一緒に動かすケースがよくあります。

:::note info
**しかし、本番環境を AWS Fargate に移行する際には、MySQL を別サービス（Amazon RDS など）として運用することが多くなります。**
:::

本記事では、そのような構成変更をどのように行えばよいのかをまとめています。

## 書こうと思ったきっかけ

ローカルではうまく動いていた FastAPI アプリが、Fargate 上では「MySQL に接続できない」というエラーはよくあります。

:::note warn
***原因は、Docker Compose では MySQL をコンテナで用意していたのに対し、AWS 上では MySQL コンテナを作らず、RDS を使う構成にしていたためでした。***
:::

自分と同じような構成で困っている人の助けになればと思い、記録としてこの記事を書きました。

## FastAPI + MySQL アプリを AWS Fargate 上で動かすときの構成変更について

FastAPI を使ったアプリケーションで、元々は Docker Compose を使い、MySQL コンテナと一緒にローカルで開発していた構成から、AWS Fargate 上で MySQL コンテナを用意せずに運用する場合の変更点をまとめます。

### 想定している元の構成

FastAPI + MySQL コンテナを同一ネットワークで動かしている開発構成では、以下のように接続しています：

```python
connection = mysql.connector.connect(
    host="db",  # コンテナ名で指定
    user=os.getenv("MYSQL_USER"),
    password=os.getenv("MYSQL_PASSWORD"),
    database=os.getenv("MYSQL_DATABASE")
)
```

この場合、`host="db"` のように MySQL コンテナのサービス名をホストとして指定しています。

---

### AWS では MySQL を RDS などの外部サービスとして利用する

Fargate 上では MySQL をコンテナとして立てない方針のため、MySQL は Amazon RDS や Aurora など外部のデータベースサービスを使います。これに合わせてアプリ側の設定を変更する必要があります。

---

### 🔧 変更点

#### 1. 接続先ホストの変更

`host="db"` を環境変数で定義された RDS のエンドポイントに変更します。

```python
host=os.getenv("MYSQL_HOST")
```

`.env` ファイルまたは環境変数に以下を設定：

```dotenv
MYSQL_HOST=your-db-instance.abcdefg.ap-northeast-1.rds.amazonaws.com
MYSQL_USER=youruser
MYSQL_PASSWORD=yourpassword
MYSQL_DATABASE=yourdatabase
```

---

#### 2. `.env` ファイルの読み込み（開発環境用）

ローカル開発では `python-dotenv` を使って `.env` を読み込みます。

```bash
pip install python-dotenv
```

```python
from dotenv import load_dotenv
load_dotenv()
```

本番環境（Fargate）では `.env` は使わず、**タスク定義の環境変数セクションで定義**します。

---

#### 3. Fargate タスク定義に環境変数を追加

以下のようにタスク定義 JSON で設定します：

```json
"environment": [
  { "name": "MYSQL_HOST", "value": "your-rds-endpoint.amazonaws.com" },
  { "name": "MYSQL_USER", "value": "youruser" },
  { "name": "MYSQL_PASSWORD", "value": "yourpassword" },
  { "name": "MYSQL_DATABASE", "value": "yourdatabase" }
]
```

---

### ✅ 修正後のコード例

```python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
import mysql.connector
import os
from dotenv import load_dotenv

load_dotenv()  # 開発用。Fargate では不要

app = FastAPI()

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI + MySQL in AWS!"}

@app.get("/db-status")
def db_status():
    try:
        connection = mysql.connector.connect(
            host=os.getenv("MYSQL_HOST"),
            user=os.getenv("MYSQL_USER"),
            password=os.getenv("MYSQL_PASSWORD"),
            database=os.getenv("MYSQL_DATABASE")
        )
        if connection.is_connected():
            connection.close()
            return {"db_status": "connected"}
        else:
            return {"db_status": "not connected"}
    except Exception as e:
        return {"db_status": "error", "details": str(e)}
```

---

## まとめ

- Docker Compose の MySQL コンテナは AWS では RDS に置き換える
- 接続ホストを RDS のエンドポイントに変更
- `.env` で管理するなら `python-dotenv` を使う（開発のみ）
- 本番ではタスク定義の `environment` で環境変数を指定

このように構成を変えることで、FastAPI アプリを Fargate 上に安全かつ安定してデプロイできると思います！