# Docker 开发指南（Windows / Docker Desktop）

本文说明如何在 **不重启 Docker Desktop** 的前提下进行日常开发。绝大多数代码改动无需任何容器操作；需要时只需重启**单个容器**。

---

## 核心原则

| 场景 | 需要做什么 | 是否需要重启 Docker Desktop |
|------|-----------|---------------------------|
| 修改 Python 后端代码 | **什么都不做**（uvicorn `--reload` 自动重载） | ❌ 不需要 |
| 修改 React 前端代码 | **什么都不做**（Vite HMR 热更新） | ❌ 不需要 |
| 容器异常 / 需要刷新进程 | `docker compose restart backend` 或 `frontend` | ❌ 不需要 |
| 修改 `Dockerfile` 或依赖文件 | `docker compose up -d --build <service>` | ❌ 不需要 |
| Docker 引擎崩溃 / 端口被占用且无法释放 | 见下文「极少需要重启 Docker Desktop」 | ⚠️ 极少需要 |

**日常开发不要重启 Docker Desktop。** 那是 Windows + WSL2 下最慢、最打断节奏的操作。

---

## 端口对照表

与 `docker-compose.yml` 一致：

| 服务 | 容器内端口 | 宿主机端口 | 访问地址 |
|------|-----------|-----------|---------|
| backend | 8000 | **23337** | http://localhost:23337 |
| frontend | 5173 | **23338** | http://localhost:23338 |

健康检查：`http://localhost:23337/health`

---

## 代码改动：自动生效

### 后端（FastAPI + uvicorn）

- 启动命令：`uvicorn main:app --host 0.0.0.0 --port 8000 --reload`
- 源码通过 volume 挂载：`./backend` → `/app`
- 保存 `.py` 文件后，uvicorn 自动检测并重载，**无需重启容器**

### 前端（Vite + React）

- 启动命令：`npm run dev -- --host 0.0.0.0`
- 源码通过 volume 挂载：`./frontend` → `/app`
- `node_modules` 保存在独立 volume 中，不随宿主机目录覆盖
- 保存 `.jsx` / `.css` 等文件后，Vite HMR 自动更新浏览器，**无需重启容器**

---

## 何时只需重启容器（不是 Docker Desktop）

以下情况用 `scripts/docker-restart.ps1` 或 `docker compose restart` 即可：

- 修改了环境变量（`docker-compose.yml` 中的 `environment`）并已 `docker compose up -d`
- 容器内进程卡死、内存泄漏
- 前端 HMR 断开、WebSocket 连接异常
- 后端 reload 失败（极少数语法错误导致 worker 无法恢复）

```powershell
# 重启单个服务
.\scripts\docker-restart.ps1 -Service backend
.\scripts\docker-restart.ps1 -Service frontend

# 重启全部
.\scripts\docker-restart.ps1 -Service all

# 或直接
docker compose restart backend
docker compose restart frontend
```

---

## 何时需要重新构建镜像

以下变更需要 **rebuild**，仍然 **不需要重启 Docker Desktop**：

| 变更内容 | 命令 |
|---------|------|
| `backend/requirements.txt` | `.\scripts\docker-rebuild.ps1 -Service backend` |
| `backend/Dockerfile` | 同上 |
| `frontend/package.json` / `package-lock.json` | `.\scripts\docker-rebuild.ps1 -Service frontend` |
| `frontend/Dockerfile` | 同上 |

```powershell
# 等价命令
docker compose up -d --build backend
docker compose up -d --build frontend
```

### 前端依赖变更（package.json 改了但不想 rebuild）

若只新增了 npm 包、尚未 rebuild 镜像，可在运行中的容器内安装一次：

```powershell
docker compose exec frontend npm install
docker compose restart frontend
```

首次 `docker compose up` 时，镜像构建阶段会执行 `npm install`，依赖写入 `node_modules` volume，之后日常启动**不再**每次 `npm install`。

---

## 极少需要重启 Docker Desktop 的情况

仅在以下情况才考虑重启 Docker Desktop 或 WSL：

1. **Docker 引擎无响应** — `docker ps` 一直挂起或报错 `Cannot connect to the Docker daemon`
2. **端口被占用且 compose down 无法释放** — 例如 23337/23338 被僵尸进程占用
3. **WSL2 后端异常** — 内存耗尽、磁盘满、网络栈故障

**优先尝试的替代方案（由轻到重）：**

```powershell
# 1. 停止并重新启动 compose 栈（不碰 Docker Desktop）
docker compose down
docker compose up -d

# 2. 查看日志定位问题
.\scripts\docker-logs.ps1
.\scripts\docker-logs.ps1 -Service backend

# 3. 仅当 Docker 完全无响应时，关闭 WSL（会连带重启 Docker 引擎）
wsl --shutdown
# 然后重新打开 Docker Desktop
```

---

## 更快的日常开发方式（推荐）

Docker 适合「全栈联调 / 验收环境」。纯改代码时，**本地直接跑**通常更快：

### 后端（本地）

```powershell
python -m venv venv
.\venv\Scripts\Activate.ps1
pip install -r backend\requirements.txt
cd backend
python main.py
```

### 前端（本地）

```powershell
cd frontend
npm install
npm run dev
```

本地开发时前端默认代理到本地后端；Docker 栈仅在需要容器化联调时使用。

---

## 辅助脚本速查

所有脚本位于 `scripts/`，在项目根目录执行：

| 脚本 | 用途 |
|------|------|
| `docker-up.ps1` | 后台启动全部服务 |
| `docker-restart.ps1` | 重启 backend / frontend / all（**不**重启 Docker Desktop） |
| `docker-logs.ps1` | 跟踪日志（可选 `-Service backend`） |
| `docker-rebuild.ps1` | 重新构建并启动指定服务 |

### 典型一日工作流

```powershell
# 早上第一次
.\scripts\docker-up.ps1

# 白天改代码 — 保存即可，backend/frontend 自动更新

# 偶尔 HMR 或 reload 异常
.\scripts\docker-restart.ps1 -Service frontend

# 改了 requirements.txt
.\scripts\docker-rebuild.ps1 -Service backend

# 下班
docker compose down
```

---

## 使用 docker-compose.dev.yml（可选）

开发环境可使用 override 文件，与主 compose 合并：

```powershell
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
```

内容与主文件优化策略一致；便于将来追加仅开发用的配置而不改动默认 compose。

---

## 常见问题

### Q: 改了前端代码但页面没更新？

1. 确认保存了文件
2. 浏览器硬刷新（Ctrl+Shift+R）
3. `.\scripts\docker-restart.ps1 -Service frontend`
4. 查看日志：`.\scripts\docker-logs.ps1 -Service frontend`

### Q: 改了后端代码但 API 行为没变？

1. 查看 backend 日志是否有 reload 报错
2. `.\scripts\docker-restart.ps1 -Service backend`
3. 若改了依赖，需 rebuild

### Q: 每次启动 frontend 都很慢？

旧版 compose 在每次容器启动时执行 `npm install`。当前配置已改为直接 `npm run dev`；依赖在**镜像构建时**或**手动 exec npm install** 时装入 volume。若仍慢，检查是否误删了 `node_modules` volume：

```powershell
docker volume ls | Select-String node_modules
```

### Q: 必须重启 Docker Desktop 吗？

**正常代码编辑：不需要。**  
**依赖 / Dockerfile 变更：rebuild 容器即可。**  
**只有 Docker 引擎本身故障时才考虑重启 Docker Desktop 或 `wsl --shutdown`。**
