SSD Nodes Learn 🎉 VPS desde $5.50/mes
Guías Matt ConnorPor Matt Connor · Actualizado 2026-08-16

Analítica web autoalojada para un VPS pequeño

Compare Plausible, Umami, Matomo, GoatCounter y GoAccess: RAM, base de datos, crecimiento del disco, proxy inverso y datos que bloquean los ad blockers.

¿Qué herramienta de analítica web autoalojada debería ejecutar en un VPS?

La analítica web autoalojada se divide en dos familias. Elegir la familia incorrecta puede costarle más que elegir el producto equivocado. Una familia ejecuta un script pequeño en el navegador del visitante y almacena los datos que ese script envía. La otra familia lee el registro de acceso que el servidor web ya genera. Todo lo demás, incluida la base de datos y la memoria que necesita, depende de esa elección.

La respuesta breve para un servidor pequeño es la siguiente. GoatCounter y Medama caben en 1 GB, porque cada uno consta de un proceso que usa un solo archivo. Umami añade un contenedor de Postgres y ofrece un panel que una persona sin conocimientos técnicos puede leer. Plausible Community Edition y Rybbit usan ClickHouse, así que debe prever 2 GB de RAM o más. Matomo es el producto completo y requiere un servidor dimensionado según el tráfico. GoAccess no añade nada a la página, porque lee un registro que ya existe.

Etiqueta de script o registro del servidor: qué puede ver cada uno

Una etiqueta de script mide los navegadores. La página se carga, el script se ejecuta y envía una petición al recopilador. Cualquier elemento que interrumpa esa cadena queda fuera de su visibilidad: JavaScript desactivado, una lista de filtros que bloquea la petición, una petición fallida al recopilador o un crawler que no ejecuta scripts.

Un analizador de registros mide peticiones. El servidor web escribe una línea por cada petición, tanto si instala algo como si no, por lo que los datos ya están en el disco. Ve todos los crawlers y todas las peticiones a archivos que no incluyen una etiqueta de script. No puede ver lo que ocurre dentro del navegador. Tampoco puede ver una página servida desde la caché del navegador o desde una CDN (red de distribución de contenido) situada delante de su servidor, porque esa petición nunca llegó al servidor.

Las dos cifras no coincidirán, y ninguna de las dos es incorrecta. Matomo puede hacer ambas cosas. Su documentación indica qué datos se pierden al importar registros frente a usar su tracker JavaScript: resolución de pantalla y títulos de página, eventos, seguimiento de contenido, mapas de calor, grabaciones de sesiones y análisis de formularios. Esa lista es el coste de contar peticiones en lugar de navegadores.

El tráfico de bots explica la otra parte de la diferencia. Los recuentos basados en registros incluyen crawlers si no los filtra. En un sitio normal, la proporción de crawlers es suficiente para cambiar sus conclusiones. GoAccess y la importación de registros de Matomo filtran los bots conocidos. Ninguno puede filtrar un crawler que falsifica su user agent. Por eso conviene combinar cualquier recuento basado en registros con bloquear crawlers de IA en el servidor y leer el registro después del bloqueo, no antes.

GoAccess: analítica a partir del registro existente

Instálelo desde el repositorio propio del proyecto para Debian y Ubuntu, porque los paquetes de la distribución suelen quedar atrás respecto a las versiones publicadas.

wget -O - https://deb.goaccess.io/gnugpg.key | gpg --dearmor | sudo tee /usr/share/keyrings/goaccess.gpg >/dev/null
echo "deb [signed-by=/usr/share/keyrings/goaccess.gpg arch=$(dpkg --print-architecture)] https://deb.goaccess.io/ $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/goaccess.list
sudo apt-get update
sudo apt-get install goaccess

Después, indíquele el registro y escriba un informe estático.

goaccess /var/log/nginx/access.log -o ~/report.html --log-format=COMBINED

Ese comando falla con Permission denied para un usuario normal, porque en Ubuntu el registro de nginx pertenece a root y al grupo adm. Añádase a ese grupo con sudo usermod -aG adm $USER y, después, cierre la sesión y vuelva a iniciarla, porque la pertenencia a los grupos se carga al iniciar sesión. Ejecute id y compruebe que adm aparece en la lista antes de volver a intentarlo.

