Toda la documentación

Empezar

  1. 01Primeros pasos
  2. 02Instalación
  3. 03Seguimiento

Funciones

  1. 04El panel
  2. 05Objetivos
  3. 06Enlaces cortos
  4. 07Fuentes y agentes de IA
  5. 08Informes por email
  6. 09Comprobación programada
  7. 10Pregunta a tu IA

Referencia

  1. 11Configuración
  2. 12API HTTP

Plataformas

  1. 13Servidor independiente
  2. 14PHP
  3. 15WordPress
  4. 16Drupal
  5. 17Craft CMS
  6. 18Python
  7. 19Rails
  8. 20Ruby
  9. 21Go
  10. 22Java
  11. 23.NET
  12. 24Elixir
  13. 25Rust

Confianza

  1. 26Privacidad

Plataformas

Servidor independiente

El servidor independiente ejecuta Runlight como una aplicación propia para cualquier número de sitios, con inicio de sesión, enlaces cortos en tus propios dominios e informes por email.

El servidor independiente es Runlight empaquetado como una aplicación propia. Encaja con un sitio cuya aplicación no puede ejecutar Runlight, y reúne varios sitios en un solo panel. Ejecuta el mismo código que la biblioteca, así que los informes, los objetivos, los enlaces cortos y los informes por email funcionan igual.

Esta página trata del servidor de Node. Python, Ruby, Go, Java y .NET tienen cada uno su propio servidor, que funciona de la misma manera, y en un hosting que ejecuta PHP sin Node, el drop-in de PHP hace el mismo trabajo.

Ponlo en marcha

Con Docker, ejecuta esto.

bash

docker run -d --name runlight -p 3000:3000 -v runlight:/data ghcr.io/runlightsh/runlight

Cuando un proxy en la misma máquina añade HTTPS, como en Publícalo en internet, publica el puerto solo en la dirección de loopback, con -p 127.0.0.1:3000:3000. Docker abre un puerto publicado saltándose cortafuegos como ufw, y un cliente que llega directamente al puerto sin cifrar puede indicar cualquier host y enviar una dirección reenviada falsa.

Con Node 22 o posterior, ejecuta esto en su lugar.

bash

npx runlight.sh

El servidor escucha en el puerto 3000. Guarda sus datos en una carpeta llamada runlight-data dentro del directorio desde el que lo arrancas, o en /data dentro de Docker.

Crea tu cuenta

En su primer arranque, el servidor escribe en su log un enlace de configuración con un código de un solo uso. Abre ese enlace e introduce tu dirección de correo y una contraseña de al menos diez caracteres, escrita dos veces para que un despiste al teclear no te deje fuera. El enlace solo funciona mientras el servidor no tiene ninguna cuenta, así que nadie que encuentre antes un servidor nuevo puede quedárselo.

En Docker, el log es donde tienes que mirar.

bash

docker logs runlight

El enlace empieza por http://localhost:3000. Cuando el servidor se ejecuta en otra máquina, conserva todo a partir de /setup y pon delante la dirección del propio servidor, como https://stats.example.com/setup?code=.... Cada arranque genera un código nuevo, así que después de reiniciar usa el enlace de las últimas líneas del log.

Quien configura el servidor es su propietario. El propietario y los administradores invitan a otras personas en Ajustes, Personas, como administrador, miembro o lector.

Rol Qué puede hacer
Propietario Todo. Nadie más puede cambiar el rol del propietario ni quitarlo.
Administrador Todo lo que puede el propietario, incluida la gestión de personas, salvo cambiar o quitar al propietario.
Miembro Cambiar los ajustes de cualquier sitio, como objetivos, embudos, enlaces cortos, dominios de enlaces, enlaces para compartir, informes por email e importaciones, y crear tokens de API. Los miembros no pueden gestionar personas, configurar el servicio de correo ni el asistente, ni eliminar un sitio.
Lector Ver las estadísticas de cualquier sitio sin cambiar nada.

