Configuración de navegador headless en Ubuntu: guía completa para servidores
Cómo configurar la automatización de navegador headless en Ubuntu con Xvfb, dependencias del sistema, servicios systemd y configuración de producción.
Prefieres la documentación del producto mantenida?
Este artículo tiene una página equivalente en el centro de documentación. Usa los docs para el flujo canónico, las flags actuales y la referencia duradera.
Introducción
Ejecutar BotBrowser en un servidor Ubuntu headless es la base de la mayoría de los despliegues de producción. Los servidores no tienen pantallas físicas, los drivers de GPU varían respecto a los sistemas de escritorio y Chrome tiene dependencias específicas de bibliotecas que no están instaladas por defecto en imágenes de servidor mínimas. Resolver estos detalles correctamente es la diferencia entre un entorno de producción estable y fallos intermitentes difíciles de diagnosticar.
Esta guía cubre todo, desde la instalación de dependencias del sistema hasta la configuración de Xvfb (X Virtual Frame Buffer), la creación de servicios systemd para persistencia y la ejecución de BotBrowser con Playwright o Puppeteer en modo headless. Al finalizar, tendrás un servidor Ubuntu confiable que ejecuta instancias de BotBrowser de forma desatendida.
Por qué importa la configuración del servidor headless
Los entornos de escritorio manejan la gestión de pantalla, la inicialización de GPU y el renderizado de fuentes automáticamente. Los entornos de servidor eliminan todo esto. Una instalación mínima de Ubuntu Server carece de las bibliotecas compartidas que Chrome necesita para renderizado, el servidor de pantalla X11 que incluso Chrome headless espera que esté presente, y los paquetes de fuentes que afectan el renderizado de texto.
Sin una configuración adecuada, encontrarás errores que van desde los obvios ("cannot open display") hasta los sutiles (segfaults durante el renderizado WebGL, salida de Canvas en blanco o familias de fuentes faltantes en las verificaciones de huella digital). Cada uno de estos problemas puede degradar silenciosamente tu protección de huella digital sin ningún mensaje de error claro.
La variable de entorno DISPLAY es particularmente importante. Incluso al ejecutar Chrome en modo headless, Chrome aún inicializa algunos subsistemas relacionados con la pantalla. En Ubuntu, se debe establecer DISPLAY=:10.0 y Xvfb debe estar ejecutándose en esa pantalla. Omitir este paso conduce a fallos o renderizado degradado que afecta la consistencia de la huella digital.
Contexto técnico
Xvfb (X Virtual Frame Buffer)
Xvfb proporciona un servidor de pantalla virtual que implementa el protocolo X11 sin requerir hardware de pantalla físico. Chrome se conecta a Xvfb como si fuera una pantalla real, completando su inicialización de renderizado correctamente.
Parámetros clave de configuración:
- Número de pantalla (
:10): Un identificador arbitrario. Usar:10evita conflictos con:0que puede ser usado por instalaciones de escritorio. - Especificación de pantalla (
1920x1080x24): Ancho, alto y profundidad de color. Se requiere una profundidad de color de 24 bits para un renderizado preciso. Profundidades menores causan bandas de color en capturas de pantalla y salida de Canvas incorrecta. - Variable de entorno DISPLAY (
DISPLAY=:10.0): Debe establecerse para cada proceso que lance Chrome, incluyendo scripts Node.js y scripts de shell.
Dependencias del sistema de Chrome
Chrome depende de docenas de bibliotecas compartidas para renderizado, audio, red y accesibilidad. En una instalación de escritorio de Ubuntu, la mayoría de estas están presentes. En una instalación de servidor, necesitas instalarlas explícitamente.
Las categorías críticas son:
- Gráficos:
libdrm2,libgbm1,libxcomposite1,libxdamage1,libxrandr2para composición de pantalla - Toolkit de UI:
libgtk-3-0,libatk-bridge2.0-0,libatk1.0-0para accesibilidad y renderizado de widgets - Seguridad:
libnss3,libnspr4para TLS y manejo de certificados - Audio:
libasound2para inicialización del subsistema de audio (incluso cuando no se reproduce audio) - Fuentes:
fonts-liberationpara disponibilidad básica de fuentes - Integración de escritorio:
xdg-utilspara manejo de tipos MIME
<svg viewBox="0 0 700 300" xmlns="http://www.w3.org/2000/svg" style={{maxWidth: '100%', height: 'auto'}}>
Enfoques comunes y limitaciones
Ejecutar sin Xvfb
Algunas guías sugieren ejecutar Chrome headless sin Xvfb. Aunque el flag --headless de Chrome no requiere estrictamente una pantalla X para la carga básica de páginas, ciertas operaciones de renderizado, rutas de inicialización de GPU y rutinas de enumeración de fuentes se comportan de manera diferente sin un servidor de pantalla. El resultado es un renderizado inconsistente que afecta la estabilidad de la huella digital.
Los perfiles de BotBrowser definen propiedades de pantalla específicas. Sin Xvfb, el navegador puede recurrir a rutas de renderizado por software que producen una salida de Canvas y WebGL diferente a la que especifica el perfil. Siempre ejecuta Xvfb.
Paquetes de fuentes faltantes
Ubuntu Server viene con soporte mínimo de fuentes. Chrome puede renderizar texto sin fuentes adicionales, pero la lista de fuentes disponibles y las métricas de renderizado no coincidirán con lo que tendría un usuario de escritorio real. Esto crea una inconsistencia en la huella digital. El motor de fuentes multiplataforma de BotBrowser mitiga esto al integrar fuentes del perfil, pero tener fuentes del sistema disponibles como respaldo mejora la consistencia del renderizado.
Profundidad de pantalla incorrecta
Usar Xvfb :10 -screen 0 1920x1080x16 (color de 16 bits) en lugar de 24 bits causa problemas de profundidad de color. El renderizado de Canvas usa menos canales de color, produciendo datos de píxeles diferentes y hashes de huella digital diferentes. Siempre usa profundidad de 24 bits.
Ejecutar como root sin flags de sandbox
El sandbox de Chrome requiere capacidades específicas del kernel. En contenedores Docker o al ejecutar como root, el sandbox falla silenciosamente o se bloquea. Usa --disable-setuid-sandbox en estos entornos.
El enfoque de BotBrowser
BotBrowser está diseñado para despliegues en servidores headless. Su sistema de perfiles multiplataforma asegura que un perfil de Windows cargado en un servidor Linux produce la misma huella digital que en una máquina Windows real. El motor de fuentes integrado renderiza texto usando los datos de fuentes del perfil independientemente de las fuentes instaladas en el servidor. Los valores de huella digital de GPU provienen del perfil, no de la GPU real del servidor.
Esto significa que el hardware del servidor no se filtra en la huella digital. Un VPS en la nube de $5 y un servidor dedicado de $500 producen una salida idéntica cuando usan el mismo perfil.
Sin embargo, el servidor aún debe proporcionar la infraestructura de renderizado que Chrome espera. BotBrowser no puede inicializarse correctamente sin las bibliotecas del sistema listadas arriba y un servidor de pantalla en ejecución.
Configuración y uso
Paso 1: Instalar dependencias del sistema
sudo apt-get update && sudo apt-get install -y \
wget ca-certificates fonts-liberation \
libasound2 libatk-bridge2.0-0 libatk1.0-0 \
libcups2 libdbus-1-3 libdrm2 libgbm1 \
libgtk-3-0 libnspr4 libnss3 \
libxcomposite1 libxdamage1 libxrandr2 \
xdg-utils xvfb
Para Ubuntu 24.04, algunos nombres de paquetes han cambiado. Si encuentras errores, ejecuta:
sudo apt-get install -y \
libasound2t64 libatk-bridge2.0-0 libatk1.0-0 \
libcups2t64 libgbm1 libgtk-3-0t64 \
libnss3 libxcomposite1 libxdamage1 \
libxrandr2 xvfb fonts-liberation xdg-utils
Paso 2: Iniciar Xvfb
Para pruebas inmediatas:
Xvfb :10 -screen 0 1920x1080x24 &
export DISPLAY=:10.0
Para producción, crea un servicio systemd:
# /etc/systemd/system/xvfb.service
[Unit]
Description=X Virtual Frame Buffer
After=network.target
[Service]
Type=simple
ExecStart=/usr/bin/Xvfb :10 -screen 0 1920x1080x24
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Habilita e inicia el servicio:
sudo systemctl daemon-reload
sudo systemctl enable xvfb
sudo systemctl start xvfb
Paso 3: Instalar BotBrowser
# Descargar la última versión
wget -O botbrowser.tar.gz \
https://github.com/botswin/BotBrowser/releases/latest/
# Extraer en /opt
sudo mkdir -p /opt/botbrowser
sudo tar -xzf botbrowser.tar.gz -C /opt/botbrowser/
sudo chmod +x /opt/botbrowser/chrome
# Verificar la instalación
DISPLAY=:10.0 /opt/botbrowser/chrome --version
Paso 4: Descargar perfiles
sudo mkdir -p /opt/profiles
git clone https://github.com/botswin/BotBrowser.git /opt/profiles
Paso 5: Prueba de lanzamiento
DISPLAY=:10.0 /opt/botbrowser/chrome \
--bot-profile="/opt/profiles/windows-chrome-131.enc" \
--headless \
--remote-debugging-port=9222 &
Verifica que el navegador esté en ejecución:
curl -s http://localhost:9222/json/version | python3 -m json.tool
Paso 6: Integración con Playwright
npm install playwright-core
const { chromium } = require('playwright-core');
(async () => {
const browser = await chromium.launch({
executablePath: '/opt/botbrowser/chrome',
args: [
'--disable-setuid-sandbox',
'--bot-profile=/opt/profiles/windows-chrome-131.enc',
'--proxy-server=socks5://user:pass@proxy.example.com:1080',
],
headless: true,
});
const context = await browser.newContext();
const page = await context.newPage();
await page.goto('https://example.com');
console.log('Title:', await page.title());
await browser.close();
})();
Ejecuta con la variable de pantalla:
DISPLAY=:10.0 node script.js
Paso 7: Servicio systemd para automatización
Para workers de automatización persistentes:
# /etc/systemd/system/botbrowser-worker.service
[Unit]
Description=BotBrowser Automation Worker
After=xvfb.service
Requires=xvfb.service
[Service]
Type=simple
Environment=DISPLAY=:10.0
WorkingDirectory=/opt/scripts
ExecStart=/usr/bin/node /opt/scripts/worker.js
Restart=always
RestartSec=10
User=botbrowser
Group=botbrowser
[Install]
WantedBy=multi-user.target
Múltiples instancias
Cada instancia concurrente necesita su propio --user-data-dir:
for i in $(seq 1 5); do
DISPLAY=:10.0 /opt/botbrowser/chrome \
--bot-profile="/opt/profiles/profile-${i}.enc" \
--user-data-dir="/tmp/bb-session-${i}" \
--remote-debugging-port=$((9222 + i)) \
--headless &
done
Gestión de procesos con PM2
npm install -g pm2
DISPLAY=:10.0 pm2 start worker.js --name "bb-worker-1" \
-- --profile="/opt/profiles/profile-1.enc"
DISPLAY=:10.0 pm2 start worker.js --name "bb-worker-2" \
-- --profile="/opt/profiles/profile-2.enc"
pm2 save
pm2 startup # Generar auto-inicio con systemd
Verificación
Después de completar la configuración, verifica que todo funcione:
# Verificar que Xvfb esté en ejecución
systemctl status xvfb
# Verificar que la pantalla sea accesible
DISPLAY=:10.0 xdpyinfo | head -5
# Verificar que las dependencias de Chrome estén satisfechas
ldd /opt/botbrowser/chrome | grep "not found"
# Lanzar y verificar huella digital
DISPLAY=:10.0 node -e "
const { chromium } = require('playwright-core');
(async () => {
const b = await chromium.launch({
executablePath: '/opt/botbrowser/chrome',
args: ['--bot-profile=/opt/profiles/profile.enc'],
headless: true,
});
const p = await (await b.newContext()).newPage();
const ua = await p.evaluate(() => navigator.userAgent);
console.log('User-Agent:', ua);
const wd = await p.evaluate(() => navigator.webdriver);
console.log('webdriver:', wd);
await b.close();
})();
"
El valor de webdriver debería ser false, y el User-Agent debería coincidir con el perfil cargado.
Mejores prácticas
Siempre establece DISPLAY=:10.0. Agrégalo a /etc/environment o a tus archivos de servicio para que nunca se olvide. Incluso Chrome headless lo necesita en Linux.
Usa profundidad de color de 24 bits para Xvfb. Profundidades menores producen salida de renderizado incorrecta.
Monitorea el uso de disco. Chrome escribe volcados de fallos y datos de caché en --user-data-dir. Configura la rotación de logs o limpieza periódica para prevenir el agotamiento del disco.
Mantén las dependencias actualizadas. Ejecuta apt-get upgrade periódicamente. Los desajustes en versiones de bibliotecas pueden causar problemas sutiles de renderizado.
Establece límites de recursos. Usa MemoryLimit y CPUQuota de systemd para prevenir que instancias descontroladas consuman todos los recursos del servidor.
Preguntas frecuentes
¿Funciona BotBrowser en Ubuntu 24.04?
Sí. Algunos nombres de paquetes han cambiado (por ejemplo, libasound2 se convirtió en libasound2t64). El comando de instalación alternativo en el Paso 1 cubre estos cambios.
¿Puedo usar una resolución de Xvfb más alta?
Sí. Puedes configurar Xvfb :10 -screen 0 2560x1440x24 o cualquier resolución que necesites. Haz que coincida con la resolución de pantalla del perfil para mejores resultados.
¿Necesito una GPU en el servidor?
No. BotBrowser usa los valores de GPU del perfil para el reporte de huella digital. La GPU real del servidor (o su ausencia) no afecta la salida de la huella digital.
¿Por qué no simplemente usar --headless=new sin Xvfb?
El nuevo modo headless de Chrome aún inicializa subsistemas de pantalla. Sin Xvfb, algunas rutas de renderizado recurren al modo solo software, lo que puede producir una salida de Canvas y WebGL diferente. Para resultados de huella digital consistentes, siempre ejecuta Xvfb.
¿Cuántas instancias puedo ejecutar por servidor?
Depende de los recursos del servidor. Cada instancia de Chrome usa 200-500 MB de RAM. Un servidor con 16 GB de RAM puede ejecutar cómodamente 20-30 instancias con espacio para el sistema operativo y servicios de soporte. Monitorea el uso de memoria y reduce la concurrencia si ves actividad de swap.
¿Cómo verifico las bibliotecas faltantes?
Ejecuta ldd /opt/botbrowser/chrome | grep "not found". Cualquier biblioteca listada como "not found" necesita ser instalada. Usa apt-file search libname.so para encontrar el paquete que proporciona una biblioteca específica.
¿Puedo ejecutar BotBrowser en servidores Ubuntu basados en ARM?
BotBrowser proporciona builds de Linux para x86_64. El soporte para ARM depende de la versión específica. Consulta la página de publicaciones de GitHub para las arquitecturas disponibles.
¿Cómo actualizo BotBrowser?
Descarga la última versión y extráela sobre la instalación existente. No se necesitan cambios de configuración. Actualiza los perfiles desde el repositorio de perfiles de BotBrowser al mismo tiempo para coincidir con la nueva versión del navegador.
Resumen
Configurar BotBrowser en un servidor Ubuntu headless requiere la instalación de dependencias del sistema, la configuración de Xvfb y la gestión adecuada de variables de entorno. Una vez configurado, el servidor proporciona una base estable para ejecutar cualquier número de instancias de BotBrowser con protección de huella digital consistente.
Para despliegues en contenedores, consulta la Guía de despliegue con Docker. Para ajuste de rendimiento a escala, consulta Optimizar el rendimiento de BotBrowser en producción. Para combinaciones de flags CLI, consulta Recetas CLI.
Artículos Relacionados
Lleva BotBrowser de la investigación a producción
Usa estas guías para entender el modelo y después avanzar hacia validación multiplataforma, contextos aislados y despliegue de navegador preparado para escalar.