# Розгортання сервера Linux

Розгорніть MoreLogin на безголовому сервері Ubuntu та автоматизуйте профілі браузера через локальний API — середовище робочого столу не потрібне.

## Чого ви досягнете

До кінця цього посібника ви матимете:

1. Запущений екземпляр MoreLogin на безголовому сервері Ubuntu 24.04
2. Мережеву переадресацію налаштовано, щоб зовнішні машини могли підключатися через CDP (Chrome DevTools Protocol)
3. Робочий сценарій автоматизації Python, який створює, запускає, контролює та очищає профілі браузера


## Огляд архітектури

```
┌──────────────────────────────────────────────────────────┐
│                    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]
Порт налагодження CDP є **динамічним** — кожен профіль браузера отримує власний порт, який повертає кінцева точка `/api/env/start`. На діаграмі вище використовується `<N>` як заповнювач.


## передумови

| Вимога | Подробиці |
|  --- | --- |
| **Операційна система** | Сервер Ubuntu 24.04 (x86_64) |
| **Рекомендовані характеристики** | 8 vCPU, 8 ГБ оперативної пам’яті (підтримує ~5 одночасних профілів) |
| **Мережа** | Вихідний доступ до Інтернету; відкрийте вхідний порт `40001` і вибрані вами перенаправлені порти CDP або використовуйте натомість тунелі SSH |
| **Python** (необов’язково) | Python 3.8+ із `pip` для виконання прикладу сценарію |


## Крок 1 — Встановіть системні залежності

Підключіться до свого сервера через SSH і встановіть необхідні пакети:

```bash
# 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
```

### Встановити шрифти (необов'язково)

Якщо сторінки браузера відображаються без тексту або показують відсутні символи, інсталюйте відповідні пакети шрифтів:

```bash
# 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
```

> Для інших мов установіть відповідний пакет [Сімейство шрифтів Noto](https://fonts.google.com/noto).


## Крок 2 — Завантажте та запустіть MoreLogin

### 2.1 Завантажте AppImage

```bash
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
```

> Замініть `2.54.0` останньою версією, доступною у вашому обліковому записі MoreLogin або на [сторінці завантаження](https://www.morelogin.com/download/).


### 2.2 Запустіть MoreLogin у фоновому режимі

Використовуйте `xvfb-run`, щоб створити віртуальний дисплей, а потім запустіть AppImage:

```bash
nohup xvfb-run -a ./MoreLogin_x86_64_2.54.0.AppImage --no-sandbox > morelogin.log 2>&1 &
```

Переконайтеся, що він розпочався успішно:

```bash
# Check the process is running
ps aux | grep MoreLogin
```

> Процес повної ініціалізації може зайняти 5–10 секунд.


## Крок 3 — увійдіть до MoreLogin через API (обов’язково)

> [!CAUTION]
**Ви повинні увійти в систему, перш ніж викликати будь-яку іншу локальну кінцеву точку API.** На безголовому сервері немає графічного інтерфейсу для входу вручну, тому ви повинні пройти автентифікацію через API. Без цього кроку всі виклики API повернуться:

```json
{"status": "помилка", "code": 401, "message": "Ваш статус входу минув, увійдіть знову"}
```


### 3.1 Отримайте свої облікові дані API

Відкрийте настільний клієнт MoreLogin (на будь-якій машині, де ви ввійшли в систему) і перейдіть до **Налаштування → API та MCP**. Скопіюйте **APP ID** і **API Key** із розділу **Open API**:

![Більше налаштувань API входу — скопіюйте ідентифікатор APP і ключ API із розділу Open API](/assets/image.cfac9a4c31ae47e8434739e42cab4601ee08d737bba4fccba40f2f3bc78e9648.b25c25ba.png)

### 3.2 Увійдіть через curl

Викличте кінцеву точку входу за допомогою облікових даних:

```bash
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"
  }'