El propietario puede ceder la propiedad a un administrador con Hacer propietario en Ajustes, Personas, después de introducir su contraseña, y pasa a ser administrador. La invitación sale por correo cuando el servidor tiene un servicio de correo (configurado en Ajustes, Servicio de correo), y el panel siempre muestra también el enlace, para que puedas enviarlo de otra forma. La persona lo abre, elige una contraseña y queda con la sesión iniciada. Un enlace funciona una vez, durante siete días, y Enviar de nuevo crea uno nuevo. Cualquiera puede cambiar su contraseña más adelante en Cuenta, al pie del panel. Un servidor anterior a estos roles mantiene a su primer propietario como propietario, y los demás propietarios pasan a ser administradores. Quitar a alguien, o convertirlo en lector, también borra los tokens de API que creó y las aplicaciones que conectó, como Claude o un hub. Los tokens creados con RUNLIGHT_TOKEN, o antes de esta versión, no tienen creador registrado, así que después de quitar a alguien revisa Ajustes, API e IA por si queda alguno de esos.

Inicio de sesión en dos pasos

Cualquiera puede activar el inicio de sesión en dos pasos en Cuenta, al pie del panel. Confirma tu contraseña, escanea el código QR con una app de autenticación como 1Password, Google Authenticator o Authy, e introduce el código que muestra. A partir de ahí, al iniciar sesión se pide un código nuevo después de la contraseña. También recibes diez códigos de recuperación, que se muestran una sola vez, y cada uno te deja entrar una vez si ya no tienes el teléfono. El propietario o un administrador puede restablecer los dos pasos de otra persona en Ajustes, Personas, después de introducir su propia contraseña, aunque solo el propietario puede cambiar los del propietario. Activar o desactivar los dos pasos cierra tu sesión en todos los demás navegadores, y el que estás usando sigue con la sesión iniciada.

Límites de inicio de sesión

Una dirección tiene diez contraseñas incorrectas para una cuenta cada quince minutos, y la cuenta tiene cincuenta desde cualquier lugar. Cada intento se cuenta en cuanto llega, así que una ráfaga de intentos enviados a la vez no llega más lejos. Cuando la cuenta está en su límite, un navegador que ya haya iniciado sesión en ella antes sigue entrando, y cualquier otro intento recibe la misma respuesta tanto si la contraseña era correcta como si no. Con el inicio de sesión en dos pasos activado, esa respuesta es el paso del código, por el que solo pasa el ticket de una contraseña correcta, así que puedes seguir entrando desde un navegador nuevo. Sin él, una contraseña correcta te envía por correo un enlace para iniciar sesión cuando el servidor tiene un servicio de correo, y si no, la cuenta espera quince minutos. El enlace funciona una vez, durante quince minutos, y al usarlo se anula cualquier enlace enviado antes. El paso del código permite cinco códigos incorrectos cada quince minutos, y confirmar una configuración nueva de dos pasos permite cinco antes de tener que empezar de nuevo. Los recuentos se guardan en memoria, con las direcciones IP y de correo guardadas como hash con una clave que se genera en cada arranque.

Contraseñas olvidadas

Si alguien se queda fuera, ejecuta el comando password en el servidor para darle a la cuenta una contraseña nueva, que el comando muestra. También desactiva el inicio de sesión en dos pasos de esa cuenta, ya que quien está en el servidor es quien dice ser. El mismo comando crea una cuenta nueva, que es la del propietario en un servidor que aún no tiene a nadie y la de un administrador en los demás casos.

bash

npx runlight.sh password someone@example.com

En Docker, ejecuta el mismo comando dentro del contenedor.

bash

docker exec runlight node node_modules/runlight.sh/dist/cli.js password someone@example.com

Añade tus sitios

Después de iniciar sesión, el panel te pide el dominio de tu primer sitio. La siguiente pantalla te da la etiqueta de script para las páginas de ese sitio, con la dirección del servidor y el id del sitio ya puestos.

html

<script defer src="https://stats.example.com/s.js?site=example.com" data-site="example.com"></script>

Añade más sitios desde el menú junto al nombre del sitio. En Ajustes, General, puedes cambiar los dominios, el nombre y la zona horaria de un sitio, o eliminar el sitio junto con todo lo registrado para él.

Conecta sitios que se cuentan solos

Un sitio con Runlight dentro de su propia aplicación también puede unirse a este servidor, para que todos los sitios estén en un solo panel. Elige Añadir un sitio, Conectar otro Runlight, e introduce la dirección de Runlight de la aplicación, como https://example.com/runlight. Tu navegador abre el Runlight de esa aplicación, donde inicias sesión si hace falta, eliges el sitio y pulsas Allow. Vuelves aquí con el sitio ya añadido.

