PersonalWebApplication/docs/superpowers/plans/2026-06-18-deploy.md
cc 5b60185f94 feat(start): 背景按时段选图(6-24 随机 No.1~5,0-6 用 Night),标题改 CCStart
- StartPage 背景改为纯本地时间:白天从 No.1~No.5 随机取一张并固定整页生命周期,夜间(0-6点)用 Night
- 登录页 h2 与 index.html 标签页标题由 Sign in 改为 CCStart
- 起始页背景图压成 WebP(限宽 2560,质量 ~82),单图从 2.5~4.7MB 降到 113~375KB,适配 3Mbps 带宽
- 删除旧 dark.png/light.jpg
- 部署文档补充前端单独重发流程与 WSL 实际路径

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

257 lines
7.0 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.
**Frontend-only redeploy (verified 2026-06-22):**
The active WSL checkout is at `/home/cc/InternetProject` (not the `/mnt/f/...`
path in the original tasks above). Since the Rust process serves `static/` from
disk, a frontend-only change needs **no server restart** — just rebuild and
replace the static files:
```bash
cd /home/cc/InternetProject/Client
npm run build
# clear stale hashed assets so old bundles don't accumulate
ssh root@8.130.143.54 "rm -rf /opt/internet-project/static/assets && mkdir -p /opt/internet-project/static"
scp -r dist/* root@8.130.143.54:/opt/internet-project/static/
# verify live
curl -s http://8.130.143.54:8548/ | grep -o '<title>[^<]*</title>'
curl -s -o /dev/null -w '%{http_code}\n' http://8.130.143.54:8548/api/client/health
```
**Restart the Rust binary (backend changes):**
A helper exists on the server: `/opt/internet-project/restart_rust.sh`. The
previous binary is kept as `RustServer.bak` for rollback.
> Startpage backgrounds: large PNG/JPG source images are pre-compressed to WebP
> (max width 2560, quality ~82) before building — keeps each background under
> ~400 KB for the 3 Mbps server link.