Triển khai MoreLogin trên máy chủ Ubuntu không đầu và tự động hóa cấu hình trình duyệt thông qua API cục bộ - không cần môi trường máy tính để bàn.
Đến cuối hướng dẫn này, bạn sẽ có:
- Một phiên bản MoreLogin đang chạy trên máy chủ không đầu Ubuntu 24.04
- Chuyển tiếp mạng được định cấu hình để các máy bên ngoài có thể kết nối qua CDP (Giao thức Chrome DevTools)
- Tập lệnh tự động hóa Python đang hoạt động để tạo, khởi chạy, điều khiển và dọn dẹp cấu hình trình duyệt
┌──────────────────────────────────────────────────────────┐
│ Ubuntu 24.04 Server │
│ │
│ ┌──────────────┐ ┌───────────────────────────────┐ │
│ │ xvfb │───▶│ MoreLogin AppImage │ │
│ │ (virtual │ │ Local API :40000 │ │
│ │ display) │ │ CDP debug :<dynamic> │ │
│ │ │ │ (127.0.0.1, per profile) │ │
│ └──────────────┘ └───────────────────────────────┘ │
│ │ │
│ socat forwarding │
│ │ │
│ 0.0.0.0:40001 → 127.0.0.1:40000 │
│ 0.0.0.0:<N+1> → 127.0.0.1:<N> │
└──────────────────────────────────────────────────────────┘
│
External machine
(Playwright / Puppeteer / Selenium)[!NOTE] Cổng gỡ lỗi CDP động — mỗi cấu hình trình duyệt có cổng riêng, được trả về bởi điểm cuối
/api/env/start. Sơ đồ trên sử dụng<N>làm phần giữ chỗ.
| Yêu cầu | Chi tiết |
|---|---|
| Hệ điều hành | Máy chủ Ubuntu 24.04 (x86_64) |
| Thông số kỹ thuật được đề xuất | 8 vCPU, RAM 8 GB (hỗ trợ ~5 cấu hình đồng thời) |
| Mạng | Truy cập internet bên ngoài; mở cổng vào 40001 và các cổng CDP được chuyển tiếp mà bạn chọn hoặc thay vào đó hãy sử dụng đường hầm SSH |
| Python (tùy chọn) | Python 3.8+ với pip để chạy tập lệnh mẫu |
Kết nối với máy chủ của bạn thông qua SSH và cài đặt các gói cần thiết:
# FUSE support (required for AppImage)
sudo apt install -y libfuse2t64
# GTK / accessibility / display libraries
sudo apt install -y libatk1.0-0 libatk-bridge2.0-0 libatspi2.0-0
sudo apt install -y libcups2
sudo apt install -y libgtk-3-0 libgdk-pixbuf2.0-0
sudo apt install -y libgbm1 libxkbcommon0 libasound2t64
# Virtual framebuffer (headless display)
sudo apt install -y xvfb
# TCP forwarder
sudo apt install -y socatNếu các trang trình duyệt hiển thị không có văn bản hoặc hiển thị các ký tự bị thiếu, hãy cài đặt các gói phông chữ tương ứng:
# CJK (Chinese, Japanese, Korean)
sudo apt install -y fonts-noto-cjk fonts-noto-cjk-extra
# Arabic
sudo apt install -y fonts-noto-color-emoji fonts-noto-extraĐối với các ngôn ngữ khác, hãy cài đặt gói Họ phông chữ Noto phù hợp.
wget https://get.morelogin.com/client/prod/linux/x64/2.54.0/MoreLogin_x86_64_2.54.0.AppImage
chmod +x MoreLogin_x86_64_2.54.0.AppImageThay thế
2.54.0bằng phiên bản mới nhất có sẵn từ tài khoản MoreLogin của bạn hoặc trang tải xuống.
Sử dụng xvfb-run để cung cấp màn hình ảo, sau đó chạy AppImage:
nohup xvfb-run -a ./MoreLogin_x86_64_2.54.0.AppImage --no-sandbox > morelogin.log 2>&1 &Xác minh nó đã bắt đầu thành công:
# Check the process is running
ps aux | grep MoreLoginQuá trình này có thể mất 5–10 giây để khởi tạo hoàn toàn.
[!CAUTION] Bạn phải đăng nhập trước khi gọi bất kỳ điểm cuối API cục bộ nào khác. Trên máy chủ không đầu không có GUI để đăng nhập theo cách thủ công, vì vậy bạn phải xác thực qua API. Nếu không có bước này, tất cả lệnh gọi API sẽ trả về:
{"status": "error", "code": 401, "message": "Trạng thái đăng nhập của bạn đã hết hạn, vui lòng đăng nhập lại"}
Mở ứng dụng khách máy tính để bàn MoreLogin (trên bất kỳ máy nào bạn đã đăng nhập) và điều hướng đến Cài đặt → API & MCP. Sao chép ID ỨNG DỤNG và Khóa API từ phần Mở API:

