Files
remote-sensing/COLAB_FRP_DEMO_GUIDE.md
T

11 KiB
Raw Blame History

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:

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

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

# 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

# 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

# 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 và paste từng cell sau.


Cell 1 — Mount Drive và di chuyển vào project

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)

# 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)

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

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

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

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

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

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)

# 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

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

bindPort = 7000
auth.token = "your_secret_token_here"
vhostHTTPPort = 80

Sửa Cell 5 (frpc.toml) trên Colab

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:

// 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 Đổ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_IPFRP_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