# Развертывание Linux-сервера

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

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

К концу этого руководства вы будете иметь:

1. Работающий экземпляр MoreLogin на автономном сервере Ubuntu 24.04.
2. Сетевая переадресация настроена так, чтобы внешние машины могли подключаться через CDP (протокол Chrome DevTools).
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 виртуальных ЦП, 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 Загрузите изображение приложения

```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 Запустить большеВойти в фоновом режиме

Используйте `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
{"статус": "ошибка", "код": 401, "сообщение": "Срок действия вашего статуса входа истек, пожалуйста, войдите снова"}
```


### 3.1 Получите свои учетные данные API

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

![Дополнительные настройки API для входа — скопируйте идентификатор приложения и ключ API из раздела «Открытый API»](/assets/image.cfac9a4c31ae47e8434739e42cab4601ee08d737bba4fccba40f2f3bc78e9648.bc76ff01.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)

По умолчанию порты отладки Local 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>` из локальных сценариев драматурга/кукловода, как если бы сервер был локальным.


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

```
ssh -L 40000:127.0.0.1:40000 -L 9222:127.0.0.1:9222 -L 9223:127.0.0.1:9223 user@<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]
**Запуск с удаленного компьютера?** Два подхода:
**Вариант А — 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 делает удаленные порты локальными.
**Вариант Б — 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](/ru/api-reference/browser) для вашей версии — форматы ответов могут различаться в зависимости от версии.


## Тест производительности

Следующие результаты были получены на виртуальной машине сервера Ubuntu 24.04 (8 виртуальных ЦП, 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 как **системную службу**, чтобы обеспечить автоматический запуск при загрузке, перезапуск при сбое и централизованное ведение журнала.

### Создайте служебный файл

```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 проверки работоспособности, которое вызывает конечную точку входа после запуска службы.


## Устранение неполадок

### ПодробнееВход не запускается

```
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` для Local 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 браузера](/ru/api-reference/browser) |
| Настройка аутентификации | [Руководство по аутентификации](/ru/api-reference/getting-started/authentication) |
| Примеры драматурга/Селена/Кукловода | [Примеры автоматизации](/ru/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](/ru/cli/quick-start) |