```

Успішна відповідь виглядає так:

```json
{"code": 0, "msg": null, "data": true}
```

### 3.3 Перевірте логін

Переконайтеся, що API готовий, перерахувавши профілі браузера:

```bash
curl -s -X POST http://127.0.0.1:40000/api/env/page \
  -H "Content-Type: application/json" \
  -d '{"pageNo": 1, "pageSize": 1}'
```

> Відповідь `{"code":0, ...}` означає, що ви ввійшли в систему та API готовий.


> **Контрольна точка:** Ваш сервер MoreLogin працює повністю. Перейдіть до [кроку 4](#step-4--configure-network-forwarding-socat) для віддаленого доступу або перейдіть безпосередньо до [кроку 5](#step-5--quick-automation-example), якщо сценарії запущено на тому самому сервері.


> [!NOTE]
Сеанс входу триває доти, доки виконується процес MoreLogin. Якщо ви перезапустите AppImage, вам потрібно буде знову ввійти.


## Крок 4 — Налаштуйте мережеву переадресацію (socat)

За замовчуванням і локальний API (`:40000`), і порти налагодження CDP прив’язуються до `127.0.0.1`. Якщо вам потрібно отримати до них доступ із зовнішнього комп’ютера (наприклад, ноутбука для розробки), використовуйте `socat` для перенаправлення трафіку.

> [!WARNING]
**Ризик безпеці — не піддавайте ці порти загальнодоступному Інтернету.**
- Локальний API не має **вбудованої автентифікації** для більшості кінцевих точок.
- Порт налагодження CDP забезпечує **повне дистанційне керування** екземпляром браузера (читання файлів cookie, введення сценаріїв, створення скріншотів).

**Рекомендації:**
- Використовуйте **тунель SSH** замість socat для віддаленого доступу: `ssh -L 40000:127.0.0.1:40000 user@server`
- Якщо вам потрібно використовувати socat, обмежте доступ за допомогою правил брандмауера до **лише певних IP-адрес**
- Використовуйте **VPN** або групи безпеки хмарного провайдера, щоб обмежити вхідний трафік
- **Ніколи** не відкривайте порти `40001` / порти CDP для `0.0.0.0` на загальнодоступному сервері без обмежень IP



### 4.1 Переадресація порту локального API

```bash
nohup socat TCP-LISTEN:40001,fork,reuseaddr,bind=0.0.0.0 TCP:127.0.0.1:40000 &
```

> Зовнішні машини тепер можуть отримати доступ до API за адресою `http://<server-ip>:40001`.


### 4.2 Прямі порти налагодження CDP

Коли ви запускаєте профіль браузера через API, відповідь включає **динамічний** `debugPort` (наприклад, `9222`). Кожен профіль може отримати інший порт. Передайте його, щоб зовнішні інструменти автоматизації (Playwright, Puppeteer, Selenium) могли підключитися:

```bash
# 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]
Під час одночасного запуску кількох профілів переконайтеся, що перенаправлені порти не конфліктують із портами налагодження інших профілів. Наприклад, якщо профіль A отримує `debugPort=9222` і ви пересилаєте на `9223`, а профіль B отримує `debugPort=9223`, виникне конфлікт портів. Розгляньте можливість використання більшого зміщення або виділеного діапазону портів.


> [!TIP]
У виробництві створюйте переадресацію socat **динамічно** після кожного виклику `/api/env/start`, використовуючи повернутий `debugPort`. Перегляньте [приклад Python](#52-create--start--automate--cleanup), щоб дізнатися про робочу реалізацію.


> Якщо сценарії автоматизації запускаються **на тому самому сервері**, ви можете пропустити socat і підключитися безпосередньо до `127.0.0.1`.


### 4.3 Відкрийте порти брандмауера

Якщо ви використовуєте socat, обмежте доступ лише надійним IP-адресам:

```bash
# 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 Рекомендовано: замість цього використовуйте тунель SSH

Для найбезпечнішого віддаленого доступу використовуйте тунель SSH — не потрібно змінювати брандмауер або socat.

Оскільки порт CDP є **динамічним** (призначається під час запуску профілю), робочий процес такий:

1. **Спочатку тунелюйте порт API:**

```bash
# Run this on your local machine
ssh -L 40000:127.0.0.1:40000 user@<server-ip>
```
2. **Запустіть профіль** через тунельований API (`http://127.0.0.1:40000/api/env/start`) і прочитайте отриманий `debugPort`.
3. **Відкрийте другий тунель для порту CDP:**

```bash
# Replace <debugPort> with the actual port returned by the API
ssh -L <debugPort>:127.0.0.1:<debugPort> user@<server-ip>
```
4. **Підключіться** до `http://127.0.0.1:<debugPort>` зі своїх локальних сценаріїв Playwright / Puppeteer, ніби сервер локальний.


> [!TIP]
Ви можете поєднати обидва тунелі в одній команді, якщо заздалегідь знаєте діапазон портів, наприклад:

```баш
ssh -L 40000:127.0.0.1:40000 -L 9222:127.0.0.1:9222 -L 9223:127.0.0.1:9223 користувач@<ip-сервер>
```
Але на практиці простіше спочатку запустити тунель API, а потім за потреби додавати тунелі для кожного профілю.


## Крок 5 — Приклад швидкої автоматизації

Нижче наведено мінімальний приклад Python, який показує повний життєвий цикл профілю браузера. Щоб отримати повний сценарій, готовий до роботи, із паралелізмом і обробкою помилок, перегляньте [повний приклад на GitHub](https://github.com/MoreLoginBrowser/MoreLogin-API-Demos/blob/main/MoreLogin-Python/linux_server_test.py).

### 5.1 Встановлення залежностей Python

```bash
pip install requests playwright
```

> Playwright використовується тут лише для клієнта CDP (`connect_over_cdp`). Вам **не** потрібно запускати `playwright install` — MoreLogin пропонує власний браузер.


### 5.2 Створити → Пуск → Автоматизувати → Очищення

У цьому прикладі передбачається, що сценарій виконується **на тому самому сервері**, що й MoreLogin. Для віддалених сценаріїв див. примітки після коду.

```python
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": 1,
    "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}")


# ② 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]
**Запускаєте з віддаленої машини?** Два підходи:
**Варіант A — тунель SSH (рекомендовано):**
Налаштуйте тунелі SSH від вашої локальної машини до сервера (див. [§ 4.4](#44-recommended-use-ssh-tunnel-instead)), а потім збережіть `API_BASE = "http://127.0.0.1:40000"` і `cdp_url = f"http://127.0.0.1:{debug_port}"` — SSH робить віддалені порти локальними.
**Варіант B — socat на сервері:**
На **сервері** запустіть переадресацію socat для порту API та для кожного порту CDP:

```баш
# Запустіть їх на СЕРВЕРІ, а не на вашій локальній машині
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 &
```
Потім у вашому сценарії встановіть `API_BASE = "http://<server-ip>:40001"` і `cdp_url = f"http://<server-ip>:{debug_port + 1}"`.
⚠️ Обмежте доступ за допомогою правил брандмауера — див. [§ 4.3](#43-open-firewall-ports).


> [!IMPORTANT]
Структура `resp.json()["data"]["envIds"]` відповідає поточному формату відповіді `/api/env/create/quick`. Якщо ви зіткнулися з іншою формою (наприклад, `data: ["id1", ...]`), перевірте [Довідник API](/uk/api-reference/browser) для вашої версії — формати відповідей можуть відрізнятися для різних випусків.


## Тест продуктивності

На віртуальній машині сервера Ubuntu 24.04 (8 vCPU, 8 ГБ оперативної пам’яті) було отримано такі результати за допомогою [повного сценарію стрес-тесту] (https://github.com/MoreLoginBrowser/MoreLogin-API-Demos/blob/main/MoreLogin-Python/linux_server_test.py):

| Метрика | Значення |
|  --- | --- |
| **Загальна кількість пробігів** | 100 |
| **Параллельність** | 4 (одночасно) |
| **Рівень успіху** | 100,0% |
| **Загальний час** | 604.06 с |
| **Середній час виконання завдання** | 6.04 с |
| **Пропускна здатність** | 0,17 задач/с |


> Ці цифри служать базовими. Фактична продуктивність залежить від характеристик сервера, умов мережі та складності сторінки.


## Виробниче розгортання (systemd)

Для робочих серверів запустіть MoreLogin як **systemd service**, щоб отримати автоматичний запуск під час завантаження, перезапуск у разі збою та централізоване журналювання.

### Створіть службовий файл

```bash
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
```

> Відкоригуйте шляхи `WorkingDirectory` і `ExecStart` відповідно до місця розміщення AppImage.


> [!TIP]
Для виробництва розгляньте можливість створення спеціального користувача (наприклад, `morelogin`) замість того, щоб працювати як `root`, і відповідно налаштуйте право власності на файл і дозволи. Якщо для AppImage наразі потрібні привілеї root, ви можете залишити `User=root`, але найкращою практикою є ізоляція процесу під обліковим записом без root.


### Увімкніть і запустіть

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

### Керуйте Сервісом

```bash
sudo systemctl status morelogin    # Check status
sudo journalctl -u morelogin -f    # Stream logs
sudo systemctl restart morelogin   # Restart
sudo systemctl stop morelogin      # Stop
```

> [!NOTE]
Після перезапуску потрібно знову викликати [кінцеву точку входу](#32-log-in-via-curl) — сеанс API не витримує перезапуску процесу. Для автоматичного відновлення розгляньте можливість додавання сценарію `ExecStartPost` або завдання cron перевірки справності, яке викликає кінцеву точку входу після запуску служби.


## Усунення несправностей

### Не вдається запустити MoreLogin

```
AppImages require FUSE to run.
```

**Виправлення:** Встановити підтримку FUSE:

```bash
sudo apt install -y libfuse2t64
```

### На сторінках веб-переглядача відображається порожній текст/пропущені символи

**Виправлення:** Установіть пакет шрифтів для цільової мови (див. [Крок 1 — Установіть шрифти](#install-fonts-optional)).

### Зовнішній комп’ютер відмовив у з’єднанні CDP

**Причина:** порти налагодження CDP прив’язуються до `127.0.0.1` за умовчанням.

**Виправлення:** налаштуйте переадресацію socat (див. [Крок 4](#step-4--configure-network-forwarding-socat)) і переконайтеся, що правила брандмауера дозволяють переадресований порт.

### `curl` до локального API повертає "Відмовлено в підключенні"

**Причина:** MoreLogin ще не завершив запуск, або процес стався збій.

**Виправлення:**

1. Зачекайте 5–10 секунд після запуску
2. Перевірте `morelogin.log` на наявність помилок
3. Переконайтеся, що процес запущено: `ps aux | grep MoreLogin`


### API повертає 401 "термін дії статусу входу минув"

```json
{"status": "error", "code": 401, "message": "Your login status has expired, please log in again"}
```

**Причина:** Ви не ввійшли через API або процес MoreLogin було перезапущено.

**Виправлення:** виклик кінцевої точки входу перед будь-яким іншим викликом API (див. [Крок 3](#step-3--log-in-to-morelogin-via-api-required)).

## Наступні кроки

| Мета | Посилання |
|  --- | --- |
| Повна довідка про API браузера | [API веб-переглядача](/uk/api-reference/browser) |
| Налаштування автентифікації | [Посібник з автентифікації](/uk/api-reference/getting-started/authentication) |
| Драматург / Селен / Приклади лялькаря | [Приклади автоматизації](/uk/api-reference/examples) |
| Повний сценарій стрес-тесту Linux | [GitHub — linux_server_test.py](https://github.com/MoreLoginBrowser/MoreLogin-API-Demos/blob/main/MoreLogin-Python/linux_server_test.py) |
| Швидкий старт CLI | [Посібник CLI](/uk/cli/quick-start) |