Gọi điểm cuối đăng nhập bằng thông tin đăng nhập của bạn:
curl -X POST http://127.0.0.1:40000/api/user/login \
-H "Content-Type: application/json" \
-d '{
"apiId": "YOUR_APP_ID",
"apiKey": "YOUR_API_KEY"
}'Một phản hồi thành công trông giống như:
{"code": 0, "msg": null, "data": true}Xác nhận API đã sẵn sàng bằng cách liệt kê hồ sơ trình duyệt:
curl -s -X POST http://127.0.0.1:40000/api/env/page \
-H "Content-Type: application/json" \
-d '{"pageNo": 1, "pageSize": 1}'Phản hồi
{"code":0, ...}có nghĩa là bạn đã đăng nhập và API đã sẵn sàng.
Điểm kiểm tra: Máy chủ MoreLogin của bạn đã hoạt động đầy đủ. Hãy tiếp tục tới Bước 4 để truy cập từ xa hoặc chuyển thẳng tới Bước 5 nếu chạy tập lệnh trên cùng một máy chủ.
[!NOTE] Phiên đăng nhập vẫn tiếp tục miễn là quá trình MoreLogin đang chạy. Nếu khởi động lại AppImage, bạn sẽ cần phải đăng nhập lại.
Theo mặc định, cả cổng gỡ lỗi API cục bộ (:40000) và CDP đều liên kết với 127.0.0.1. Nếu bạn cần truy cập chúng từ máy bên ngoài (ví dụ: máy tính xách tay phát triển của bạn), hãy sử dụng socat để chuyển tiếp lưu lượng truy cập.
[!WARNING] Rủi ro bảo mật — không để các cổng này tiếp xúc với Internet công cộng.
- API cục bộ không có tính năng xác thực tích hợp cho hầu hết các điểm cuối.
- Cổng gỡ lỗi CDP cấp toàn quyền điều khiển từ xa phiên bản trình duyệt (đọc cookie, chèn tập lệnh, chụp ảnh màn hình).
Khuyến nghị:
- Sử dụng đường hầm SSH thay vì socat để truy cập từ xa:
ssh -L 40000:127.0.0.1:40000 user@server- Nếu bạn phải sử dụng socat, hãy hạn chế quyền truy cập bằng quy tắc tường lửa đối với chỉ các IP cụ thể
- Sử dụng VPN hoặc nhóm bảo mật của nhà cung cấp dịch vụ đám mây để hạn chế lưu lượng truy cập vào
- Không bao giờ mở cổng
40001/ CDP tới0.0.0.0trên máy chủ công khai mà không có giới hạn IP
nohup socat TCP-LISTEN:40001,fork,reuseaddr,bind=0.0.0.0 TCP:127.0.0.1:40000 &Máy bên ngoài hiện có thể tiếp cận API tại
http://<server-ip>:40001.
Khi bạn khởi động cấu hình trình duyệt qua API, phản hồi sẽ bao gồm động debugPort (ví dụ: 9222). Mỗi hồ sơ có thể nhận được một cổng khác nhau. Chuyển tiếp nó để các công cụ tự động hóa bên ngoài (Playwright, Puppeteer, Selenium) có thể kết nối:
# Example: if debugPort=9222, forward to external port 9223 (debugPort + 1)
# Adjust both ports to match the actual debugPort returned by /api/env/start
nohup socat TCP-LISTEN:9223,fork,reuseaddr,bind=0.0.0.0 TCP:127.0.0.1:9222 &[!WARNING] Khi chạy đồng thời nhiều cấu hình, hãy đảm bảo các cổng chuyển tiếp không xung đột với các cổng gỡ lỗi của cấu hình khác. Ví dụ: nếu cấu hình A nhận được
debugPort=9222và bạn chuyển tiếp tới9223nhưng cấu hình B nhận đượcdebugPort=9223thì sẽ xảy ra xung đột cổng. Hãy cân nhắc sử dụng khoảng chênh lệch lớn hơn hoặc phạm vi cổng chuyên dụng.
[!TIP] Trong quá trình sản xuất, hãy tạo chuyển tiếp socat động sau mỗi cuộc gọi
/api/env/start, sử dụngdebugPortđược trả về. Xem ví dụ về Python để biết cách triển khai hoạt động.
Nếu chạy tập lệnh tự động hóa trên cùng một máy chủ, bạn có thể bỏ qua socat và kết nối trực tiếp với
127.0.0.1.
Nếu bạn sử dụng socat, chỉ hạn chế quyền truy cập vào các IP đáng tin cậy:
# Allow only a specific IP (recommended)
sudo ufw allow from <YOUR_IP> to any port 40001 proto tcp
sudo ufw allow from <YOUR_IP> to any port 9223 proto tcp
# Or allow from any IP (NOT recommended for production)
# sudo ufw allow 40001/tcp
# sudo ufw allow 9223/tcpĐể truy cập từ xa an toàn nhất, hãy sử dụng đường hầm SSH — không cần thay đổi tường lửa hoặc socat.
Vì cổng CDP là động (được chỉ định khi bạn khởi động cấu hình) nên quy trình làm việc là:
Trước tiên hãy đào cổng API:
# Run this on your local machine ssh -L 40000:127.0.0.1:40000 user@<server-ip>Bắt đầu cấu hình qua API được tạo đường hầm (
http://127.0.0.1:40000/api/env/start) và đọcdebugPortđược trả về.Mở đường hầm thứ hai cho cổng CDP:
# Replace <debugPort> with the actual port returned by the API ssh -L <debugPort>:127.0.0.1:<debugPort> user@<server-ip>Kết nối với
http://127.0.0.1:<debugPort>từ tập lệnh Nhà viết kịch / Người múa rối cục bộ của bạn như thể máy chủ là cục bộ.
[!TIP] Bạn có thể kết hợp cả hai đường hầm trong một lệnh nếu bạn biết trước phạm vi cổng, ví dụ:
ssh -L 40000:127.0.0.1:40000 -L 9222:127.0.0.1:9222 -L 9223:127.0.0.1:9223 user@<server-ip>Nhưng trên thực tế, việc khởi động đường hầm API trước sẽ dễ dàng hơn, sau đó thêm đường hầm theo từng cấu hình nếu cần.
Dưới đây là ví dụ Python tối thiểu hiển thị toàn bộ vòng đời của cấu hình trình duyệt. Để biết tập lệnh hoàn chỉnh sẵn sàng sản xuất có tính năng xử lý đồng thời và lỗi, hãy xem ví dụ đầy đủ trên GitHub.
pip install requests playwrightNhà viết kịch chỉ được sử dụng ở đây cho ứng dụng khách CDP (
connect_over_cdp). Bạn không cần chạyplaywright install— MoreLogin cung cấp trình duyệt riêng.
Trên Linux Server, trình duyệt phải chạy với cờ --no-sandbox. Bạn truyền tham số này qua trường startupParams khi tạo hoặc cập nhật hồ sơ trình duyệt.
[!CAUTION] Nếu thiếu
--no-sandbox, trình duyệt sẽ không thể khởi chạy trên hầu hết các môi trường Linux server (đặc biệt khi chạy với quyềnroothoặc thiếu phiên desktop đầy đủ).
Sử dụng /api/env/create/advanced để tạo hồ sơ có startupParams (endpoint /api/env/create/quick không hỗ trợ trường này):
curl -X POST http://127.0.0.1:40000/api/env/create/advanced \
-H "Content-Type: application/json" \
-d '{
"browserTypeId": 1,
"operatorSystemId": 5,
"startupParams": ["--no-sandbox"]
}'[!TIP] Nếu bạn đã dùng
/api/env/create/quickđể tạo hồ sơ, hãy gọi/api/env/updateđể thêm--no-sandboxtrước khi khởi chạy — xem bên dưới.
Nếu bạn đã có hồ sơ trình duyệt được tạo mà không có --no-sandbox, hãy cập nhật trước khi khởi chạy:
curl -X POST http://127.0.0.1:40000/api/env/update \
-H "Content-Type: application/json" \
-d '{
"envId": "YOUR_ENV_ID",
"startupParams": ["--no-sandbox"]
}'[!NOTE] Trường
startupParamschấp nhận một mảng chuỗi. Bạn cũng có thể thêm các cờ Chrome khác (ví dụ:["--no-sandbox", "--disable-gpu"]). Cờ--no-sandboxchỉ cần thiết trên Linux — các hồ sơ Windows và macOS không cần.
Ví dụ này giả định tập lệnh chạy trên cùng một máy chủ với MoreLogin. Đối với các kịch bản từ xa, hãy xem ghi chú sau mã.
import requests
from playwright.sync_api import sync_playwright
# ── Configuration ──────────────────────────────────────────
# Local: script runs on the SAME server as MoreLogin
# Remote: script runs on a DIFFERENT machine — see notes below
API_BASE = "http://127.0.0.1:40000"
# ① Create a browser profile
resp = requests.post(f"{API_BASE}/api/env/create/quick", json={
"browserTypeId": 1,
"operatorSystemId": 5,
"quantity": 1
})
resp_data = resp.json()
assert resp_data["code"] == 0, f"Create failed: {resp_data}"
env_id = resp_data["data"]["envIds"][0]
print(f"✅ Created profile: {env_id}")
# ①-b Add --no-sandbox (required on Linux Server)
resp = requests.post(f"{API_BASE}/api/env/update", json={
"envId": env_id,
"startupParams": ["--no-sandbox"]
})
resp_data = resp.json()
assert resp_data["code"] == 0, f"Update failed: {resp_data}"
print(f"✅ Set --no-sandbox for profile: {env_id}")
# ② Start the profile (headless)
resp = requests.post(f"{API_BASE}/api/env/start", json={
"envId": env_id
})
resp_data = resp.json()
assert resp_data["code"] == 0, f"Start failed: {resp_data}"
debug_port = resp_data["data"]["debugPort"] # Dynamic — different for each profile
print(f"✅ Started — debug port: {debug_port}")
# ③ Build the CDP URL
cdp_url = f"http://127.0.0.1:{debug_port}"
# ④ Connect via CDP and automate
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp_url)
page = browser.contexts[0].pages[0]
page.goto("https://www.google.com")
page.screenshot(path=f"screenshot_{env_id}.png")
print(f"✅ Screenshot saved")
# Use disconnect() — not close() — to detach without killing the browser.
# The profile will be stopped cleanly via the API in step ⑤.
browser.disconnect()
# ⑤ Stop the profile
requests.post(f"{API_BASE}/api/env/close", json={"envId": env_id})
print(f"✅ Profile stopped")
# ⑥ Delete the profile
requests.post(f"{API_BASE}/api/env/remove", json={"envIds": [env_id]})
print(f"✅ Profile deleted")[!NOTE] Chạy từ máy từ xa? Hai cách tiếp cận:
Tùy chọn A — Đường hầm SSH (được khuyến nghị): Thiết lập đường hầm SSH từ máy cục bộ của bạn đến máy chủ (xem § 4.4), sau đó giữ
API_BASE = "http://127.0.0.1:40000"vàcdp_url = f"http://127.0.0.1:{debug_port}"— SSH làm cho các cổng từ xa xuất hiện cục bộ.Tùy chọn B — socat trên máy chủ: Trên máy chủ, bắt đầu chuyển tiếp socat cho cổng API và cho mỗi cổng CDP:
# Chạy chúng trên MÁY CHỦ, không phải trên máy cục bộ của bạn socat TCP-LISTEN:40001,fork,reuseaddr,bind=0.0.0.0 TCP:127.0.0.1:40000 & socat TCP-LISTEN:$((debug_port+1)),fork,reuseaddr,bind=0.0.0.0 TCP:127.0.0.1:$debug_port &Sau đó, trong tập lệnh của bạn, hãy đặt
API_BASE = "http://<server-ip>:40001"vàcdp_url = f"http://<server-ip>:{debug_port + 1}". ⚠️ Hạn chế quyền truy cập bằng quy tắc tường lửa — xem § 4.3.
[!IMPORTANT] Cấu trúc
resp.json()["data"]["envIds"]khớp với định dạng phản hồi/api/env/create/quickhiện tại. Nếu bạn gặp một hình dạng khác (ví dụ:data: ["id1", ...]), hãy kiểm tra Tham khảo API cho phiên bản của bạn — định dạng phản hồi có thể khác nhau giữa các bản phát hành.
Các kết quả sau đây thu được trên máy ảo Ubuntu 24.04 Server (8 vCPU, 8 GB RAM) bằng cách sử dụng tập lệnh kiểm tra mức độ căng thẳng đầy đủ:
| Số liệu | Giá trị |
|---|---|
| Tổng số lượt chạy | 100 |
| Đồng thời | 4 (đồng thời) |
| Tỷ lệ thành công | 100,0% |
| Tổng thời gian | 604,06 giây |
| Thời gian trung bình cho mỗi nhiệm vụ | 6,04 giây |
| Thông lượng | 0,17 nhiệm vụ/giây |
Những con số này phục vụ như là một đường cơ sở. Hiệu suất thực tế phụ thuộc vào thông số kỹ thuật của máy chủ, điều kiện mạng và độ phức tạp của trang.
Đối với các máy chủ sản xuất, hãy chạy MoreLogin dưới dạng dịch vụ systemd để tự động khởi động khi khởi động, khởi động lại khi gặp sự cố và ghi nhật ký tập trung.
sudo tee /etc/systemd/system/morelogin.service > /dev/null <<'EOF'
[Unit]
Description=MoreLogin Browser (headless)
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=root
WorkingDirectory=/opt/morelogin
ExecStart=/usr/bin/xvfb-run -a /opt/morelogin/MoreLogin_x86_64_2.54.0.AppImage --no-sandbox
Restart=on-failure
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOFĐiều chỉnh đường dẫn
WorkingDirectoryvàExecStartđể khớp với vị trí bạn đã đặt AppImage.
[!TIP] Đối với sản xuất, hãy cân nhắc việc tạo người dùng chuyên dụng (ví dụ:
morelogin) thay vì chạy dưới dạngrootvà điều chỉnh quyền sở hữu cũng như quyền đối với tệp cho phù hợp. Nếu AppImage hiện yêu cầu đặc quyền root thì bạn có thể giữUser=rootnhưng cách ly quy trình trong tài khoản không phải root là cách tốt nhất.
sudo systemctl daemon-reload
sudo systemctl enable morelogin # Auto-start on boot
sudo systemctl start morelogin # Start nowsudo systemctl status morelogin # Check status
sudo journalctl -u morelogin -f # Stream logs
sudo systemctl restart morelogin # Restart
sudo systemctl stop morelogin # Stop[!NOTE] Sau khi khởi động lại, bạn phải gọi lại điểm cuối đăng nhập — phiên API không tồn tại trong quá trình khởi động lại. Để khôi phục tự động, hãy cân nhắc thêm tập lệnh
ExecStartPosthoặc công việc định kỳ kiểm tra tình trạng gọi điểm cuối đăng nhập sau khi dịch vụ khởi động.
AppImages require FUSE to run.Khắc phục: Cài đặt hỗ trợ FUSE:
sudo apt install -y libfuse2t64Khắc phục: Cài đặt gói phông chữ cho ngôn ngữ đích (xem Bước 1 — Cài đặt phông chữ).
Lý do: Cổng gỡ lỗi CDP liên kết với 127.0.0.1 theo mặc định.
Khắc phục: Thiết lập chuyển tiếp socat (xem Bước 4) và đảm bảo quy tắc tường lửa cho phép cổng chuyển tiếp.
Lý do: MoreLogin chưa khởi động xong hoặc quá trình bị lỗi.
Sửa chữa:
- Đợi 5–10 giây sau khi khởi động
- Kiểm tra
morelogin.logđể tìm lỗi - Xác minh quy trình đang chạy:
ps aux | grep MoreLogin
{"status": "error", "code": 401, "message": "Your login status has expired, please log in again"}Lý do: Bạn chưa đăng nhập qua API hoặc quá trình MoreLogin đã được khởi động lại.
Khắc phục: Gọi điểm cuối đăng nhập trước bất kỳ lệnh gọi API nào khác (xem Bước 3).
| Mục tiêu | liên kết |
|---|---|
| Tài liệu tham khảo API trình duyệt đầy đủ | API trình duyệt |
| Thiết lập xác thực | Hướng dẫn xác thực |
| Ví dụ về nhà viết kịch / Selenium / Puppeteer | Ví dụ về tự động hóa |
| Hoàn thành tập lệnh kiểm tra căng thẳng Linux | GitHub — linux_server_test.py |
| CLI bắt đầu nhanh | Hướng dẫn CLI |