Un informe sobre el registro activo sólo incluye las entradas que logrotate todavía no ha movido. Las peticiones de ayer están en access.log.1 y las más antiguas están comprimidas, por lo que una vista semanal también debe leer los archivos rotados.

zcat /var/log/nginx/access.log.*.gz | goaccess - --log-format=COMBINED -o ~/last-week.html

También existe un modo en tiempo real, --real-time-html, que actualiza la página mediante un WebSocket. Requiere un segundo puerto y su propia regla del proxy. Para la mayoría de los sitios, basta con que cron escriba un informe cada hora, y hay menos elementos que proteger.

GoatCounter: un binario de Go y un archivo SQLite

GoatCounter se distribuye como un binario compilado estáticamente, por lo que no es necesario instalar ningún entorno de ejecución. Descargue una compilación desde la página de versiones y ejecútela, o use la imagen.

docker run -p 8080:8080 -v goatcounter-data:/home/goatcounter/goatcounter-data arp242/goatcounter

Cuando se ejecuta como binario, goatcounter serve escucha en el puerto 8080 y crea la base de datos SQLite en ./goatcounter-data/db.sqlite3. Cree el primer sitio desde la línea de comandos en lugar de usar el asistente web cuando la instancia ya esté detrás de un proxy.

goatcounter db create site -vhost=stats.example.com -user.email=me@example.com

Puede gestionar su propio certificado con goatcounter serve -listen=:443 -tls=tls,rdr,acme mediante ACME (entorno de gestión automática de certificados), lo que resulta útil en un servidor que no ejecuta ningún otro servicio. Si nginx o Caddy ya administra el puerto 443, mantenga GoatCounter en el puerto 8080 y configure un proxy hacia él. El script de seguimiento ocupa alrededor de 3.5K según la cifra del propio proyecto, y también hay un píxel de seguimiento para las páginas que no contienen JavaScript. Si SQLite se convierte en el límite de un sitio con mucha actividad, el mismo binario admite Postgres con goatcounter serve -db 'postgresql+dbname=goatcounter'. Las copias de seguridad consisten en copiar un archivo. Ese es el argumento principal para este tipo de herramienta.

Medama: un solo contenedor que declara usar 256 MB

Medama es la opción más reciente de binario único de esta lista. Está diseñado para no usar cookies y el proyecto declara un tracker de menos de 1 KB, además de sitios pequeños ejecutándose en máquinas virtuales con 256 MB de memoria. Esas son las cifras publicadas por el proyecto, no valores medidos para esta guía.

docker volume create medama-data
docker run -d -p 127.0.0.1:8080:8080 -v medama-data:/app/data ghcr.io/medama-io/medama:latest

El comando oficial publica el puerto como 8080:8080. El prefijo de loopback anterior es intencionado y la sección sobre el reverse proxy explica el motivo. El primer inicio de sesión es admin con la contraseña CHANGE_ME_ON_FIRST_LOGIN, y el nombre de esa contraseña es la instrucción.

Hay un modo de fallo documentado que puede afectar a la configuración. El inicio de sesión sólo funciona mediante HTTPS o en localhost. Por tanto, si configura el proxy antes que el certificado, el formulario rechaza una contraseña correcta y no muestra el motivo. Complete primero la configuración de TLS (seguridad de la capa de transporte) y después inicie sesión.

Umami: Postgres y un panel conocido

git clone https://github.com/umami-software/umami.git
cd umami
docker compose up -d

Esto inicia la aplicación en el puerto 3000 junto con un contenedor de PostgreSQL. La documentación indica PostgreSQL v12.14 como versión mínima y Node.js 18.18 o posterior si se compila desde el código fuente. Hay una imagen precompilada, docker.umami.is/umami-software/umami:postgresql-latest, que necesita que DATABASE_URL apunte a una base de datos que ya esté en ejecución.

El primer inicio de sesión es admin con la contraseña umami. Cámbiela antes de apuntar el DNS al servidor, porque la instancia queda accesible desde Internet en cuanto el registro resuelve y el proxy responde. Para consultar los detalles de Compose, los archivos de entorno y la política de reinicio, consulte una pila de Docker Compose en un VPS en lugar de copiar una pila que no haya revisado.

