事前準備
- Python、Node.js、Docker Destop(Windows)をインストールしておく
フォルダ作成
- 適当な階層に新規フォルダ「react-fastapi-docker」を作成し、VSCodeで開く
- プロジェクトフォルダ直下に「frontend」「backend」フォルダを作成
react-fastapi-docker/
├── frontend/
└── backend/
フロントエンドのセットアップ
- VSCodeのターミナルタブから新規ターミナルを開き、frontendフォルダの階層で下記を実行
npm create vite@latest
- 入力を求められた際は下記を選択
Project name | . |
Select a framework | React |
Select a variant | TypeScript + SWC |
ターミナル画面
PS C:\Users\source\test\react-fastapi-docker\frontend> npm create vite@latest
> npx
> create-vite
? Project name: » .
? Select a framework: » - Use arrow-keys. Return to submit.
Vanilla
Vue
> React
Preact
Lit
Svelte
Solid
Qwik
Angular
Others
? Select a variant: » - Use arrow-keys. Return to submit.
TypeScript
> TypeScript + SWC
JavaScript
JavaScript + SWC
React Router v7 ↗
- 続いてfrontendフォルダの階層で下記を実行
npm install
下記のようにフォルダ・ファイルが生成される
frontend/
├── node_modules/
├── public/
├── src/
├── .gitignore
├── eslint.config.js
├── index.html
├── package-lock.json
├── package.json
├── README.md
├── tsconfig.app.json
├── tsconfig.json
├── tsconfig.node.json
└── vite.config.ts
- 下記コードを実行し、Reactアプリの起動を確認
npm run dev
バックエンドのセットアップ
・backendフォルダの階層で下記を実行
python -m venv env
- 仮想環境をアクティブ化し、fastapi, uvicornをインストール
PS C:\Users\source\test\react-fastapi-docker\backend> .\env\Scripts\activate
(env) PS C:\Users\source\test\react-fastapi-docker\backend> pip install fastapi uvicorn
- main.pyファイルを作成し、簡単なAPIを作成
backend/
├── app/
│ ├── main.py
└── env/
# main.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
app = FastAPI()
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
@app.get("/api/hello")
async def read_root():
return {"message": "Hello from FastAPI"}
- backendフォルダの階層で下記コードを実行し、APIの実行確認
uvicorn app.main:app --reload
- ブラウザで「http://127.0.0.1:8000/api/hello」にアクセスし、出力の確認
{"message":"Hello from FastAPI"}
- 下記コマンドを実行し、インストール済みパッケージ一覧を出力する
pip freeze > requirements.txt
ReactからAPIの呼び出し
- /frontend/src/App.tsxを修正し、FastAPIを呼び出す機能を実装する
import { useState, useEffect } from 'react'
import reactLogo from './assets/react.svg'
import viteLogo from '/vite.svg'
import './App.css'
function App() {
const [count, setCount] = useState(0);
const [apiMessage, setApiMessage] = useState<string | null>(null);
useEffect(() => {
const fetchMessage = async () => {
try {
const response = await fetch('http://localhost:8000/api/hello'); // FastAPIのエンドポイント
const data = await response.json();
setApiMessage(data.message); // メッセージを状態に保存
} catch (error) {
console.error('Error fetching the API:', error);
setApiMessage('Failed to fetch data from API');
}
};
fetchMessage();
}, []);
return (
<>
<div>
<a href="https://vite.dev" target="_blank">
<img src={viteLogo} className="logo" alt="Vite logo" />
</a>
<a href="https://react.dev" target="_blank">
<img src={reactLogo} className="logo react" alt="React logo" />
</a>
</div>
<h1>Vite + React</h1>
<div className="card">
<button onClick={() => setCount((count) => count + 1)}>
count is {count}
</button>
<p>
Edit <code>src/App.tsx</code> and save to test HMR
</p>
</div>
<div className="api-message">
<h2>Message from FastAPI:</h2>
<p>{apiMessage || 'Loading...'}</p>
</div>
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
)
}
export default App
- frontendフォルダの階層で下記コマンドを実行し、ビルド
npm run build
Dockerの準備
- backendフォルダ直下に下記Dockerfileを作成
FROM python:3.9-slim
WORKDIR /app
COPY requirements.txt /app/
RUN pip install --upgrade pip
RUN pip install --no-cache-dir -r requirements.txt
COPY ./app /app/
CMD ["uvicorn", "app.main:app", "--host", "0.0.0.0", "--port", "8000", "--reload"]
EXPOSE 8000
- frontendフォルダ直下に下記Dockerfileを作成
FROM node:lts-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
- projectフォルダ直下に下記docker-compose.ymlファイルを配置
version: '3.9'
services:
backend:
build:
context: ./backend
dockerfile: Dockerfile
ports:
- "8000:8000"
volumes:
- ./backend:/app
frontend:
build:
context: ./frontend
dockerfile: Dockerfile
ports:
- "3000:80"
volumes:
- ./src:/app/src
- ./public:/app/public
stdin_open: true
- ディレクトリ構造は下記のようになる
react-fastapi-docker/
├── backend/
│ ├── app
│ │ ├── main.py
│ ├── Dockerfile
│ └── requirements.txt
├── frontend/
│ ├── src
│ ├── ...
│ ├── Dockerfile
└── docker-compose.yml
Dockerによるアプリの起動
- プロジェクトフォルダの階層で下記コマンドを実行してアプリを起動
docker-compose build
docker-compose up
- http://localhost:3000/にアクセスしてアプリの起動を確認
FastAPIの呼び出しもうまくいっている
コメント