Skip to content
Last updated

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.


Những gì bạn sẽ đạt được

Đến cuối hướng dẫn này, bạn sẽ có:

  1. Một phiên bản MoreLogin đang chạy trên máy chủ không đầu Ubuntu 24.04
  2. 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)
  3. 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

Tổng quan về kiến trúc

┌──────────────────────────────────────────────────────────┐
│                    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ỗ.


Điều kiện tiên quyết

Yêu cầuChi tiết
Hệ điều hànhMáy chủ Ubuntu 24.04 (x86_64)
Thông số kỹ thuật được đề xuất8 vCPU, RAM 8 GB (hỗ trợ ~5 cấu hình đồng thời)
MạngTruy 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

Bước 1 - Cài đặt phụ thuộc hệ thống

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 socat

Cài đặt phông chữ (Tùy chọn)

Nế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.


Bước 2 - Tải xuống và khởi chạy ThêmĐăng nhập

2.1 Tải xuống hình ảnh ứng dụng

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.AppImage

Thay thế 2.54.0 bằ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.

2.2 Bắt đầu thêmĐăng nhập trong nền

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 MoreLogin

Quá trình này có thể mất 5–10 giây để khởi tạo hoàn toàn.


Bước 3 - Đăng nhập vào MoreLogin qua API (Bắt buộc)

[!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"}

3.1 Nhận thông tin xác thực API của bạn

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ỤNGKhóa API từ phần Mở API:

Cài đặt API đăng nhập nhiều hơn — Sao chép ID ứng dụng và khóa API từ phần API mở

3.2 Đăng nhập qua cuộn tròn

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}

3.3 Xác minh thông tin đăng nhập

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.


Bước 4 - Định cấu hình Chuyển tiếp mạng (socat)

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ới 0.0.0.0 trên máy chủ công khai mà không có giới hạn IP

4.1 Chuyển tiếp cổng API cục bộ

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.

4.2 Chuyển tiếp cổng gỡ lỗi CDP

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=9222 và bạn chuyển tiếp tới 9223 nhưng cấu hình B nhận được debugPort=9223 thì 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ụng debugPort đượ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.

4.3 Mở cổng tường lửa

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

4.4 Khuyến nghị: Thay vào đó hãy sử dụng Đường hầm SSH

Để 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à:

  1. 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>
  2. 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à đọc debugPort được trả về.

  3. 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>
  4. 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.


Bước 5 - Ví dụ về tự động hóa nhanh

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.

5.1 Cài đặt phụ thuộc Python

pip install requests playwright

Nhà 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ạy playwright install — MoreLogin cung cấp trình duyệt riêng.

5.2 Đặt --no-sandbox cho Hồ sơ Trình duyệt (Bắt buộc trên Linux)

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ền root hoặc thiếu phiên desktop đầy đủ).

Hồ sơ mới — bao gồm startupParams khi tạo

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-sandbox trước khi khởi chạy — xem bên dưới.

Hồ sơ hiện có — cập nhật qua /api/env/update

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 startupParams chấ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-sandbox chỉ cần thiết trên Linux — các hồ sơ Windows và macOS không cần.


5.3 Tạo → Bắt đầu → Tự động hóa → Dọn dẹp

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"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"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/quick hiệ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.


Điểm chuẩn hiệu suất

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ệuGiá trị
Tổng số lượt chạy100
Đồng thời4 (đồng thời)
Tỷ lệ thành công100,0%
Tổng thời gian604,06 giây
Thời gian trung bình cho mỗi nhiệm vụ6,04 giây
Thông lượng0,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.


Triển khai sản xuất (systemd)

Đố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.

Tạo tệp dịch vụ

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 WorkingDirectoryExecStart để 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ạng root và đ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=root nhưng cách ly quy trình trong tài khoản không phải root là cách tốt nhất.

Kích hoạt và bắt đầu

sudo systemctl daemon-reload
sudo systemctl enable morelogin    # Auto-start on boot
sudo systemctl start morelogin     # Start now

Quản lý dịch vụ

sudo 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 ExecStartPost hoặ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.


Khắc phục sự cố

ThêmĐăng nhập không khởi động được

AppImages require FUSE to run.

Khắc phục: Cài đặt hỗ trợ FUSE:

sudo apt install -y libfuse2t64

Các trang trình duyệt hiển thị văn bản trống/ký tự bị thiếu

Khắ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ữ).

Kết nối CDP bị từ chối từ máy bên ngoài

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.

curl tới API cục bộ trả về "Kết nối bị từ chối"

Lý do: MoreLogin chưa khởi động xong hoặc quá trình bị lỗi.

Sửa chữa:

  1. Đợi 5–10 giây sau khi khởi động
  2. Kiểm tra morelogin.log để tìm lỗi
  3. Xác minh quy trình đang chạy: ps aux | grep MoreLogin

API trả về 401 "trạng thái đăng nhập đã hết hạn"

{"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).


Các bước tiếp theo

Mục tiêuliê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ựcHướng dẫn xác thực
Ví dụ về nhà viết kịch / Selenium / PuppeteerVí dụ về tự động hóa
Hoàn thành tập lệnh kiểm tra căng thẳng LinuxGitHub — linux_server_test.py
CLI bắt đầu nhanhHướng dẫn CLI