La instalación consta de un proceso de Node y Postgres. Consume más recursos que un binario único y muchos menos que cualquier sistema que ejecute ClickHouse.

Plausible Community Edition: ClickHouse establece el mínimo de RAM

git clone -b v3.2.1 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
touch .env
echo "BASE_URL=https://stats.example.com" >> .env
echo "SECRET_KEY_BASE=$(openssl rand -base64 48)" >> .env
docker compose up -d

La versión v3.2.1 es la actual en agosto de 2026, y el comando de clonación la fija de forma intencionada. La pila tiene tres partes: la aplicación, Postgres para las cuentas y la configuración, y ClickHouse para los datos de eventos. SECRET_KEY_BASE debe tener al menos 64 bytes, que es lo que genera la llamada openssl.

Los requisitos de Plausible indican que se necesitan al menos 2 GB de RAM para que ClickHouse y la aplicación no sean terminados por el asesino de procesos por falta de memoria, además de una CPU compatible con SSE 4.2 o NEON, que ClickHouse necesita. Conviene comprobar este segundo requisito antes de comprar, y es una diferencia práctica al elegir entre un VPS ARM y uno x86. ClickHouse también usará tanta memoria como considere disponible, así que, en un servidor compartido, establezca un límite como se describe en limitar la memoria de los contenedores en Compose.

BASE_URL debe coincidir exactamente con la URL pública. Si no coincide, el inicio de sesión se completa, la aplicación redirige al host incorrecto y la cookie de sesión se escribe para un dominio que no es el del navegador. Por eso se vuelve al formulario de inicio de sesión sin ningún mensaje de error.

El archivo compose incluido no publica ningún puerto, porque se espera que haya un proxy delante. Añada una anulación que publique el puerto de aplicación predeterminado sólo en loopback.

cat > compose.override.yml << EOF
services:
    plausible:
        ports:
            - 127.0.0.1:8000:8000
EOF

Matomo: el producto completo y el servidor que necesita

Matomo se ejecuta con PHP y MySQL o MariaDB. Por eso encaja en la pila web clásica, no en una pila de contenedores. También es la única herramienta de esta lista que publica requisitos de hardware según el volumen de tráfico.

ChartMatomo sizing guidance by monthly pageviews
The data behind this chart
[
  {
    "label": "100K/month",
    "cpu_cores": 2,
    "ram_gb": 2,
    "disk_gb": 50
  },
  {
    "label": "1M/month",
    "cpu_cores": 4,
    "ram_gb": 8,
    "disk_gb": 250
  },
  {
    "label": "10M/month",
    "cpu_cores": 8,
    "ram_gb": 16,
    "disk_gb": 400
  }
]

Esos son los requisitos mínimos publicados por Matomo en agosto de 2026. No son mediciones realizadas para esta guía. Hasta 100,000 visitas de página al mes, requiere 2 núcleos de CPU, 2 GB de RAM y 50 GB de SSD. Un solo servidor aloja la aplicación y la base de datos. En 1M/month, esto aumenta a 8 GB de RAM y 250 GB de almacenamiento. En 10M/month, Matomo recomienda dos servidores. La última fila muestra el servidor de base de datos: 16 GB de RAM y 400 GB de almacenamiento. Compare esas cifras de disco con las opciones basadas en un único binario, donde todo el conjunto de datos está en un archivo SQLite.

El archivado es lo que suele sorprender. De forma predeterminada, Matomo genera sus informes cuando alguien abre el panel. A medida que crecen los datos, el panel se vuelve más lento y finalmente agota el tiempo de espera. La solución documentada consiste en desactivar el archivado activado por el navegador en la configuración general y ejecutar el archivador mediante cron desde el directorio de Matomo, con el usuario propietario de los archivos de Matomo.

php console core:archive --url=https://analytics.example.com

Matomo también conserva tablas con registros sin procesar junto a las tablas de informes procesados. Puede eliminar los datos sin procesar antiguos y los informes antiguos según una programación. Active esta función durante la instalación, no cuando el disco ya esté lleno. Matomo también puede importar registros de acceso del servidor. Por eso es el único producto de esta lista que cubre ambas familias a la vez.

