Saltar al contenido
Last updated

Implementación del servidor Linux

Implemente MoreLogin en un servidor Ubuntu sin cabeza y automatice los perfiles del navegador a través de la API local, sin necesidad de un entorno de escritorio.


Lo que lograrás

Al final de esta guía tendrás:

  1. Una instancia de MoreLogin en ejecución en un servidor sin cabeza Ubuntu 24.04
  2. Reenvío de red configurado para que las máquinas externas puedan conectarse a través de CDP (Protocolo Chrome DevTools)
  3. Un script de automatización de Python funcional que crea, inicia, controla y limpia perfiles del navegador.

Descripción general de la arquitectura

┌──────────────────────────────────────────────────────────┐
│                    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] El puerto de depuración de CDP es dinámico: cada perfil de navegador tiene su propio puerto, devuelto por el punto final /api/env/start. El diagrama anterior utiliza <N> como marcador de posición.


Requisitos previos

RequisitoDetalles
Sistema operativoServidor Ubuntu 24.04 (x86_64)
Especificaciones recomendadas8 vCPU, 8 GB de RAM (admite ~5 perfiles simultáneos)
RedAcceso a Internet saliente; abra el puerto de entrada 40001 y los puertos CDP reenviados que elija, o utilice túneles SSH en su lugar
Python (opcional)Python 3.8+ con pip para ejecutar el script de ejemplo

Paso 1: instalar las dependencias del sistema

Conéctese a su servidor a través de SSH e instale los paquetes requeridos:

# 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

Instalar fuentes (opcional)

Si las páginas del navegador se muestran sin texto o muestran caracteres faltantes, instale los paquetes de fuentes correspondientes:

# 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

Para otros idiomas, instale el paquete familia de fuentes Noto correspondiente.


Paso 2: Descargar y ejecutar MásIniciar sesión

2.1 Descargar la AppImage

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

Reemplace 2.54.0 con la última versión disponible en su cuenta MoreLogin o en la página de descarga.

2.2 Comenzar másIniciar sesión en segundo plano

Utilice xvfb-run para proporcionar una pantalla virtual, luego ejecute AppImage:

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

Verifique que haya comenzado exitosamente:

# Check the process is running
ps aux | grep MoreLogin

El proceso puede tardar entre 5 y 10 segundos en inicializarse por completo.


Paso 3: inicie sesión en MoreLogin mediante API (obligatorio)

[!CAUTION] Debe iniciar sesión antes de llamar a cualquier otro punto final de API local. En un servidor sin cabeza no hay una GUI para iniciar sesión manualmente, por lo que debe autenticarse a través de la API. Sin este paso, todas las llamadas API devolverán:

{"status": "error", "code": 401, "message": "Su estado de inicio de sesión ha caducado, inicie sesión nuevamente"}

3.1 Obtenga sus credenciales API

Abra el cliente de escritorio MoreLogin (en cualquier máquina en la que haya iniciado sesión) y navegue hasta Configuración → API y MCP. Copie el ID de aplicación y la Clave de API de la sección Abrir API:

Más configuración de API de inicio de sesión: copie el ID de la aplicación y la clave de API de la sección Abrir API

3.2 Iniciar sesión mediante curl

Llame al punto final de inicio de sesión con sus credenciales:

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

Una respuesta exitosa se parece a:

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

3.3 Verificar el inicio de sesión

Confirme que la API esté lista enumerando los perfiles del navegador:

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

Una respuesta {"code":0, ...} significa que ha iniciado sesión y que la API está lista.

Punto de control: Su servidor MoreLogin está en pleno funcionamiento. Continúe con el Paso 4 para obtener acceso remoto o vaya directamente al Paso 5 si ejecuta scripts en el mismo servidor.

[!NOTE] La sesión de inicio de sesión persiste mientras se esté ejecutando el proceso MoreLogin. Si reinicia AppImage, deberá iniciar sesión nuevamente.


Paso 4: configurar el reenvío de red (socat)

De forma predeterminada, tanto la API local (:40000) como los puertos de depuración del CDP se vinculan a 127.0.0.1. Si necesita acceder a ellos desde una máquina externa (por ejemplo, su computadora portátil de desarrollo), use socat para reenviar el tráfico.

[!WARNING] Riesgo de seguridad: no exponga estos puertos a la Internet pública.

  • La API local no tiene autenticación integrada para la mayoría de los puntos finales.
  • Un puerto de depuración CDP otorga control remoto total de la instancia del navegador (leer cookies, inyectar scripts, capturar capturas de pantalla).