Las cifras del sitio se quedan en la base de datos de la propia aplicación. Este servidor las lee a través de la API de la aplicación cada vez que miras, así que siempre están al día. Sus objetivos, embudos, enlaces cortos, dominios de enlaces, informes por email, enlaces para compartir y el tiempo que conserva las visitas se pueden cambiar desde aquí, y cada cambio se guarda en la aplicación. Las personas, los tokens, las importaciones y el servicio de correo de la aplicación se quedan en la aplicación. Todos los sitios, en el menú de sitios, pone todos los sitios uno al lado del otro para las fechas que elijas.

La aplicación guarda el permiso como un token en sus Ajustes, API e IA, limitado a ese sitio. Si lo borras allí, este servidor se desconecta al momento. Un sitio conectado con un token de solo lectura antes de que existiera esto muestra Permitir cambios en sus ajustes, que sigue los mismos pasos. Si la aplicación borra ese token, Conectar de nuevo en los ajustes del sitio crea uno nuevo, y desconectar un sitio aquí borra su token allí.

Si la aplicación ejecuta un Runlight más antiguo que este, conéctala con un token. Crea uno en Ajustes, API e IA de la aplicación y elige Usar un token de API al conectar. Un token de lectura muestra aquí las cifras del sitio, y sus ajustes se quedan en la aplicación.

Publícalo en internet

El servidor habla HTTP sin cifrar, así que ejecútalo detrás de un proxy que añada HTTPS. Con Caddy, toda la configuración para un servidor en stats.example.com es esta.

Caddyfile

stats.example.com {
  reverse_proxy localhost:3000
}

Define RUNLIGHT_URL con la dirección pública del servidor, como https://stats.example.com. Así los enlaces cortos nunca pueden quedarse con ese nombre, y los correos de invitación y de informes enlazan a ella sea cual sea la cabecera Host de la petición. Un hub conectado solo añade dominios de enlaces e informes por email cuando está definida.

Runlight lee la dirección de cada visitante de la última entrada de X-Forwarded-For, la que añade tu proxy. Define TRUST_PROXY como x-real-ip o cf-connecting-ip cuando la dirección venga en esa cabecera, por ejemplo detrás de Cloudflare y otro proxy. Define TRUST_PROXY=false cuando no haya nada delante del servidor, para que un visitante no pueda enviar una dirección falsa.

Cualquier dominio que apunte al servidor puede servir enlaces cortos en su raíz, sin instalar nada más. Apunta el dominio al servidor con un registro CNAME, haz que tu proxy lo acepte con HTTPS y luego añádelo en Ajustes, Dominios personalizados. En Caddy, eso significa poner el dominio junto al del propio servidor.

Caddyfile

stats.example.com, go.example.com {
  reverse_proxy localhost:3000
}

Cada enlace responde también en /go/your-slug en el dominio del propio servidor. Las páginas del propio servidor, como /login y todo lo que hay bajo /api, responden como el servidor también en un dominio de enlaces, así que un enlace con uno de esos slugs solo funciona en /go/. Un dominio de enlaces nunca puede ser la dirección pública del servidor ni un nombre desde el que el propietario o un administrador haya iniciado sesión, y si alguno se añadió así antes, iniciar sesión en /login sigue abriendo el panel para que puedas quitarlo. El servidor recuerda los primeros 20 nombres desde los que inician sesión, así que define RUNLIGHT_URL si responde en más.

Ubicaciones

Detrás de Cloudflare, Runlight toma el país, la región y la ciudad de cada visitante de las cabeceras que añade Cloudflare. Sin ellas, el servidor descarga la base de datos gratuita de ciudades de DB-IP en su carpeta de datos en el primer arranque y obtiene la nueva versión de cada mes. El archivo ocupa unos 130 MB y el servidor lo mantiene en memoria. La licencia de DB-IP pide que se le atribuya, así que el pie del panel la menciona.

Define RUNLIGHT_GEO=country para usar la base de datos de países de DB-IP, más pequeña, que ocupa unos 8 MB y no tiene regiones ni ciudades. Defínela como off para no consultar nada, o como la ruta de un archivo MMDB propio, como GeoLite2 City de MaxMind.

Ajustes

El servidor lee sus ajustes de variables de entorno.

