# 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 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** ```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 1–4. For frontend-only changes, skip Task 2.