Files
remote-sensing/COLAB_FRP_DEMO_GUIDE.md

446 lines
11 KiB
Markdown
Raw Permalink 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.
# Demo Website trên Google Colab với FRP
Hướng dẫn này giúp bạn chạy toàn bộ hệ thống **remote-sensing** trên Google Colab
và expose ra internet qua **FRP (Fast Reverse Proxy)** — không cần ngrok, URL cố định, không giới hạn session.
---
## Yêu cầu
| Thành phần | Mô tả |
|---|---|
| **Google Colab** | Tài khoản Google thông thường (free tier là đủ) |
| **Google Drive** | Dùng để lưu project và models |
| **1 VPS có IP public** | Chạy `frps` server — VPS $35/tháng là đủ |
| **Port mở trên VPS** | 7000 (FRP control) + 8080 (web traffic) |
---
## Phần 1 — Chuẩn bị VPS (chạy 1 lần, giữ mãi)
### Bước 1.1 — Download FRP lên VPS
SSH vào VPS rồi chạy:
```bash
wget https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz
tar -xzf frp_0.61.1_linux_amd64.tar.gz
cd frp_0.61.1_linux_amd64
```
### Bước 1.2 — Tạo file cấu hình `frps.toml`
```bash
cat > frps.toml << 'EOF'
bindPort = 7000
auth.token = "your_secret_token_here"
# Dashboard để theo dõi kết nối (tuỳ chọn)
webServer.port = 7500
webServer.user = "admin"
webServer.password = "admin123"
EOF
```
> ⚠️ Đặt `auth.token` thành chuỗi bí mật của bạn, ví dụ: `"rs_demo_2026_abc123"`. Phải giống với phía Colab.
### Bước 1.3 — Chạy frps
```bash
# Test chạy foreground (Ctrl+C để dừng)
./frps -c frps.toml
# Chạy nền (production)
nohup ./frps -c frps.toml > frps.log 2>&1 &
# Kiểm tra đang chạy
ps aux | grep frps
```
### Bước 1.4 — Mở firewall VPS
```bash
# Ubuntu/Debian
ufw allow 7000 # FRP control port
ufw allow 8080 # Web traffic port
ufw allow 7500 # Dashboard (tuỳ chọn)
ufw reload
# CentOS/RHEL
firewall-cmd --permanent --add-port=7000/tcp
firewall-cmd --permanent --add-port=8080/tcp
firewall-cmd --reload
```
### Bước 1.5 — Kiểm tra frps hoạt động
```bash
# Xem log
tail -f frps.log
# Kết quả kỳ vọng:
# [frps] frp service started, listen on 0.0.0.0:7000
```
---
## Phần 2 — Chuẩn bị Google Drive
### Bước 2.1 — Upload project lên Drive
Cấu trúc thư mục trên Google Drive:
```
My Drive/
└── remote-sensing/
├── api_server.py
├── train_module.py
├── feature_extractor.py
├── model_manager.py
├── cloud_removal.py
├── report_generator.py
├── generate_previews.py
├── vietnam_provinces.py
├── vietnam_provinces_merged.py
├── utils.py
├── model_train/ ← copy toàn bộ models đã train
│ ├── *.joblib
│ └── *.json
├── cloud_removal_model/ ← copy nếu dùng cloud removal DL
│ └── *.pth
├── predictions/ ← để trống, Colab sẽ tạo output vào đây
├── reports/ ← để trống
└── training_interface.html ← và tất cả *.html
```
> 💡 Upload nhanh nhất: zip toàn bộ folder `remote-sensing`, upload 1 file zip lên Drive, rồi giải nén bằng Colab.
---
## Phần 3 — Notebook Google Colab
Tạo notebook mới tại [colab.google.com](https://colab.google.com) và paste từng cell sau.
---
### Cell 1 — Mount Drive và di chuyển vào project
```python
from google.colab import drive
drive.mount('/content/drive')
import os
PROJECT_PATH = '/content/drive/MyDrive/remote-sensing'
os.chdir(PROJECT_PATH)
print(f"Working directory: {os.getcwd()}")
print("Files:", os.listdir()[:10])
```
---
### Cell 2 — Giải nén nếu upload dạng zip (tuỳ chọn)
```python
# Chỉ chạy nếu bạn upload file zip
import zipfile
ZIP_PATH = '/content/drive/MyDrive/remote-sensing.zip'
EXTRACT_TO = '/content/drive/MyDrive/'
if os.path.exists(ZIP_PATH):
with zipfile.ZipFile(ZIP_PATH, 'r') as z:
z.extractall(EXTRACT_TO)
print("✅ Extracted successfully")
else:
print("⏭️ No zip found, skipping")
```
---
### Cell 3 — Cài dependencies (chạy lần đầu, ~812 phút)
```python
print("Installing core API dependencies...")
!pip install -q fastapi uvicorn pydantic
print("Installing geospatial + ML dependencies...")
!pip install -q \
numpy pandas xarray rasterio rioxarray geopandas shapely \
scikit-learn xgboost joblib \
matplotlib pillow markdown
print("Installing Planetary Computer dependencies...")
!pip install -q pystac-client planetary-computer odc-stac
print("Installing PyTorch (GPU)...")
!pip install -q torch torchvision \
--extra-index-url https://download.pytorch.org/whl/cu118
print("✅ All dependencies installed")
```
---
### Cell 4 — Kiểm tra GPU và môi trường
```python
import torch
print(f"PyTorch version : {torch.__version__}")
print(f"GPU available : {torch.cuda.is_available()}")
if torch.cuda.is_available():
print(f"GPU name : {torch.cuda.get_device_name(0)}")
import rasterio, xarray, geopandas
print(f"rasterio : {rasterio.__version__}")
print(f"xarray : {xarray.__version__}")
print(f"geopandas : {geopandas.__version__}")
```
---
### Cell 5 — Download và cấu hình frpc
```python
import subprocess, os
# Download frpc
!wget -q https://github.com/fatedier/frp/releases/download/v0.61.1/frp_0.61.1_linux_amd64.tar.gz \
-O /tmp/frp.tar.gz
!tar -xzf /tmp/frp.tar.gz -C /tmp/
!chmod +x /tmp/frp_0.61.1_linux_amd64/frpc
# ============================================================
# ⚠️ SỬA 2 DÒNG NÀY TRƯỚC KHI CHẠY
VPS_IP = "123.456.789.000" # IP public của VPS bạn
FRP_TOKEN = "your_secret_token_here" # Phải giống frps.toml trên VPS
# ============================================================
frpc_config = f"""
serverAddr = "{VPS_IP}"
serverPort = 7000
auth.token = "{FRP_TOKEN}"
[[proxies]]
name = "remote-sensing-web"
type = "tcp"
localIP = "127.0.0.1"
localPort = 8000
remotePort = 8080
"""
with open('/tmp/frpc.toml', 'w') as f:
f.write(frpc_config)
print(f"✅ frpc configured → VPS: {VPS_IP}:8080")
```
---
### Cell 6 — Khởi động FastAPI server
```python
import subprocess, time, os
os.chdir('/content/drive/MyDrive/remote-sensing')
# Khởi động FastAPI
server = subprocess.Popen(
["uvicorn", "api_server:app",
"--host", "127.0.0.1",
"--port", "8000",
"--log-level", "warning"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
time.sleep(4)
# Kiểm tra server đã lên chưa
if server.poll() is None:
print("✅ FastAPI server is running on port 8000")
else:
out, err = server.communicate()
print("❌ Server failed to start:")
print(err.decode()[:1000])
```
---
### Cell 7 — Khởi động frpc tunnel
```python
import subprocess, time
frpc = subprocess.Popen(
["/tmp/frp_0.61.1_linux_amd64/frpc", "-c", "/tmp/frpc.toml"],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
time.sleep(3)
if frpc.poll() is None:
print("✅ FRP tunnel is active")
print("=" * 55)
print(f"🌐 Main site : http://{VPS_IP}:8080")
print(f"📊 Dashboard : http://{VPS_IP}:8080/dashboard")
print(f"🏋️ Training : http://{VPS_IP}:8080/training")
print(f"🔮 Prediction : http://{VPS_IP}:8080/prediction")
print(f"📦 Batch : http://{VPS_IP}:8080/batch")
print(f"🌿 NDVI : http://{VPS_IP}:8080/ndvi")
print(f"📈 Reports : http://{VPS_IP}:8080/reports")
print("=" * 55)
else:
out, err = frpc.communicate()
print("❌ FRP failed:")
print(err.decode()[:500])
```
---
### Cell 8 — Kiểm tra toàn bộ hệ thống
```python
import urllib.request, json
BASE = "http://127.0.0.1:8000"
checks = [
("/api/network/check", "Network connectivity"),
("/api/models/list", "Model list"),
("/api/provinces/list", "Province list"),
("/api/cloud-removal/methods", "Cloud removal methods"),
]
for path, label in checks:
try:
r = urllib.request.urlopen(BASE + path, timeout=5)
data = json.loads(r.read())
status = "✅"
except Exception as e:
data = str(e)
status = "❌"
print(f"{status} {label:<30}{str(data)[:80]}")
```
---
### Cell 9 — Xem log nếu có lỗi (tuỳ chọn)
```python
# Xem stderr của FastAPI
import select, sys
if server.poll() is not None:
_, err = server.communicate()
print("FastAPI stderr:")
print(err.decode())
else:
# Đọc log không block
import os
flags = os.O_RDONLY | os.O_NONBLOCK
try:
fd = server.stderr.fileno()
os.set_blocking(fd, False)
print(server.stderr.read(2000).decode())
except:
print("Server is running (no errors captured)")
```
---
### Cell 10 — Dừng server khi xong demo
```python
import subprocess
server.terminate()
frpc.terminate()
print("✅ FastAPI stopped")
print("✅ FRP tunnel closed")
```
---
## Phần 4 — Dùng domain thay vì IP (nâng cao)
Nếu VPS có domain riêng, bạn có thể truy cập bằng URL đẹp hơn.
### Sửa `frps.toml` trên VPS
```toml
bindPort = 7000
auth.token = "your_secret_token_here"
vhostHTTPPort = 80
```
### Sửa Cell 5 (`frpc.toml`) trên Colab
```toml
serverAddr = "your-vps.com"
serverPort = 7000
auth.token = "your_secret_token_here"
[[proxies]]
name = "remote-sensing-web"
type = "http"
localPort = 8000
customDomains = ["demo.your-vps.com"]
```
### DNS — trỏ subdomain về VPS
```
demo.your-vps.com → A record → 123.456.789.000
```
→ Truy cập: `http://demo.your-vps.com` (không cần `:8080`)
---
## Phần 5 — Giữ session Colab sống lâu hơn
Colab tự disconnect sau ~90 phút idle. Để tránh:
```javascript
// Paste vào console trình duyệt (F12 → Console)
function keepAlive() {
document.querySelector('#connect button')?.click();
console.log('keep-alive ping:', new Date().toLocaleTimeString());
}
setInterval(keepAlive, 60000);
```
Hoặc dùng **Colab Pro** ($10/tháng) để không bị giới hạn session.
---
## Phần 6 — Tóm tắt so sánh FRP vs ngrok
| Tiêu chí | FRP (self-host) | ngrok (free) |
|---|---|---|
| URL cố định | ✅ Có | ❌ Đổi mỗi session |
| Session timeout | ✅ Không giới hạn | ⚠️ 2 giờ |
| Chi phí | Free (cần VPS) | Free tier có giới hạn |
| Dữ liệu qua server bên thứ 3 | ❌ Không | ✅ Qua server ngrok |
| Cần setup | ⚠️ Cần cài frps trên VPS | ✅ Chạy ngay |
| Phù hợp | Demo dài hạn, production | Demo nhanh 1 lần |
---
## Checklist trước khi demo
- [ ] VPS đang chạy `frps` và port 7000, 8080 đã mở
- [ ] Project đã upload đầy đủ lên Google Drive (kể cả `model_train/`)
- [ ] Đã điền đúng `VPS_IP``FRP_TOKEN` trong Cell 5
- [ ] Cell 3 (cài deps) đã chạy thành công
- [ ] Cell 8 (health check) cho thấy tất cả ✅
- [ ] Truy cập `http://VPS_IP:8080/dashboard` từ trình duyệt → hiện trang
---
*Tạo ngày: 03/04/2026 — dự án remote-sensing Vietnam Land Classification*