ハッカソン個人備忘録④：FastAPI + Next.js を Docker で動かすローカル開発環境構築ガイド（モノレポ構成）

## はじめに

ローカル開発を始めるにあたって、FastAPI（バックエンド）と Next.js（フロントエンド）を Docker + Docker Compose を使って構築するのがオススメです。

:::note info
**個人の備忘録程度の走り書きとなっておりますが、温かい目で見守っていただければ幸いです。**
:::

以下では、必要なディレクトリ構成やセットアップ手順、動作確認方法までをまとめています。

---

## ☖ ディレクトリ構成

```
your-app/
├── backend/                # ← FastAPIプロジェクト
│   ├── app/
│   │   └── main.py         # ← FastAPIエントリポイント
│   ├── requirements.txt    # ← Python依存ライブラリ
│   └── Dockerfile          # ← backend用Dockerfile
├── frontend/               # ← Next.jsプロジェクト
│   ├── Dockerfile          # ← frontend用Dockerfile
│   ├── next.config.js      # ← Next.js設定ファイル
│   ├── package.json        # ← npm初期化後に自動生成
│   ├── package-lock.json   # ← npm初期化後に自動生成
│   └── ...                 # ← その他Next.jsコード
├── docker-compose.yml      # ← Docker Compose設定
└── README.md               # ← 起動方法など
```

---

## ⚙️ docker-compose.yml

```yaml
version: '3.9'

services:
  backend:
    build: ./backend
    container_name: fastapi_app
    ports:
      - "8000:8000"
    volumes:
      - ./backend:/app
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

  frontend:
    build: ./frontend
    container_name: nextjs_app
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
    command: npm run dev
```

---

## 🐍 backend/Dockerfile

```Dockerfile
FROM python:3.11

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
```

### backend/requirements.txt

```
fastapi
uvicorn[standard]
```

### backend/app/main.py

```python
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI!"}
```

---

## 🗪 frontend/Dockerfile

```Dockerfile
FROM node:18

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . .

CMD ["npm", "run", "dev"]
```

---

## ✨ frontend初期化

```bash
cd your-app/frontend
npx create-next-app@latest . --typescript
```

---

## ✅ 起動

```bash
cd your-app
docker compose up --build
```

---

## 🌐 動作確認

- FastAPI: http://localhost:8000
- Next.js: http://localhost:3000

---

## ⚡️ シェルスクリプト (init_project.sh)

```bash
#!/bin/bash

PROJECT_NAME="your-app"

# 1. ディレクトリ作成
mkdir -p ${PROJECT_NAME}/backend/app
mkdir -p ${PROJECT_NAME}/frontend

# 2. FastAPI main.py
cat <<EOF > ${PROJECT_NAME}/backend/app/main.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/")
def read_root():
    return {"message": "Hello from FastAPI!"}
EOF

# 3. FastAPI requirements.txt
cat <<EOF > ${PROJECT_NAME}/backend/requirements.txt
fastapi
uvicorn[standard]
EOF

# 4. FastAPI Dockerfile
cat <<EOF > ${PROJECT_NAME}/backend/Dockerfile
FROM python:3.11

WORKDIR /app

COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt

COPY . .
EOF

# 5. docker-compose.yml
cat <<EOF > ${PROJECT_NAME}/docker-compose.yml
version: '3.9'

services:
  backend:
    build: ./backend
    container_name: fastapi_app
    ports:
      - "8000:8000"
    volumes:
      - ./backend:/app
    command: uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

  frontend:
    build: ./frontend
    container_name: nextjs_app
    ports:
      - "3000:3000"
    volumes:
      - ./frontend:/app
    command: npm run dev
EOF

# 6. README.md
cat <<EOF > ${PROJECT_NAME}/README.md
# ${PROJECT_NAME}

## 起動

\`\`\`bash
docker-compose up --build
\`\`\`

## アクセス

- FastAPI → http://localhost:8000
- Next.js → http://localhost:3000
EOF

# 7. Next.js プロジェクト初期化
cd ${PROJECT_NAME}/frontend
echo "▶️ Next.js プロジェクトを初期化中..."
npx create-next-app@latest . --typescript --no-git --eslint

# 8. Dockerfile 生成（初期化後に）
cat <<EOF > Dockerfile
FROM node:18

WORKDIR /app

COPY package.json package-lock.json ./
RUN npm install

COPY . .

CMD ["npm", "run", "dev"]
EOF

# 9. next.config.js（最小構成）
cat <<EOF > next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {}

module.exports = nextConfig
EOF

# 10. アプリ起動！
cd ..
echo ""
echo "🚀 Docker Compose でアプリを起動します..."
docker compose up --build
```

---

## まとめ
ここまでお読みいただき、ありがとうございました。これで **FastAPI + Next.js を Docker で開発するための準備** はひととおり完了です！  

個人の備忘録程度の内容ではありますが、**温かく見守っていただければ幸いです。** 引き続き、**記事のアウトプットも頑張っていきます！**