diff --git a/README.md b/README.md index 51e242d..0b574ed 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,135 @@ -WebAppTemplate -=============== +# WebAppTemplate + +Webアプリケーション開発のためのテンプレートです。 + +## 📁 プロジェクト一覧 + +### 1. flask-app +シンプルなFlask Webアプリケーション + +**特徴:** +- Flaskのみで完結するシンプルな構成 +- 静的ファイル(HTML/CSS/JS)を配信 + +**詳細:** [flask-app/README.md](flask-app/README.md) + +--- + +### 2. flask-react-app +Flask(バックエンド)+ React(フロントエンド)の分離構成 + +**特徴:** +- フロントエンド:React + TypeScript + Vite +- バックエンド:Flask REST API + +**詳細:** [flask-react-app/README.md](flask-react-app/README.md) + +**カスタマイズ:** +フロントエンドの他の選択肢(Vue.js, Next.jsなど)への変更も可能 + +--- + +## 🚀 使い方 + +### 前提条件 +- Docker Desktop がインストールされていること +- Docker Compose が利用可能であること +- ローカルにPythonやNode.jsをインストールする必要はありません + +### プロジェクトの起動 + +各プロジェクトディレクトリに移動して起動します: + +```bash +# Flask単体アプリの場合 +cd flask-app +docker compose up -d + +# Flask + React アプリの場合 +cd flask-react-app +docker compose up -d +``` + +### 停止 + +```bash +docker compose down +``` + +## 🛠️ 拡張 +- データベースを追加する場合は、`docker-compose.yml` にサービスを追加してください。 +- cssフレームワーク(Tailwind Bootstrapなど)を導入。 + +## 📚 Dockerコマンド集 +* コンテナ起動 +`docker compose up -d` +* ビルドして起動 +`docker compose up -d --build` +* ビルド +`docker compose build ` +* キャッシュなしでビルド +`docker compose build --no-cache ` +* コンテナ停止 +`docker compose down` +* コンテナ再起動 +`docker compose restart` +* コンテナ状況確認 +`docker ps` +* コンテナログ確認 +`docker logs ` +* コンテナ内に入る +`docker compose exec bash` + +## 🔍 Docker のセットアップ(WSL) + +### 3.1. 既存の Docker Desktop を無効化 + +Windows 上で Docker Desktop が動いている場合は停止します。(アンインストールしてもOK) + +### 3.2. 必要なパッケージをインストール(以下からはWSL内で実行) + +```bash +sudo apt update +sudo apt install -y ca-certificates curl gnupg lsb-release +``` + +### 3.3. Docker リポジトリを登録 + +```bash +sudo mkdir -p /etc/apt/keyrings +curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg +echo \ + "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] \ + https://download.docker.com/linux/ubuntu \ + $(lsb_release -cs) stable" | \ + sudo tee /etc/apt/sources.list.d/docker.list > /dev/null +``` + +### 3.4. Docker をインストール + +```bash +sudo apt update +sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin +``` + +### 3.5. Docker デーモン起動 & 自動起動設定 + +```bash +echo "[boot]\nsystemd=true" | sudo tee /etc/wsl.conf > /dev/null +wsl --shutdown # これだけPowerShell で実行 +# 再度 WSL を開いて: +sudo systemctl enable --now docker +``` + +### 3.6. 権限設定(sudo不要でDocker実行) + +```bash +sudo usermod -aG docker $USER +newgrp docker +``` + +### 3.7. 動作確認 + +```bash +docker run hello-world +``` \ No newline at end of file diff --git a/flask-app/README.md b/flask-app/README.md new file mode 100644 index 0000000..ea99a2b --- /dev/null +++ b/flask-app/README.md @@ -0,0 +1,105 @@ +# Flask Web Application + +シンプルなFlask Webアプリケーションのテンプレートです。Docker Composeで簡単に起動できます。 + +## 🚀 プロジェクト構成 + +``` +flask-app/ +├── docker-compose.yml # Docker Compose設定 +├── README.md # このファイル +└── backend/ + ├── app.py # Flaskアプリケーション本体 + ├── Dockerfile # Dockerイメージ定義 + ├── requirements.txt # Python依存パッケージ + ├── static/ # 静的ファイル(CSS, JS) + │ ├── app.js + │ └── style.css + └── templates/ # HTMLテンプレート + └── index.html +``` + + +## 🏃 起動方法 + +### 1. アプリケーションの起動 +/flask-app ディレクトリに移動して、以下のコマンドを実行: +```bash +docker compose up -d +``` + +### 2. アクセス + +ブラウザで以下のURLにアクセス: + +``` +http://localhost:5000 +``` + +### 3. 停止 + +```bash +docker compose down +``` + +## 🔌 API エンドポイント + +### GET `/` +- トップページ(index.html)を表示 + +### GET `/api/health` +- 応答確認API +- レスポンス例: + ```json + { + "ok": true, + "message": "hello from Flask" + } + ``` + +### POST `/api/echo` +- 送信されたJSONをそのまま返すエコーAPI +- リクエスト例: + ```json + { + "name": "test", + "time": "2026-02-08T12:50:16.020Z" + } + ``` +- レスポンス例: + ```json + { + "ok": true, + "you_sent": { + "name": "test", + "time": "2026-02-08T12:50:16.020Z" + } + } + ``` + +## 🛠️ 開発 + +### ログの確認 + +```bash +docker compose logs -f +``` + +### コンテナ内に入る + +```bash +docker compose exec backend /bin/sh +``` + +### ソースコードの編集 +ホストマシンの `backend/` ディレクトリ内のファイルを編集すると、コンテナ内のアプリケーションに即座に反映されます。(デバッグモードのため) + +## 📦 使用技術 + +- **Flask** - PythonのWebフレームワーク +- + +## 📝 備考 + +- デバッグモードが有効になっているため、本番環境では設定を変更してください +- ポート5000を使用しています。他のアプリケーションと競合する場合は`docker-compose.yml`のポート設定を変更してください diff --git a/flask-app/backend/Dockerfile b/flask-app/backend/Dockerfile new file mode 100644 index 0000000..51d8e97 --- /dev/null +++ b/flask-app/backend/Dockerfile @@ -0,0 +1,15 @@ +# Pythonの軽量イメージを使用 +FROM python:3.11-slim + +# 作業ディレクトリ +WORKDIR /app + +# 依存関係インストール +COPY requirements.txt /app/requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +# アプリをコピー +COPY . /app + +# Flaskポート +EXPOSE 5000 diff --git a/flask-app/backend/app.py b/flask-app/backend/app.py new file mode 100644 index 0000000..b911931 --- /dev/null +++ b/flask-app/backend/app.py @@ -0,0 +1,45 @@ +""" +Flaskアプリ本体 + +役割: +- HTMLページを配信 +- APIを提供 +""" +from flask import Flask, render_template, jsonify, request + +# Flaskアプリ生成 +app = Flask(__name__) + + +# ページ配信 +@app.get("/") +def index(): + """ + templates/index.html を返す + Flaskでは templates/ がHTMLの場所として扱われる + """ + return render_template("index.html") + + +# API +@app.get("/api/health") +def health(): + """ + 動作確認用API + """ + return jsonify(ok=True, message="hello from Flask") + + +@app.post("/api/echo") +def echo(): + """ + フロントから送られたJSONをそのまま返すAPI + """ + data = request.get_json(silent=True) or {} + print("Received data:", data, flush=True) + return jsonify(ok=True, you_sent=data) + + +# 直接実行時のみ起動 +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) diff --git a/flask-app/backend/static/app.js b/flask-app/backend/static/app.js new file mode 100644 index 0000000..0daafda --- /dev/null +++ b/flask-app/backend/static/app.js @@ -0,0 +1,33 @@ +/* +ブラウザで実行されるJavaScript + +役割: +- ボタンイベントを処理 +- Flask APIをfetch +*/ + +// health API呼び出し +document.querySelector("#btn-health").addEventListener("click", async () => { + const res = await fetch("/api/health"); + const json = await res.json(); + + document.querySelector("#out-health").textContent = + JSON.stringify(json, null, 2); +}); + +// echo API呼び出し +document.querySelector("#btn-echo").addEventListener("click", async () => { + const res = await fetch("/api/echo", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ + name: "test", + time: new Date().toISOString() + }), + }); + + const json = await res.json(); + + document.querySelector("#out-echo").textContent = + JSON.stringify(json, null, 2); +}); diff --git a/flask-app/backend/static/style.css b/flask-app/backend/static/style.css new file mode 100644 index 0000000..f9d1d24 --- /dev/null +++ b/flask-app/backend/static/style.css @@ -0,0 +1,37 @@ +/* ページ全体のフォント */ +:root { + font-family: system-ui, sans-serif; +} + +/* 背景 */ +body { + margin: 0; + background: #f6f7fb; +} + +/* レイアウト */ +.wrap { + max-width: 800px; + margin: 40px auto; +} + +/* カードUI */ +.card { + background: white; + padding: 16px; + border-radius: 12px; + margin: 16px 0; +} + +/* ボタン */ +button { + padding: 8px 12px; +} + +/* 出力表示 */ +pre { + background: #0b1020; + color: #fff; + padding: 12px; + border-radius: 8px; +} diff --git a/flask-app/backend/templates/index.html b/flask-app/backend/templates/index.html new file mode 100644 index 0000000..b77ea54 --- /dev/null +++ b/flask-app/backend/templates/index.html @@ -0,0 +1,36 @@ + + + + + + + Flask App + + + + +
+

