Siempre fui escéptico con los clientes IRC web. Mis experiencias con Mibbit, KiwiIRC y la primera generación de webchat eran mediocres: lentos, sin persistencia, y con una UX que parecía diseñada para ahuyentar usuarios. Luego probé The Lounge y cambié de opinión.
The Lounge es un cliente IRC web autoalojado que funciona como un bouncer con interfaz. Lo instalas en tu servidor, creas cuentas de usuario, y cada usuario se conecta desde el navegador. La conexión IRC es persistente — cierras la pestaña, vuelves tres días después, y todo tu historial está ahí. Push notifications, soporte de múltiples redes, temas, file upload... es lo que los clientes IRC web deberían haber sido desde el principio.
Lo uso como punto de acceso complementario desde hace dos años. Mi setup principal sigue siendo WeeChat + tmux, pero cuando estoy en una máquina ajena o en el móvil, The Lounge es mi puerta de entrada a IRC.
¿Qué es The Lounge y por qué te interesa?
The Lounge es un fork de Shout, reescrito y mejorado sustancialmente. Está escrito en Node.js con una interfaz Vue.js. Sí, Node.js — y antes de que alguien arrugue la nariz, el rendimiento es perfectamente aceptable. He tenido instancias con 30 usuarios concurrentes en un VPS de 2 GB de RAM sin problemas.
Las razones técnicas para elegir The Lounge sobre otras opciones:
- Persistencia real — No es un webchat efímero. Tu sesión IRC vive en el servidor 24/7.
- Push notifications — Funciona como PWA. Instalas la webapp en tu móvil y recibes notificaciones de highlights.
- Multi-red — Conectas a tantas redes IRC como necesites desde una sola interfaz.
- File upload — Arrastras un archivo a la ventana de chat y se sube automáticamente. El link se comparte en el canal.
- Búsqueda en historial — Buscar en logs desde la interfaz. Funciona rápido incluso con meses de historial.
- SASL, TLS, certificados cliente — Soporte completo de autenticación moderna.
Instalación en Debian/Ubuntu
La instalación limpia en un Debian 12 o Ubuntu 22.04+:
# Instalar Node.js 20 LTS (requisito mínimo: Node 18)
curl -fsSL https://deb.nodesource.com/setup_20.x | sudo bash -
sudo apt-get install -y nodejs
# Verificar versiones
node --version # v20.x.x
npm --version # 10.x.x
# Instalar The Lounge globalmente
sudo npm install -g thelounge
# Verificar instalación
thelounge --version
# Crear usuario del sistema
sudo useradd --system --user-group --home-dir /var/opt/thelounge --create-home thelounge
# Inicializar configuración
sudo -u thelounge thelounge start --config /var/opt/thelounge
# Ctrl+C después de que arranque — solo queremos que genere la config
Ahora creamos el servicio systemd:
# /etc/systemd/system/thelounge.service
[Unit]
Description=The Lounge - IRC web client
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=thelounge
Group=thelounge
ExecStart=/usr/bin/thelounge start
Restart=on-failure
RestartSec=5
Environment=THELOUNGE_HOME=/var/opt/thelounge
# Hardening
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/var/opt/thelounge
NoNewPrivileges=true
PrivateTmp=true
[Install]
WantedBy=multi-user.target
# Activar y arrancar
sudo systemctl daemon-reload
sudo systemctl enable thelounge
sudo systemctl start thelounge
sudo systemctl status thelounge
sudo -u thelounge thelounge add mi_usuario para crear el usuario desde CLI.Configuración detallada
El archivo de configuración principal está en /var/opt/thelounge/config.js:
// /var/opt/thelounge/config.js
module.exports = {
// Modo privado: solo usuarios registrados pueden conectar
public: false,
// Puerto de escucha (detrás de reverse proxy, solo localhost)
host: "127.0.0.1",
port: 9000,
// Protocolo IRC por defecto
defaults: {
name: "Libera.Chat",
host: "irc.libera.chat",
port: 6697,
tls: true,
rejectUnauthorized: true,
nick: "mi_nick",
realname: "The Lounge User",
join: "#canal1,#canal2"
},
// Historial persistente
messageStorage: ["sqlite"],
// Subida de archivos
fileUpload: {
enable: true,
maxFileSize: 10240, // KB
baseUrl: null // usa la URL del servidor
},
// Prefetch de links (thumbnails)
prefetch: true,
prefetchStorage: true,
prefetchMaxImageSize: 2048,
// Tema por defecto
theme: "default",
// Logs
debug: {
ircFramework: false,
raw: false
}
};
Los puntos que siempre cambio del default:
public: false— Siempre. No quiero que cualquiera use mi instancia como bouncer gratuito.host: "127.0.0.1"— Solo escuchar en localhost. El acceso externo pasa por nginx.messageStorage: ["sqlite"]— Sin esto, pierdes el historial al reiniciar. SQLite funciona perfectamente para el volumen de datos de IRC.rejectUnauthorized: true— No aceptar certificados TLS inválidos. Nunca.
Reverse proxy con nginx
The Lounge usa WebSockets, así que nginx necesita configuración específica:
# /etc/nginx/sites-available/thelounge.conf
server {
listen 443 ssl http2;
server_name irc.tudominio.com;
ssl_certificate /etc/letsencrypt/live/irc.tudominio.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/irc.tudominio.com/privkey.pem;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers off;
# Headers de seguridad
add_header Strict-Transport-Security "max-age=63072000" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options DENY;
add_header Referrer-Policy strict-origin-when-cross-origin;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_http_version 1.1;
# WebSocket support
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Timeouts largos para WebSocket
proxy_read_timeout 1800s;
proxy_send_timeout 1800s;
}
}
server {
listen 80;
server_name irc.tudominio.com;
return 301 https://$host$request_uri;
}
# Activar y probar
sudo ln -s /etc/nginx/sites-available/thelounge.conf /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
proxy_read_timeout es fundamental. Si lo dejas en el valor por defecto de nginx (60s), la conexión WebSocket se cortará cada minuto y el cliente reconectará constantemente. 1800 segundos (30 minutos) es un valor razonable. The Lounge envía pings de keepalive, así que la conexión no se queda huérfana.Gestión de usuarios y LDAP
Los usuarios se gestionan desde la CLI:
# Crear usuario
sudo -u thelounge thelounge add nombre_usuario
# Te pedirá contraseña interactivamente
# Listar usuarios
sudo -u thelounge thelounge list
# Resetear contraseña
sudo -u thelounge thelounge reset nombre_usuario
# Eliminar usuario
sudo -u thelounge thelounge remove nombre_usuario
Para entornos corporativos o equipos, The Lounge soporta autenticación LDAP:
// En config.js, añadir:
ldap: {
enable: true,
url: "ldaps://ldap.tudominio.com:636",
primaryKey: "uid",
searchDN: {
rootDN: "cn=readonly,dc=tudominio,dc=com",
rootPassword: "password_readonly",
filter: "(objectClass=inetOrgPerson)",
base: "ou=users,dc=tudominio,dc=com",
scope: "sub"
}
}
Con LDAP activo, los usuarios se autentican contra tu directorio existente. No necesitas crear usuarios locales en The Lounge — se crean automáticamente en el primer login.
Personalización y temas
The Lounge soporta temas CSS personalizados. Los temas se instalan como paquetes npm:
# Instalar un tema de la comunidad
sudo -u thelounge thelounge install thelounge-theme-nord
# O instalar desde un directorio local
sudo -u thelounge thelounge install /path/to/custom-theme
# Los temas instalados aparecen en la configuración del usuario
# dentro de la interfaz web: Configuración → Apariencia → Tema
Si quieres crear tu propio tema, la estructura es sencilla:
# package.json del tema
{
"name": "thelounge-theme-mi-tema",
"version": "1.0.0",
"thelounge": {
"type": "theme"
},
"main": "theme.css"
}
# theme.css - ejemplo básico
:root {
--body-bg-color: #1a1b26;
--window-bg-color: #1a1b26;
--body-color: #c0caf5;
--link-color: #7aa2f7;
--unread-marker-color: #ff9e64;
--highlight-bg-color: rgba(255, 158, 100, 0.1);
--highlight-border-color: #ff9e64;
}
Llevar The Lounge a producción
Si planeas tener más de un puñado de usuarios, hay cosas que debes considerar:
Backups
La data de The Lounge vive en /var/opt/thelounge/. Ahí están los configs de usuario, las bases de datos SQLite con el historial, y los archivos subidos. Un backup diario de ese directorio te cubre.
# Backup simple con rsync
rsync -a /var/opt/thelounge/ /backups/thelounge/$(date +%Y%m%d)/
# O con un cron job
0 3 * * * rsync -a --delete /var/opt/thelounge/ /backups/thelounge/latest/ \
&& tar czf /backups/thelounge/thelounge-$(date +\%Y\%m\%d).tar.gz \
/backups/thelounge/latest/
Monitorización
The Lounge no expone métricas Prometheus nativamente, pero puedes monitorizar el proceso Node.js y el estado del servicio:
# Verificar que el proceso está vivo
systemctl is-active thelounge
# Memoria usada
ps aux | grep thelounge | grep -v grep | awk '{print $6/1024 " MB"}'
# Conexiones activas
ss -tnp | grep ':9000' | wc -l
Actualizaciones
# Actualizar The Lounge
sudo npm update -g thelounge
sudo systemctl restart thelounge
# Verificar
thelounge --version
sudo systemctl status thelounge
Limpieza de historial
Si no controlas el tamaño del historial SQLite, las bases de datos crecen indefinidamente. No hay limpieza automática integrada — tienes que hacerlo tú.
# Ver tamaño de las bases de datos por usuario
du -sh /var/opt/thelounge/users/*/
# Limpiar mensajes antiguos (más de 6 meses)
# ¡Haz backup antes!
for db in /var/opt/thelounge/users/*/logs/*.sqlite3; do
sqlite3 "$db" "DELETE FROM messages WHERE time < strftime('%s','now','-6 months') * 1000;"
sqlite3 "$db" "VACUUM;"
done
Preguntas frecuentes
¿The Lounge puede reemplazar a ZNC como bouncer?
Funcionalmente sí — mantiene la conexión IRC persistente y almacena historial. Pero no es un bouncer en el sentido tradicional: no puedes conectar irssi o WeeChat a The Lounge como harías con ZNC. Si tu único punto de acceso es el navegador, The Lounge es suficiente. Si alternas entre terminal y web, necesitas ZNC + The Lounge como cliente separado, o WeeChat con el relay protocol.
¿Cuántos usuarios soporta una instancia?
Depende de cuántos canales y redes tengan configurados. En mi experiencia, un VPS con 2 GB de RAM y 2 vCPU maneja 30-40 usuarios sin problemas. Cada usuario consume entre 30-60 MB de RAM dependiendo de cuántas redes tenga. El cuello de botella suele ser la I/O de disco cuando SQLite escribe historial masivo, no la CPU.
¿Funciona en dispositivos móviles?
Sí, y bien. La interfaz es responsive y funciona como PWA (Progressive Web App). En Android con Chrome, puedes "instalarla" en la pantalla de inicio y se comporta como una app nativa con push notifications. En iOS con Safari también funciona como PWA, aunque las notificaciones push en iOS tienen limitaciones conocidas de Apple.