Recomendaciones:

  • Utilice un túnel SSH en lugar de socat para acceso remoto: ssh -L 40000:127.0.0.1:40000 user@server
  • Si debe usar socat, restrinja el acceso con reglas de firewall a IP específicas únicamente
  • Utilice una VPN o grupos de seguridad de proveedores de nube para limitar el tráfico entrante
  • Nunca abra los puertos 40001/CDP a 0.0.0.0 en un servidor público sin restricciones de IP

4.1 Reenviar el puerto API local

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

Las máquinas externas ahora pueden acceder a la API en http://<server-ip>:40001.

4.2 Puertos de depuración CDP directos

Cuando inicia un perfil de navegador a través de la API, la respuesta incluye un debugPort dinámico (por ejemplo, 9222). Cada perfil puede recibir un puerto diferente. Reenvíelo para que las herramientas de automatización externas (Playwright, Puppeteer, Selenium) puedan conectarse:

# 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] Cuando ejecute varios perfiles simultáneamente, asegúrese de que los puertos reenviados no choquen con los puertos de depuración de otros perfiles. Por ejemplo, si el perfil A obtiene debugPort=9222 y usted reenvía a 9223, pero el perfil B recibe debugPort=9223, habrá un conflicto de puerto. Considere utilizar un desplazamiento mayor o un rango de puertos dedicado.

[!TIP] En producción, cree el reenvío socat dinámicamente después de cada llamada /api/env/start, utilizando el debugPort devuelto. Consulte el ejemplo de Python para ver una implementación funcional.

Si ejecuta scripts de automatización en el mismo servidor, puede omitir socat y conectarse directamente a 127.0.0.1.

4.3 Abrir puertos de firewall

Si usa socat, restrinja el acceso solo a direcciones IP confiables:

# 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 Recomendado: utilice el túnel SSH en su lugar

Para obtener el acceso remoto más seguro, utilice un túnel SSH: no se necesitan cambios en el firewall ni socat.

Debido a que el puerto CDP es dinámico (asignado cuando inicia un perfil), el flujo de trabajo es:

  1. Primero canalice el puerto API:

    # Run this on your local machine
    ssh -L 40000:127.0.0.1:40000 user@<server-ip>
  2. Inicie el perfil a través de la API tunelizada (http://127.0.0.1:40000/api/env/start) y lea el debugPort devuelto.

  3. Abrir un segundo túnel para el puerto CDP:

    # Replace <debugPort> with the actual port returned by the API
    ssh -L <debugPort>:127.0.0.1:<debugPort> user@<server-ip>
  4. Conéctate a http://127.0.0.1:<debugPort> desde tus scripts locales de Playwright/Puppeteer como si el servidor fuera local.

[!TIP] Puede combinar ambos túneles en un comando si conoce el rango de puertos de antemano, por ejemplo:

ssh -L 40000:127.0.0.1:40000 -L 9222:127.0.0.1:9222 -L 9223:127.0.0.1:9223 usuario@<ip-servidor>

Pero en la práctica es más fácil iniciar primero el túnel API y luego agregar túneles por perfil según sea necesario.


Paso 5: ejemplo de automatización rápida

A continuación se muestra un ejemplo mínimo de Python que muestra el ciclo de vida completo de un perfil de navegador. Para obtener el script completo listo para producción con simultaneidad y manejo de errores, consulte el ejemplo completo en GitHub.

5.1 Instalar dependencias de Python

pip install requests playwright

Playwright se utiliza aquí solo para su cliente CDP (connect_over_cdp). No es necesario ejecutar playwright install: MoreLogin proporciona su propio navegador.

5.2 Configurar --no-sandbox para Perfiles de Navegador (Obligatorio en Linux)

En Linux Server, el motor del navegador debe ejecutarse con la bandera --no-sandbox. Este parámetro se pasa a través del campo startupParams al crear o actualizar un perfil de navegador.

[!CAUTION] Sin --no-sandbox, el navegador no podrá iniciarse en la mayoría de los entornos de servidor Linux (especialmente al ejecutar como root o sin una sesión de escritorio completa).

Nuevos perfiles — incluir startupParams en la creación

Use /api/env/create/advanced para crear un perfil con startupParams (el endpoint /api/env/create/quick no soporta este campo):

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] Si usó /api/env/create/quick para crear el perfil, llame a /api/env/update para agregar --no-sandbox antes de iniciarlo — vea a continuación.

Perfiles existentes — actualizar mediante /api/env/update

Si ya tiene perfiles de navegador creados sin --no-sandbox, actualícelos antes de iniciar:

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] El campo startupParams acepta un array de strings. También puede incluir otras banderas de Chrome (por ejemplo, ["--no-sandbox", "--disable-gpu"]). La bandera --no-sandbox solo es necesaria en Linux — los perfiles de Windows y macOS no la necesitan.