Rybbit y las pilas más recientes

git clone https://github.com/rybbit-io/rybbit.git
cd rybbit
chmod +x *.sh
./setup.sh your.domain.name

Rybbit es una incorporación reciente con un panel moderno. El script de instalación escribe el archivo de entorno y levanta la pila con Docker Compose. Ejecuta ClickHouse e incluye Caddy como servidor web propio. Caddy ocupa el puerto 443 y solicita un certificado para el dominio que se haya indicado. Si nginx ya utiliza el puerto 443 en el servidor, el script no podrá enlazarse a ese puerto. En ese caso, use el procedimiento manual de Compose del proyecto y colóquelo detrás del proxy existente. La documentación indica un mínimo de 2 GB de RAM, pruebas en Ubuntu 24 LTS y ARMv8.2-A o posterior en sistemas ARM debido a ClickHouse.

La consideración importante para cualquier proyecto joven es la siguiente: las funciones se incorporan rápidamente y los cambios incompatibles también. Fije una etiqueta, lea las notas de la versión antes de actualizar y haga primero una copia de seguridad de la base de datos.

Retención y crecimiento del disco: mídalos en su propio servidor

El crecimiento del disco depende de lo que la herramienta almacena en cada evento. GoatCounter agrega las visitas en contadores, por lo que su archivo crece más según el número de páginas y días distintos que según el volumen bruto. Umami y Matomo almacenan una fila por evento, y Matomo añade tablas de informes procesados a las tablas sin procesar. ClickHouse almacena los eventos en columnas y los comprime mucho, por eso Plausible soporta un volumen que pondría bajo presión a un almacén basado en filas.

Esta guía no publica una cifra de megabytes por millón de páginas vistas, porque no la ha medido con su tráfico. Tome la medición usted mismo. Ajuste los nombres del servicio y del usuario para que coincidan con su propio archivo Compose.

du -h goatcounter-data/db.sqlite3
docker compose exec db psql -U umami -d umami -c "SELECT pg_size_pretty(pg_database_size('umami'));"
docker compose exec plausible_events_db clickhouse-client -q "SELECT formatReadableSize(sum(bytes_on_disk)) FROM system.parts WHERE active"

Anote el número, espere una semana, vuelva a anotarlo y divida la diferencia entre las páginas vistas que el panel informa para esa semana. Esa cifra corresponde a su sitio y a su filtrado de bots, por lo que resulta más útil que cualquier promedio publicado. Después, establezca un límite de retención mientras el número todavía sea pequeño. Un disco lleno detiene todos los servicios del VPS, no sólo los de analítica, lo que constituye el argumento más sólido para mantener el volumen de la base de datos en un lugar sobre el que df -h le avisará. Este riesgo merece más atención en un servidor que ya almacena algo voluminoso, porque un servidor de fotos autohospedado agotará el disco mucho antes de que cualquier base de datos de analítica se acerque a ese límite.

Cómo funciona detrás de un reverse proxy en un subdominio

Coloque el collector en un subdominio del sitio que mide, como stats.example.com. Así, las solicitudes del collector son de primer nivel y no las afectan las reglas del navegador que bloquean las solicitudes de terceros.

Enlace la aplicación a loopback al publicar el puerto del contenedor. Docker escribe sus propias reglas de firewall antes que ufw, por lo que un contenedor publicado como -p 3000:3000 es accesible desde Internet aunque ufw status indique que el puerto está denegado. Pruébelo desde otra máquina con curl http://SERVER_IP:3000 y obtendrá el dashboard. Si se publica como -p 127.0.0.1:3000:3000, la misma prueba devuelve Connection refused y sólo el proxy puede acceder a él.

server {
    listen 443 ssl;
    server_name stats.example.com;

    location / {
        proxy_pass http://127.0.0.1:3000;
        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;
    }
}

Las cabeceras de reenvío son obligatorias en este caso. Sin X-Forwarded-For, todas las visitas llegan desde 127.0.0.1, por lo que el informe por país queda vacío y los visitantes únicos tienden a reducirse a uno. Cada proyecto decide qué cabecera acepta y con qué configuración, así que revise una vez su documentación sobre proxies en lugar de darlo por supuesto. Caddy establece esas cabeceras por sí mismo, y un Caddyfile para la misma tarea tiene dos líneas.