Flaskを用いたWebアプリケーション

+ + +
+ +

+      
+ + +
+ +

+      
+
+ + + + + diff --git a/flask-app/docker-compose.yml b/flask-app/docker-compose.yml new file mode 100644 index 0000000..18fdfec --- /dev/null +++ b/flask-app/docker-compose.yml @@ -0,0 +1,26 @@ +# Docker Compose定義 +# Flaskアプリのコンテナで起動する + +services: + web: + # backend/Dockerfile を使ってイメージを作成 + build: ./backend + + # コンテナ名 + container_name: flask-app + + # ホスト(ローカル、自分のマシン)ポート5000 → コンテナポート5000(基本同じが良い) + ports: + - "5000:5000" + + # ソースコードをコンテナ内の/appにマウント + volumes: + - ./backend:/app + + # 環境変数設定 + environment: + - FLASK_ENV=development + - FLASK_DEBUG=1 + + # Flask開発サーバ起動コマンド(ポート5000、開発モード) + command: flask --app app.py run --host=0.0.0.0 --port=5000 --debug diff --git a/flask-react-app/README.md b/flask-react-app/README.md new file mode 100644 index 0000000..43d976d --- /dev/null +++ b/flask-react-app/README.md @@ -0,0 +1,151 @@ +# Flask + React Web Application + +FlaskバックエンドとReactフロントエンドを組み合わせたWebアプリケーションテンプレートです。Docker Composeで両方を簡単に起動できます。 + +## 🚀 プロジェクト構成 + +``` +flask-react-app/ +├── docker-compose.yml # Docker Compose設定 +├── README.md # このファイル +├── backend/ # Flaskバックエンド +│ ├── app.py # Flaskアプリケーション本体 +│ ├── Dockerfile # バックエンド用Dockerイメージ定義 +│ └── requirements.txt # Python依存パッケージ +└── frontend/ # Reactフロントエンド + ├── src/ # Reactソースコード + │ ├── App.tsx # Reactメインコンポーネント + │ ├── App.css + │ └── main.tsx # Reactエントリーポイント + ├── index.html # 起動の起点となるHTMLファイル + ├── package.json # Node.js依存パッケージ(pythonのrequirements.txtみたいなもの) + ├── vite.config.ts # Vite設定 + ├── tsconfig.json # TypeScript設定 + └── Dockerfile # フロントエンド用Dockerイメージ定義 +``` + + +## 🏃 起動方法 + +### 1. アプリケーションの起動 +/flask-react-app ディレクトリに移動して、以下のコマンドを実行: +```bash +docker compose up -d +``` + +### 2. アクセス + +#### フロントエンド(React) +ブラウザで以下のURLにアクセス: +``` +http://localhost:5173 +``` +基本はこっちにアクセスして、Reactアプリを利用します。 + +#### バックエンド(Flask) +``` +http://localhost:6000 +``` +こっちはAPIサーバー用です。 + +### 3. 停止 + +```bash +docker compose down +``` + +## 🔌 API エンドポイント + +バックエンド(Flask)は `http://localhost:6000` で以下のAPIを提供します。 + +### GET `/` +- トップページ(index.html)を表示 + +### GET `/api/health` +- 応答確認API +- レスポンス例: + ```json + { + "ok": true, + "message": "hello from Flask" + } + ``` + +### POST `/api/echo` +- 送信されたJSONをそのまま返すエコーAPI +- リクエスト例: + ```json + { + "name": "test", + "time": "2026-02-08T12:50:16.020Z" + } + ``` +- レスポンス例: + ```json + { + "ok": true, + "you_sent": { + "name": "test", + "time": "2026-02-08T12:50:16.020Z" + } + } + ``` + +## 🛠️ 開発 + +### ログの確認 + +全サービスのログ: +```bash +docker compose logs -f +``` + +特定のサービスのみ: +```bash +docker compose logs -f backend +docker compose logs -f frontend +``` + +### コンテナ内に入る + +バックエンド: +```bash +docker compose exec backend bash +``` + +フロントエンド: +```bash +docker compose exec frontend sh +``` + +### ソースコードの編集 + +#### バックエンド +`backend/` 配下のファイルを編集すると、Flaskの開発モードにより自動でリロードされます。 + +#### フロントエンド +`frontend/src/` 配下のファイルを編集すると、Viteのホットリロード機能により自動で反映されます。 + +## 📦 使用技術 + +### バックエンド +- **Flask** - PythonのWebフレームワーク + +### フロントエンド +- **React** - フロントエンドWebフレームワーク +- **Vite** - フロントエンドビルドツール + + +## 🌐 ポート設定 + +| サービス | ポート | 説明 | +|---------|-------|------| +| Frontend | 5173 | React開発サーバー(Vite) | +| Backend | 6000 | Flask APIサーバー | + +## 📝 備考 + +- デバッグモードが有効になっているため、本番環境では設定を変更してください +- フロントエンドからバックエンドAPIを呼び出す際は `http://localhost:6000/api/...` を使用してください +- ポートが他のアプリケーションと競合する場合は `docker-compose.yml` のポート設定を変更してください +- フロントエンドのホットリロードとバックエンドの自動リロードが有効になっています diff --git a/flask-react-app/backend/Dockerfile b/flask-react-app/backend/Dockerfile new file mode 100644 index 0000000..0119747 --- /dev/null +++ b/flask-react-app/backend/Dockerfile @@ -0,0 +1,15 @@ +# Pythonの軽量イメージを使用 +FROM python:3.11-slim + +# 作業ディレクトリ +WORKDIR /app + +# 依存関係インストール +COPY requirements.txt /app/requirements.txt +RUN pip install --no-cache-dir -r requirements.txt + +# アプリをコピー +COPY . /app + +# Flaskポート +EXPOSE 6000 diff --git a/flask-react-app/backend/app.py b/flask-react-app/backend/app.py new file mode 100644 index 0000000..b911931 --- /dev/null +++ b/flask-react-app/backend/app.py @@ -0,0 +1,45 @@ +""" +Flaskアプリ本体 + +役割: +- HTMLページを配信 +- APIを提供 +""" +from flask import Flask, render_template, jsonify, request + +# Flaskアプリ生成 +app = Flask(__name__) + + +# ページ配信 +@app.get("/") +def index(): + """ + templates/index.html を返す + Flaskでは templates/ がHTMLの場所として扱われる + """ + return render_template("index.html") + + +# API +@app.get("/api/health") +def health(): + """ + 動作確認用API + """ + return jsonify(ok=True, message="hello from Flask") + + +@app.post("/api/echo") +def echo(): + """ + フロントから送られたJSONをそのまま返すAPI + """ + data = request.get_json(silent=True) or {} + print("Received data:", data, flush=True) + return jsonify(ok=True, you_sent=data) + + +# 直接実行時のみ起動 +if __name__ == "__main__": + app.run(host="0.0.0.0", port=5000, debug=True) diff --git a/flask-react-app/docker-compose.yml b/flask-react-app/docker-compose.yml new file mode 100644 index 0000000..86d8d68 --- /dev/null +++ b/flask-react-app/docker-compose.yml @@ -0,0 +1,55 @@ +# docker-compose.yml +# FlaskとReactの両方のコンテナを定義 + +services: + backend: + # backend/Dockerfile を使ってイメージを作成 + build: ./backend + + # コンテナ名 + container_name: backend + + # ホスト(ローカル、自分のマシン)ポート6000 → コンテナポート6000(基本同じが良い + ports: + - "6000:6000" + + # ソースコードをコンテナ内の/appにマウント + volumes: + - ./backend:/app + + # 環境変数設定 + environment: + - FLASK_ENV=development + - FLASK_DEBUG=1 + - PORT=6000 + + # Flask開発サーバ起動コマンド(ポート6000、開発モード) + command: flask --app app.py run --host=0.0.0.0 --port=6000 --debug + + frontend: + # frontend/Dockerfile を使ってイメージを作成 + build: ./frontend + + # コンテナ名 + container_name: frontend + + # ホスト(ローカル、自分のマシン)ポート5173 → コンテナポート5173(基本同じが良い) + ports: + - "5173:5173" + + # ソースコードをコンテナ内の/appにマウント + volumes: + - ./frontend:/app + - /app/node_modules + + # 環境変数設定 + environment: + - HOST=0.0.0.0 + - PORT=5173 + + # React(Vite)開発サーバ起動コマンド(ポート5173、ホスト0.0.0.0) + command: npm run dev -- --host 0.0.0.0 --port 5173 + + # 他のコンテナ(backend)が起動してから起動するように設定 + depends_on: + - backend diff --git a/flask-react-app/frontend/Dockerfile b/flask-react-app/frontend/Dockerfile new file mode 100644 index 0000000..1a869be --- /dev/null +++ b/flask-react-app/frontend/Dockerfile @@ -0,0 +1,15 @@ +# nodeイメージを使用 +FROM node:20-slim + +# 作業ディレクトリ +WORKDIR /app + +# 依存関係のインストール +COPY package.json /app/package.json +RUN npm install + +# アプリをコピー +COPY . /app + +# Reactポート +EXPOSE 5173 diff --git a/flask-react-app/frontend/index.html b/flask-react-app/frontend/index.html new file mode 100644 index 0000000..c0eaf9a --- /dev/null +++ b/flask-react-app/frontend/index.html @@ -0,0 +1,15 @@ + + + + + + + Flask + React + TS Starter + + +
+ + + + diff --git a/flask-react-app/frontend/package.json b/flask-react-app/frontend/package.json new file mode 100644 index 0000000..3ce17c9 --- /dev/null +++ b/flask-react-app/frontend/package.json @@ -0,0 +1,26 @@ +{ + "//": "frontend/package.json - React + TypeScript + Vite", + "name": "flask-react-ts-starter", + "private": true, + "version": "0.0.1", + "type": "module", + "scripts": { + "//dev": "開発サーバ(ホットリロード)", + "dev": "vite", + "//build": "本番用ビルド(dist生成)", + "build": "tsc -b && vite build", + "//preview": "distを簡易サーバで確認", + "preview": "vite preview --host 0.0.0.0 --port 5173" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@types/react": "^18.3.3", + "@types/react-dom": "^18.3.0", + "@vitejs/plugin-react": "^4.3.1", + "typescript": "^5.5.4", + "vite": "^5.4.0" + } +} diff --git a/flask-react-app/frontend/src/App.css b/flask-react-app/frontend/src/App.css new file mode 100644 index 0000000..51ad697 --- /dev/null +++ b/flask-react-app/frontend/src/App.css @@ -0,0 +1,31 @@ +:root { font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif; } +body { margin: 0; background: #f6f7fb; color: #111; } + +.wrap { max-width: 900px; margin: 40px auto; padding: 0 16px; } + +.card { + background: white; + border-radius: 12px; + padding: 16px; + margin: 16px 0; + box-shadow: 0 8px 20px rgba(0,0,0,0.06); +} + +button { + padding: 10px 12px; + border: 1px solid #ddd; + background: #fff; + border-radius: 10px; + cursor: pointer; +} + +button:hover { background: #f2f2f2; } + +pre { + background: #0b1020; + color: #e8e8e8; + padding: 12px; + border-radius: 10px; + overflow: auto; + min-height: 2.2em; +} diff --git a/flask-react-app/frontend/src/App.tsx b/flask-react-app/frontend/src/App.tsx new file mode 100644 index 0000000..2bda69c --- /dev/null +++ b/flask-react-app/frontend/src/App.tsx @@ -0,0 +1,57 @@ +// - GET /api/health を叩いて結果表示 +// - POST /api/echo を叩いて結果表示 + +import { useState } from "react"; + +type HealthResponse = { + ok: boolean; + message: string; +}; + +type EchoResponse = { + ok: boolean; + you_sent: unknown; +}; + +export default function App() { + // API結果表示用(型付き) + const [health, setHealth] = useState(null); + const [echo, setEcho] = useState(null); + + const callHealth = async () => { + const res = await fetch("/api/health"); + const json: HealthResponse = await res.json(); + setHealth(json); + }; + + const callEcho = async () => { + const payload = { hello: "world", at: new Date().toISOString() }; + + const res = await fetch("/api/echo", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify(payload) + }); + + const json: EchoResponse = await res.json(); + setEcho(json); + }; + + return ( +
+

Flask + React + TypeScript (Vite) Starter

+ +
+

GET /api/health

+ +
{health ? JSON.stringify(health, null, 2) : ""}
+
+ +
+

POST /api/echo

+ +
{echo ? JSON.stringify(echo, null, 2) : ""}
+
+
+ ); +} diff --git a/flask-react-app/frontend/src/main.tsx b/flask-react-app/frontend/src/main.tsx new file mode 100644 index 0000000..fd6f4af --- /dev/null +++ b/flask-react-app/frontend/src/main.tsx @@ -0,0 +1,12 @@ +// Reactアプリ起動(TypeScript版) + +import React from "react"; +import ReactDOM from "react-dom/client"; +import App from "./App"; +import "./App.css"; + +ReactDOM.createRoot(document.getElementById("root")!).render( + + + +); diff --git a/flask-react-app/frontend/tsconfig.json b/flask-react-app/frontend/tsconfig.json new file mode 100644 index 0000000..a8d723e --- /dev/null +++ b/flask-react-app/frontend/tsconfig.json @@ -0,0 +1,19 @@ +{ + "//": "ブラウザ側(React)のTypeScript設定", + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + "moduleResolution": "Bundler", + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + + "jsx": "react-jsx", + "strict": true + }, + "include": ["src"] +} diff --git a/flask-react-app/frontend/tsconfig.node.json b/flask-react-app/frontend/tsconfig.node.json new file mode 100644 index 0000000..69eddbe --- /dev/null +++ b/flask-react-app/frontend/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "//": "Vite設定ファイルなどNode側のTS用", + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/flask-react-app/frontend/vite.config.ts b/flask-react-app/frontend/vite.config.ts new file mode 100644 index 0000000..1c30c4d --- /dev/null +++ b/flask-react-app/frontend/vite.config.ts @@ -0,0 +1,18 @@ +// frontend/vite.config.ts +// TypeScriptで書くVite設定 +// /api へのアクセスを Flask(backend:6000) に転送する + +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; + +export default defineConfig({ + plugins: [react()], + server: { + proxy: { + "/api": { + target: "http://backend:6000", + changeOrigin: true + } + } + } +});