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

5.9 KiB
Raw Blame History

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:

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 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
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 14. For frontend-only changes, skip Task 2.