stats.example.com {
    reverse_proxy 127.0.0.1:3000
}

Si todavía no ha elegido un proxy, la comparación de nginx, Caddy y Traefik explica cuál se adapta mejor a un único servidor con varios subdominios.

¿Todavía necesita un banner de cookies si aloja el servicio usted mismo?

El alojamiento propio cambia quién conserva los datos. No cambia lo que establece la ley sobre esos datos. Mantenga separadas estas dos reglas. La regla de consentimiento de ePrivacy se refiere a almacenar o leer cualquier dato en el dispositivo del visitante. Por tanto, una herramienta que no establece ninguna cookie ni escribe datos en el almacenamiento local queda fuera de ese requisito específico. El GDPR se refiere al tratamiento de datos personales. Una dirección IP cuenta como dato personal. Por eso, todavía necesita una base jurídica, un límite de conservación y una respuesta cuando alguien pregunte qué datos conserva sobre esa persona.

Plausible, Umami, GoatCounter y Medama no establecen cookies de forma predeterminada. Lo que cada uno deriva en su lugar varía según el proyecto y cambia entre versiones. Consulte la documentación de privacidad del propio proyecto en lugar de un resumen. Matomo incluye anonimización de IP y un endpoint de exclusión voluntaria que se habilita en la interfaz de administración.

Los organismos reguladores llegan a conclusiones diferentes en cada país. Por ejemplo, la CNIL de Francia publica las condiciones en las que la medición de audiencia puede quedar exenta del consentimiento. Esta sección es un resumen informativo y no constituye asesoramiento jurídico. Para un sitio real con usuarios reales, consulte a un abogado de su jurisdicción.

Hay un punto que suele pasarse por alto: un registro de acceso también contiene datos personales. GoAccess no añade ningún script a la página y aun así procesa direcciones IP. Por tanto, la analítica basada en registros no queda automáticamente fuera de estas normas.

Bloqueadores de publicidad y por qué bajarán sus cifras

Las listas de filtros buscan coincidencias en el nombre de host y en el patrón de la URL. Un producto de analítica alojado es fácil de identificar porque todos lo cargan desde el mismo nombre de host conocido. Mover el colector a su propio subdominio elimina ese nombre de host de la solicitud. Servir el script desde una ruta elegida por usted elimina el nombre de archivo conocido. Ambas medidas cambian los elementos con los que debe coincidir una lista.

Esta publicación no afirma una tasa de detección porque no midió ninguna. La proporción de visitantes que bloquea una configuración concreta depende de su audiencia. Una audiencia de desarrolladores bloquea mucho más que una audiencia general. Mida su propia diferencia. Durante la misma semana, cuente con GoAccess las solicitudes de páginas HTML en el registro de acceso y compárelas con las páginas vistas que informa su herramienta basada en scripts. La diferencia corresponde a visitas bloqueadas y a páginas servidas desde la caché de su sitio.

Espere que los totales cambien el día que deje de usar un producto alojado. Parte de ese cambio no tendrá relación con el bloqueo. Los productos no coinciden en la definición de página vista, en si un cambio de ruta dentro de una aplicación de una sola página cuenta como una página y en el momento en que termina una sesión. Compare las tendencias durante varias semanas antes de concluir que el tráfico disminuyó.

Cuál elegir para cada sitio

  • Un sitio personal o un blog con aproximadamente menos de 50,000 páginas vistas al mes: GoatCounter o Medama, en un VPS de 1 GB, con copias de seguridad que consistan en copiar archivos.
  • Un sitio en el que no pueda añadir un script, o con una audiencia que bloquee scripts de forma estricta: GoAccess sobre el registro existente, ejecutado según una programación.
  • Un sitio de una pequeña empresa cuyo panel vaya a consultar otra persona: Umami, con su contenedor de Postgres.
  • Un sitio en el que quiera definir objetivos y embudos, en un equipo con 2 GB de RAM o más: Plausible Community Edition, o Rybbit si prefiere un panel más reciente y acepta un proyecto menos maduro.
  • Muchos sitios, muchas cuentas de usuario o la necesidad de conservar los datos sin procesar según su propia política de retención: Matomo, dimensionado según las recomendaciones publicadas anteriormente.

