PersonalWebApplication/docs/superpowers/plans/2026-06-18-deploy.md
cc a185e56c22 feat: 导航起始页 + 天气/定位 + 天气动态效果
起始页(StartPage)
- 极简玻璃风导航页作未登录首页:时段问候、Bing 默认可切换搜索、10 个快捷位、右下齿轮进登录
- 昼夜背景自动切换(light/dark),按天气图标码 + 本地时间判断
- 天气动态效果(WeatherFx canvas):雨/雪/雷,克制风格,尊重 reduced-motion

天气与定位(前后端)
- 后端 /api/web/weather:高德 IP 定位(城市+坐标) + 和风实时天气
- 和风用 JWT(EdDSA/Ed25519)认证,密钥走环境变量、仅后端持有
- 每日限流(高德 300、和风 900,北京 0 点归零) + 10 分钟按 IP 缓存
- 前端 useWeather + WeatherIcon(7 类极简 SVG)

导航与登录
- 浏览器返回键支持(History API);返回即登出
- 记住我:勾选存 localStorage、不勾存 sessionStorage,默认不勾

其他
- .gitignore 忽略 *.pem/*.env 等密钥
- 新增文档 docs/startpage-weather-location.md 及部署 spec/plan

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-18 20:13:18 +08:00

233 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# InternetProject Deployment Plan
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
**Goal:** Deploy the React + Rust full-stack app to `root@8.130.143.54`, accessible at `http://8.130.143.54:8548`.
**Architecture:** Rust binary (`RustServer`) serves both the REST API and React static files from a single process. React is built locally, Rust is cross-compiled in WSL, both artifacts are uploaded via scp and started with nohup.
**Tech Stack:** React 19 + Vite 8 (frontend), Rust + Axum 0.8 (backend), Ubuntu 22.04 (server), WSL2 mirrored network (build env)
## Global Constraints
- Server: `root@8.130.143.54`, Ubuntu 22.04, x86_64
- Deploy path: `/opt/internet-project/` on server
- Static files served from: `/opt/internet-project/static/`
- Port: `8548` (via `PORT=8548` env var at runtime)
- WSL mirrored network + `autoProxy=true` — no manual proxy config needed
- `main.rs` already updated to read `PORT` env var (default `8080`)
- Do NOT install any toolchain on the remote server
---
### Task 1: Build React Frontend
**Files:**
- Build: `Client/``Client/dist/`
**Interfaces:**
- Produces: `Client/dist/index.html` + `Client/dist/assets/*` (consumed by Task 3)
- [ ] **Step 1: Install dependencies (if not already installed)**
Run in PowerShell from `F:\Code\InternetProject\Client`:
```powershell
npm install
```
Expected: `node_modules/` populated, no errors.
- [ ] **Step 2: Build the frontend**
```powershell
npm run build
```
Expected output ends with something like:
```
dist/index.html x.xx kB
dist/assets/index-[hash].js xxx.xx kB
✓ built in x.xxs
```
- [ ] **Step 3: Verify dist output**
```powershell
Get-ChildItem Client\dist
```
Expected: `index.html`, `assets/`, `favicon.svg`, `icons.svg` present.
- [ ] **Step 4: Commit the main.rs port change**
```powershell
git add Server/src/main.rs
git commit -m "feat: read PORT from env var, default 8080"
```
---
### Task 2: Build Rust Binary in WSL
**Files:**
- Build: `Server/``Server/target/release/RustServer`
**Interfaces:**
- Produces: `/mnt/f/Code/InternetProject/Server/target/release/RustServer` — Linux x86_64 ELF binary (consumed by Task 3)
- [ ] **Step 1: Open WSL and navigate to project**
In a WSL terminal:
```bash
cd /mnt/f/Code/InternetProject/Server
```
- [ ] **Step 2: Check Rust toolchain is installed**
```bash
rustc --version
```
If not installed:
```bash
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
```
Expected: `rustc 1.xx.x (...)` printed.
- [ ] **Step 3: Build release binary**
```bash
cargo build --release
```
First build takes 25 minutes (downloads + compiles dependencies). Expected final line:
```
Finished `release` profile [optimized] target(s) in Xs
```
- [ ] **Step 4: Verify binary exists and is Linux ELF**
```bash
file target/release/RustServer
```
Expected:
```
target/release/RustServer: ELF 64-bit LSB pie executable, x86-64, ...
```
---
### Task 3: Upload Artifacts to Server
**Files:**
- Remote create: `/opt/internet-project/` (directory)
- Remote create: `/opt/internet-project/RustServer` (binary)
- Remote create: `/opt/internet-project/static/` (frontend files)
**Interfaces:**
- Consumes: `Server/target/release/RustServer` (from Task 2), `Client/dist/*` (from Task 1)
- Produces: server-side deploy directory ready to run (consumed by Task 4)
- [ ] **Step 1: Create deploy directory on server**
Run in WSL:
```bash
ssh root@8.130.143.54 "mkdir -p /opt/internet-project/static"
```
Expected: no output, exit 0.
- [ ] **Step 2: Upload the Rust binary**
```bash
scp /mnt/f/Code/InternetProject/Server/target/release/RustServer \
root@8.130.143.54:/opt/internet-project/RustServer
```
Expected: progress bar, then returns to prompt.
- [ ] **Step 3: Upload frontend static files**
```bash
scp -r /mnt/f/Code/InternetProject/Client/dist/* \
root@8.130.143.54:/opt/internet-project/static/
```
Expected: multiple files transferred (index.html, assets/, etc.).
- [ ] **Step 4: Make binary executable**
```bash
ssh root@8.130.143.54 "chmod +x /opt/internet-project/RustServer"
```
- [ ] **Step 5: Verify remote layout**
```bash
ssh root@8.130.143.54 "ls -lh /opt/internet-project/ && ls /opt/internet-project/static/"
```
Expected:
```
total XX
-rwxr-xr-x 1 root root XXM ... RustServer
drwxr-xr-x 2 root root ... static/
assets favicon.svg icons.svg index.html
```
---
### Task 4: Start the Server and Verify
**Files:**
- Remote: `/opt/internet-project/server.log` (created on start)
**Interfaces:**
- Consumes: deploy directory from Task 3
- Produces: running service at `http://8.130.143.54:8548`
- [ ] **Step 1: Start server with nohup**
```bash
ssh root@8.130.143.54 "cd /opt/internet-project && nohup PORT=8548 ./RustServer > server.log 2>&1 &"
```
Expected: no output (background process started).
- [ ] **Step 2: Check server started successfully**
```bash
ssh root@8.130.143.54 "sleep 1 && cat /opt/internet-project/server.log"
```
Expected:
```
backend listening on http://0.0.0.0:8548
```
- [ ] **Step 3: Verify API endpoint responds**
```bash
curl http://8.130.143.54:8548/api/client/health
```
Expected: HTTP 200 with a JSON response (or empty 200).
- [ ] **Step 4: Verify frontend loads**
Open `http://8.130.143.54:8548` in a browser. Expected: React app renders correctly (login page / blog page visible).
- [ ] **Step 5: Verify API stats endpoint**
```bash
curl http://8.130.143.54:8548/api/web/stats
```
Expected: JSON with system metrics (CPU, memory, etc.).
---
## Operations Reference
**Stop server:**
```bash
ssh root@8.130.143.54 "pkill RustServer"
```
**View live logs:**
```bash
ssh root@8.130.143.54 "tail -f /opt/internet-project/server.log"
```
**Redeploy after code changes:**
Re-run Tasks 14. For frontend-only changes, skip Task 2.