# 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 $3–5/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, ~8–12 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` và `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*