Empiece con la herramienta más pequeña que responda a su pregunta real. Pasar de GoatCounter a Plausible más adelante le costará un subdominio y parte del historial. Pasar de Matomo a cualquier otra opción le costará una migración que probablemente no querrá realizar. Si todavía está decidiendo qué más alojar en el mismo equipo, la comparativa más amplia de autoalojamiento explica qué servicios pueden funcionar junto a él. Si lo que realmente necesita es rastrear las solicitudes de una aplicación, en lugar de contar visitantes, un servicio de observabilidad autoalojado es la herramienta adecuada.

FAQ

¿El análisis autohospedado elimina la necesidad de mostrar un aviso de cookies?

No, y son dos cuestiones distintas. La regla de consentimiento de ePrivacy se aplica al almacenamiento o la lectura de datos en el dispositivo del visitante. Por tanto, una herramienta que no establece ninguna cookie ni escribe datos en el almacenamiento local queda fuera de ese requisito concreto. GDPR es una norma distinta y se aplica al tratamiento de datos personales. Una dirección IP es un dato personal, por lo que sigue necesitando una base jurídica y un límite de conservación aunque no use cookies. El autohospedaje traslada los datos a su servidor y le convierte en la parte responsable de ellos. Consulte las directrices de su autoridad reguladora y pida asesoramiento jurídico para su caso.

¿Cuánta RAM necesita el análisis autohospedado en un VPS?

La necesidad la determina el almacén de datos, no el panel. GoatCounter y Medama se ejecutan como un solo proceso sobre un único archivo, y la documentación de Medama indica que los sitios pequeños funcionan en máquinas con 256 MB. Umami añade un contenedor de Postgres junto a una aplicación Node. Plausible Community Edition y Rybbit ejecutan ClickHouse, y ambos proyectos indican un mínimo de 2 GB. Las recomendaciones del propio Matomo parten de 2 núcleos de CPU y 2 GB de RAM para un máximo de 100,000 vistas de página al mes.

¿Por qué mis cifras autohospedadas son inferiores a las del sistema de análisis que sustituí?

Hay dos causas, y ambas son reales. Las listas de filtros bloquean algunas solicitudes al recolector, por lo que todas las herramientas basadas en scripts pierden esas visitas. Además, los productos contabilizan de forma distinta, porque varían la definición de vista de página y el momento en que termina una sesión. Compare una semana de solicitudes de páginas HTML en el registro de acceso con la misma semana de vistas de página basadas en scripts. Esa diferencia corresponde a las visitas bloqueadas y a las páginas almacenadas en caché, medidas en su propio sitio en lugar de basarse en una tasa publicada por otra entidad.

¿Puedo ejecutar Plausible o Rybbit en un VPS ARM?

Ambos ejecutan ClickHouse, y ClickHouse necesita SSE 4.2 en x86 o NEON en ARM. Los requisitos de Plausible lo indican expresamente, y la documentación de Rybbit señala que los sistemas ARM necesitan ARMv8.2-A o posterior. Los núcleos ARM actuales cumplen ese requisito, pero los antiguos no. El fallo aparece cuando ClickHouse se niega a arrancar con un error del conjunto de instrucciones, no como un mensaje de la aplicación en su registro. En un equipo ARM pequeño, las herramientas basadas en un único archivo evitan esta cuestión, porque ninguna ejecuta ClickHouse.

¿Debo analizar los registros del servidor en lugar de usar un script de seguimiento?

Use el análisis de registros cuando no pueda añadir un script, cuando su audiencia bloquee muchos recursos o cuando quiera un recuento que incluya los rastreadores. GoAccess lee un registro que el servidor ya genera, por lo que no añade peso a las páginas ni necesita una base de datos. A cambio, no registra lo que ocurre dentro del navegador y omite las páginas servidas desde una CDN o desde la caché del navegador, porque esas solicitudes nunca llegaron al servidor. Muchos sitios utilizan ambos métodos y los tratan como dos mediciones diferentes.