5.3 Crear → Iniciar → Automatizar → Limpiar

Este ejemplo supone que el script se ejecuta en el mismo servidor que MoreLogin. Para escenarios remotos, consulte las notas después del código.

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] ¿Se ejecuta desde una máquina remota? Dos enfoques:

Opción A: túnel SSH (recomendado): Configure túneles SSH desde su máquina local al servidor (consulte § 4.4), luego mantenga API_BASE = "http://127.0.0.1:40000" y cdp_url = f"http://127.0.0.1:{debug_port}": SSH hace que los puertos remotos parezcan locales.

Opción B: socat en el servidor: En el servidor, inicie el reenvío socat para el puerto API y para cada puerto CDP:

# Ejecútelos en el SERVIDOR, no en su máquina local
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 &

Luego, en su secuencia de comandos, configure API_BASE = "http://<server-ip>:40001" y cdp_url = f"http://<server-ip>:{debug_port + 1}". ⚠️ Restringir el acceso con reglas de firewall: consulte § 4.3.

[!IMPORTANT] La estructura resp.json()["data"]["envIds"] coincide con el formato de respuesta /api/env/create/quick actual. Si encuentra una forma diferente (por ejemplo, data: ["id1", ...]), consulte la Referencia de API para su versión; los formatos de respuesta pueden variar según la versión.


Punto de referencia de rendimiento

Se obtuvieron los siguientes resultados en una máquina virtual de servidor Ubuntu 24.04 (8 vCPU, 8 GB de RAM) utilizando el script de prueba de esfuerzo completo:

MétricaValor
Ejecuciones totales100
Simultaneidad4 (simultáneo)
Tasa de éxito100,0%
Tiempo total604,06 segundos
Tiempo promedio por tarea6,04 segundos
Rendimiento0,17 tareas/s

Estos números sirven como punto de referencia. El rendimiento real depende de las especificaciones del servidor, las condiciones de la red y la complejidad de la página.


Implementación de producción (systemd)

Para servidores de producción, ejecute MoreLogin como un servicio systemd para obtener un inicio automático al arrancar, reiniciar en caso de falla y un registro centralizado.

Crear el archivo de servicio

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

Ajuste las rutas WorkingDirectory y ExecStart para que coincidan con el lugar donde colocó la AppImage.

[!TIP] Para producción, considere crear un usuario dedicado (por ejemplo, morelogin) en lugar de ejecutarlo como root y ajuste la propiedad y los permisos del archivo en consecuencia. Si AppImage actualmente requiere privilegios de root, puede conservar User=root, pero aislar el proceso en una cuenta que no sea root es una buena práctica.

Habilitar e iniciar

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

Gestionar el servicio

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

[!NOTE] Después de reiniciar, debe volver a llamar al punto final de inicio de sesión; la sesión API no sobrevive a los reinicios del proceso. Para una recuperación automatizada, considere agregar un script ExecStartPost o un trabajo cron de verificación de estado que llame al punto final de inicio de sesión después de que se inicie el servicio.


Solución de problemas

MásEl inicio de sesión no puede iniciarse

AppImages require FUSE to run.

Solución: Instalar soporte FUSE:

sudo apt install -y libfuse2t64

Las páginas del navegador muestran texto en blanco o caracteres faltantes

Solución: Instale el paquete de fuentes para el idioma de destino (consulte Paso 1: Instalar fuentes).

Conexión CDP rechazada desde una máquina externa

Causa: Los puertos de depuración de CDP se vinculan a 127.0.0.1 de forma predeterminada.

Solución: Configure el reenvío socat (consulte el Paso 4) y asegúrese de que las reglas del firewall permitan el puerto reenviado.

curl a la API local devuelve "Conexión rechazada"

Causa: MoreLogin aún no ha terminado de iniciarse o el proceso falló.

Arreglo:

  1. Espere de 5 a 10 segundos después del inicio
  2. Verifique morelogin.log para ver si hay errores
  3. Verifique que el proceso se esté ejecutando: ps aux | grep MoreLogin

API devuelve 401 "el estado de inicio de sesión ha caducado"

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

Causa: No has iniciado sesión a través de la API o se reinició el proceso MoreLogin.

Solución: Llame al punto final de inicio de sesión antes de cualquier otra llamada API (consulte el Paso 3).


Próximos pasos

ObjetivoEnlace
Referencia completa de la API del navegadorAPI del navegador
Configuración de autenticaciónGuía de autenticación
Ejemplos de Playwright / Selenium / PuppeteerEjemplos de automatización
Script completo de prueba de estrés de LinuxGitHub — linux_server_test.py
Inicio rápido de CLIGuía CLI