Variable Qué hace
PORT El puerto en el que escucha. Por defecto, 3000.
HOST La dirección en la que escucha. Por defecto, 0.0.0.0.
DATA_DIR La carpeta para el archivo SQLite, el secreto y los datos de ubicación. Por defecto, ./runlight-data, o /data en Docker.
DATABASE_URL Una dirección postgres:// guarda los datos en Postgres en lugar de SQLite, y una dirección mysql:// o mariadb:// los guarda en MySQL o MariaDB.
RUNLIGHT_SECRET La clave que firma los inicios de sesión y cifra las claves guardadas, del correo, del Asistente de IA, de las instalaciones conectadas y del inicio de sesión en dos pasos. Sin ella, el servidor crea una y la guarda en DATA_DIR.
RUNLIGHT_URL La dirección pública del servidor, como https://stats.example.com, que nunca puede convertirse en dominio de enlaces. Los correos de invitación y de informes enlazan a ella.
RUNLIGHT_TOKEN Un token que los scripts pueden enviar como bearer, además de los tokens de API creados en el panel.
RUNLIGHT_OBSERVE_KEY Una sola clave con la que un sitio de WordPress, Drupal o Craft puede informar de agentes de IA, para cualquier sitio. Cada sitio tiene además su propia clave de agentes, que aparece en Ajustes, Instalación y está limitada a ese sitio, y es la mejor opción.
TRUST_PROXY Defínela como false cuando no haya ningún proxy delante del servidor.
RUNLIGHT_GEO De dónde salen las ubicaciones cuando ninguna cabecera las da. Por defecto es city, y puede ser country, off o la ruta a un archivo MMDB.

Informes por email y la comprobación programada

El servidor ejecuta él mismo la comprobación programada de Runlight cada cinco minutos, así que no necesita cron. Configura un servicio de correo en Ajustes, Servicio de correo, añade quién recibe informes en Ajustes, Informes por email, y los informes salen solos.

Copias de seguridad y actualizaciones

Haz copia de seguridad de la carpeta de datos. Contiene el archivo SQLite y el archivo secret, y sin el secreto las claves guardadas no se pueden leer y todo el mundo tiene que volver a iniciar sesión. Esas claves son las del servicio de correo, las del Asistente de IA, los tokens de las instalaciones conectadas y los secretos de dos pasos de todo el mundo, así que el inicio de sesión en dos pasos también hay que volver a configurarlo. Para actualizar, descarga la imagen nueva o ejecuta npx runlight.sh@latest, y la base de datos se actualiza sola al arrancar.

Ejecutar más de una copia

Varias copias del servidor pueden compartir una misma base de datos Postgres, MySQL o MariaDB, por ejemplo detrás de un balanceador de carga. Cada copia vuelve a leer la lista de sitios y de instalaciones conectadas cada cinco minutos, así que uno añadido en cualquier copia aparece en las demás en menos de cinco minutos. Todo lo demás, desde las visitas hasta los objetivos y los enlaces, se comparte al instante.

Agentes de IA desde un log

Los agentes de IA como GPTBot y ClaudeBot acceden a las páginas sin ejecutar JavaScript, así que la etiqueta de script nunca los ve. En un sitio con Runlight dentro de la aplicación, o con un plugin de WordPress, Drupal o Craft, se cuentan donde se sirve la página. Para cualquier otro sitio que alojes tú, el log de acceso del servidor web los tiene, y el comando agents lo lee.

bash

npx runlight.sh agents --log /var/log/nginx/access.log --to https://stats.example.com --key rlo_... --site https://example.com --follow

La clave es la clave de agentes del sitio, que aparece en Runlight en Ajustes, Instalación, y solo puede informar de accesos a ese sitio. --site es la dirección del sitio, para logs en el formato habitual de nginx o Apache, que no incluyen el host. Los logs JSON de Caddy sí llevan el host, así que ahí no hace falta.

Con --follow, el comando sigue en marcha, envía los accesos a medida que ocurren y continúa cuando se rota el log, terminando el archivo antiguo antes de pasar al nuevo. Un servicio de systemd o un gestor de procesos lo mantiene en marcha. Añade --state ./agents.json para que un reinicio continúe donde se quedó. Sin --follow, lee el log una vez y se detiene, y con --state la siguiente ejecución empieza donde terminó la anterior, lo que encaja con cron. Solo una ejecución a la vez puede usar un archivo de estado. Mantiene un bloqueo junto al archivo (agents.json.lock), así que una segunda ejecución, como una tarea de cron que arranca mientras la anterior sigue enviando, se detiene con un mensaje y no envía nada dos veces. Un bloqueo que dejó una ejecución que falló se toma de nuevo.

Solo salen de la máquina los accesos correctos a páginas de agentes de IA conocidos, cada uno con la dirección de la página, el user agent del agente y cuándo se sirvió. Las direcciones de los visitantes y todo lo demás del log se quedan donde están.