起始页(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>
5.9 KiB
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(viaPORT=8548env var at runtime) - WSL mirrored network +
autoProxy=true— no manual proxy config needed main.rsalready updated to readPORTenv var (default8080)- 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:
npm install
Expected: node_modules/ populated, no errors.
- Step 2: Build the frontend
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
Get-ChildItem Client\dist
Expected: index.html, assets/, favicon.svg, icons.svg present.
- Step 4: Commit the main.rs port change
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:
cd /mnt/f/Code/InternetProject/Server
- Step 2: Check Rust toolchain is installed
rustc --version
If not installed:
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
cargo build --release
First build takes 2–5 minutes (downloads + compiles dependencies). Expected final line:
Finished `release` profile [optimized] target(s) in Xs
- Step 4: Verify binary exists and is Linux ELF
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:
ssh root@8.130.143.54 "mkdir -p /opt/internet-project/static"
Expected: no output, exit 0.
- Step 2: Upload the Rust binary
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
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
ssh root@8.130.143.54 "chmod +x /opt/internet-project/RustServer"
- Step 5: Verify remote layout
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
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
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
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
curl http://8.130.143.54:8548/api/web/stats
Expected: JSON with system metrics (CPU, memory, etc.).
Operations Reference
Stop server:
ssh root@8.130.143.54 "pkill RustServer"
View live logs:
ssh root@8.130.143.54 "tail -f /opt/internet-project/server.log"
Redeploy after code changes: Re-run Tasks 1–4. For frontend-only changes, skip Task 2.