Cài đặt 9router API Proxy trên VPS với PM2 và Cloudflared
Hướng dẫn chi tiết cách cài đặt 9router API proxy trên VPS dùng PM2 và Cloudflared Tunnel. Quản lý nhiều API key AI (OpenAI, Anthropic, Google), xoay vòng provider, ẩn credentials và kiểm soát chi phí.

Chạy một proxy trung gian giữa ứng dụng của bạn và các AI provider giúp tập trung quản lý API keys, xoay vòng provider khi rate limit, và ẩn credentials thật khỏi client. 9router làm chính xác việc đó.
Bài viết này hướng dẫn chi tiết cách cài đặt 9router trên VPS sử dụng PM2 để chạy headless mode và Cloudflared Tunnel để expose service ra bên ngoài mà không cần mở port.
Tại sao cần API Proxy?
- Xoay vòng API keys — Tự động chuyển sang key dự phòng khi key chính hết quota
- Ẩn credentials — Client chỉ biết endpoint của bạn, không thấy key thật
- Quản lý rate limit — Phân phối request qua nhiều provider (OpenAI, Anthropic, Google)
- Log và kiểm soát — Theo dõi usage, chi phí theo project
Yêu cầu
- VPS Linux (Ubuntu/Debian)
- Node.js ≥ 18
- PM21 (process manager)
- Cloudflared2 (Cloudflare Tunnel)
- Port 20128 mở local
Cài đặt
# Cài Node.js qua nvmcurl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.0/install.sh | bashnvm install --lts
# Cài 9routernpm install -g 9router9router: npm package | Documentation
Kiểm tra version:
9router --version # 0.4.20+Chạy trên VPS
VPS không có GUI nên chạy ở headless mode:
9router --headlessChạy bền bỉ với PM2 (khuyến nghị):
npm install -g pm2
pm2 start $(which 9router) --name 9router -- -tpm2 startuppm2 saveOutput:
🚀 9router v0.4.20Server: http://localhost:20128💡 Router is now running in headless mode.Test ngay:
curl http://localhost:20128/v1/modelsKiểm tra:
pm2 listpm2 logs 9routerCấu hình API Keys
Mở Web UI (http://vps-ip:20128) hoặc config qua API. Thêm keys của các provider:
- OpenAI:
sk-... - Anthropic:
sk-ant-... - Google:
AIza...
9router tự chọn provider theo model trong request.
Truy cập từ bên ngoài
Dùng Cloudflare Tunnel (khuyến nghị)
Cloudflared không cần open port, proxy qua Cloudflare an toàn hơn:
# Cài cloudflaredcurl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-amd64 -o /usr/local/bin/cloudflaredchmod +x /usr/local/bin/cloudflared
# Tạo tunnelcloudflared tunnel create 9router
# Chạy tunnelcloudflared tunnel run --url http://localhost:20128 9routerTham khảo: Hướng dẫn Cloudflare Tunnel
Quản lý Tunnel
# Liệt kê tunnelscloudflared tunnel list
# Tạo tunnel mớicloudflared tunnel create <tunnel-name>
# Xóa tunnelcloudflared tunnel delete <tunnel-name-or-id>
# Kiểm tra tunnel đang chạycloudflared tunnel info <tunnel-name>
# Chạy tunnel (quick run)cloudflared tunnel run <tunnel-name>
# Chạy với config file cụ thểcloudflared tunnel --config /etc/cloudflared/config.yml run <tunnel-name>
# Kiểm tra kết nối (từ local)curl -I https://proxy.yourdomain.comChạy như service vs quick run
Quick run — chạy trực tiếp, config ở ~/.cloudflared/config.yml:
cloudflared tunnel run 9routerService (production) — chạy như systemd service, config ở /etc/cloudflared/:
# Di chuyển credentials filesudo mv ~/.cloudflared/<tunnel-id>.json /etc/cloudflared/sudo chown root:root /etc/cloudflared/<tunnel-id>.jsonsudo chmod 600 /etc/cloudflared/<tunnel-id>.jsonTạo config file với mẫu template bên dưới
sudo nano /etc/cloudflared/config.ymlFile config cho service: /etc/cloudflared/config.yml (không phải ~/.cloudflared/)
tunnel: <tunnel-name>credentials-file: /etc/cloudflared/<tunnel-id>.jsonprotocol: http2metrics: 127.0.0.1:9090retries: 5grace-period: 30s
ingress: - hostname: proxy.yourdomain.com service: http://127.0.0.1:20128 originRequest: connectTimeout: 30s tlsTimeout: 30s tcpKeepAlive: 30s keepAliveConnections: 100 keepAliveTimeout: 90s noTLSVerify: true httpHostHeader: proxy.yourdomain.com disableChunkedEncoding: false - service: http_status:404sau đó lưu lại và chạy lệnh sau để validate config:
cloudflared tunnel ingress validate# hoặc với file cấu hình cụ thểcloudflared tunnel --config /etc/cloudflared/config.yml validate# nếu bị lỗi thù xem chi tiết lỗi bằng lệnhjournalctl -u cloudflared -fCài đặt service
sudo cloudflared service installKiểm tra service:
sudo systemctl status cloudflaredsudo systemctl restart cloudflaredjournalctl -u cloudflared -fLưu ý: File credentials chứa secret key nhạy cảm — đặt ở
/etc/cloudflared/với quyền600và owned byroot.
Dùng cloudflared như service:
sudo systemctl enable cloudflaredsudo systemctl start cloudflaredMapping domain
#Đăng nhâp vào cloudflared bằng lệnhcloudflared tunnel loginSau đó tạo DNS record trỏ subdomain (ví dụ: `proxy.yourdomain.com tương ứng trong file config):
cloudflared tunnel route dns <tunel-name or tunnel-id> proxy.yourdomain.comMở port trực tiếp (không khuyến nghị)
sudo ufw allow 20128Với cách này, endpoint sẽ là http://vps-ip:20128.
Dùng trong ứng dụng
Thay đổi endpoint từ provider gốc sang proxy của bạn:
# Trướccurl https://api.openai.com/v1/chat/completions \ -H "Authorization: Bearer sk-xxxx"
# Sau (dùng URL từ cloudflared tunnel)curl https://proxy.yourdomain.com/v1/chat/completions \ -H "Authorization: Bearer sk-xxxx"Hoặc set biến môi trường:
export OPENAI_API_BASE="https://proxy.yourdomain.com/v1"Kiểm tra trạng thái
pm2 status # Kiểm tra cả 9router và cloudflared tunnelpm2 logs 9router # Log 9routerTham khảo
- 9router Official Documentation
- 9router GitHub Repository
- 9router npm Package
- PM2 Documentation
- Cloudflare Tunnel Documentation
- Cloudflare Zero Trust Documentation
Kết luận
Với một VPS nhỏ, 9router, PM2 và Cloudflared, bạn có một API proxy production-ready để quản lý AI keys, phân phối request và kiểm soát chi phí — không cần open port hay VPN.
Ưu điểm so với các giải pháp khác:
- Không tốn phí Cloudflare Worker
- Không cần domain pointed trực tiếp về VPS
- An toàn hơn vì traffic đi qua Cloudflare
- Tự chủ hoàn toàn với VPS giá rẻ

