Autoalojar Plausible Analytics en un VPS con Docker Compose
Despliega Plausible Community Edition en tu VPS con Docker Compose. Guía completa que cubre instalación, integración del script de seguimiento, eventos personalizados, copias de seguridad y actualizaciones.
Plausible Analytics ofrece analítica web sin cookies, sin recopilación de datos personales y sin banners de consentimiento. Autoalojar la Community Edition significa que los datos de tus visitantes nunca salen de tu servidor. Esta guía cubre el ciclo de vida completo: despliegue de Plausible CE v3.2.0 con Docker Compose, integración del script de seguimiento, configuración de eventos personalizados, copias de seguridad y actualizaciones.
Requisitos previos: Un VPS con al menos 4 GB de RAM ejecutando Docker y Docker Compose Docker en producción en un VPS: qué falla y cómo solucionarlo, un nombre de dominio apuntando a tu servidor, y un reverse proxy gestionando TLS Traefik vs Caddy vs Nginx: reverse proxy Docker comparado.
¿Qué es Plausible Community Edition y en qué se diferencia de la versión Cloud?
Plausible CE es la versión autoalojada, gratuita y con licencia AGPL de Plausible Analytics. Se ejecuta como tres contenedores Docker: la aplicación web Plausible (Elixir), PostgreSQL para cuentas de usuario y ClickHouse para el almacenamiento de eventos analíticos. Obtienes el mismo panel de control respetuoso con la privacidad que la versión cloud de pago. Tus datos permanecen en tu servidor. La CE se publica dos veces al año como versión de soporte a largo plazo.
Las diferencias:
| Característica | Cloud | Community Edition |
|---|---|---|
| Panel de analítica | Sí | Sí |
| Privacidad (sin cookies) | Sí | Sí |
| Eventos y objetivos personalizados | Sí | Sí |
| Stats API (v2) | Sí | Sí |
| Informes por correo | Sí | Sí (requiere SMTP) |
| Funnels y objetivos de ingresos | Sí | No |
| Sites API | Sí | No |
| Conector Looker Studio | Sí | No |
| Integración Google Search Console | Sí | Sí (requiere configuración) |
| SSO / gestión de equipos | Sí | No |
| Soporte premium | Sí | Solo comunidad |
| Frecuencia de actualizaciones | Semanal | Dos veces al año |
| Gestión de infraestructura | Gestionada | Tú te encargas |
La versión cloud funciona con un modelo de suscripción. Consulta la página de precios de Plausible para las tarifas actuales. El autoalojamiento solo te cuesta los recursos de tu VPS.
¿Cuáles son los requisitos del sistema para autoalojar Plausible?
ClickHouse es el componente más exigente. Necesita al menos 2 GB de RAM en reposo y consume más durante consultas complejas sobre grandes conjuntos de datos. La CPU debe soportar instrucciones SSE 4.2 (todos los procesadores x86_64 modernos lo hacen; ARM64 con NEON también funciona). Dimensiona tu VPS en consecuencia.
| Recurso | Mínimo | Recomendado |
|---|---|---|
| RAM | 2 GB | 4 GB |
| CPU | 1 vCPU (SSE 4.2) | 2 vCPU |
| Disco | 10 GB | 20 GB+ |
| Docker | 20.10+ | Última versión estable |
| Docker Compose | v2.x | Última versión estable |
El crecimiento del disco depende del tráfico. Calcula aproximadamente 1 GB por cada 1-2 millones de páginas vistas almacenadas en ClickHouse. Con volúmenes bajos de tráfico (menos de 100.000 páginas vistas al mes), el uso de disco es insignificante.
¿Cómo se instala Plausible Analytics con Docker Compose?
Clona el repositorio oficial de la Community Edition en el tag v3.2.0, configura las variables de entorno e inicia los contenedores. El proceso completo lleva unos cinco minutos.
Clona el repositorio:
git clone -b v3.2.0 --single-branch https://github.com/plausible/community-edition plausible-ce
cd plausible-ce
Esto te da el compose.yml, los archivos de configuración de ClickHouse y un README.
¿Cómo se configuran las variables de entorno?
Crea un archivo .env en el directorio plausible-ce. Dos variables son obligatorias. El resto son opcionales, pero algunas se recomiendan encarecidamente.
Genera primero los secretos:
openssl rand -base64 48
Esto produce una cadena de 64 caracteres. Cópiala para SECRET_KEY_BASE.
Genera una clave separada para el cifrado TOTP:
openssl rand -base64 32
Ahora crea el archivo .env:
cat > .env << 'EOF'
BASE_URL=https://plausible.example.com
SECRET_KEY_BASE=<your-64-char-secret>
TOTP_VAULT_KEY=<your-32-char-key>
DISABLE_REGISTRATION=invite_only
# SMTP for email reports and password resets
MAILER_EMAIL=plausible@example.com
SMTP_HOST_ADDR=mail.example.com
SMTP_HOST_PORT=587
SMTP_USER_NAME=plausible@example.com
SMTP_USER_PWD=<your-smtp-password>
SMTP_HOST_SSL_ENABLED=false
EOF
Restringe los permisos del archivo ya que contiene secretos:
chmod 600 .env
ls -la .env
-rw------- 1 root root 412 Mar 20 10:00 .env
Qué hace cada variable:
- BASE_URL: La URL pública donde Plausible es accesible. Debe coincidir con la configuración de tu reverse proxy.
- SECRET_KEY_BASE: Cifra las sesiones y genera claves derivadas. Mínimo 64 bytes. Nunca la compartas.
- TOTP_VAULT_KEY: Cifra los secretos de autenticación de dos factores con AES256-GCM. Si se omite, se deriva de
SECRET_KEY_BASEvía PBKDF2, pero establecerla explícitamente es más seguro para la rotación de claves. - DISABLE_REGISTRATION: Establécelo en
invite_only(por defecto) otruedespués de crear tu cuenta. Impide que desconocidos se registren en tu instancia. - Variables SMTP: Necesarias para informes por correo, restablecimiento de contraseña e invitaciones. Sin SMTP, Plausible funciona pero las funciones de correo están desactivadas.
¿Cómo se configura un reverse proxy con TLS para Plausible?
Plausible escucha en el puerto 8000 por defecto. Tu reverse proxy redirige el tráfico HTTPS hacia él. Si ya tienes Caddy o Traefik funcionando desde Traefik vs Caddy vs Nginx: reverse proxy Docker comparado, añade Plausible como nuevo upstream.
Crea un compose.override.yml para conectar Plausible a la red de tu reverse proxy:
services:
plausible:
networks:
- proxy
- default
networks:
proxy:
external: true
Si usas Caddy, añade esto a tu Caddyfile:
plausible.example.com {
reverse_proxy plausible:8000
}
Si usas Traefik, añade labels al override:
services:
plausible:
labels:
- "traefik.enable=true"
- "traefik.http.routers.plausible.rule=Host(`plausible.example.com`)"
- "traefik.http.routers.plausible.tls.certresolver=letsencrypt"
- "traefik.http.services.plausible.loadbalancer.server.port=8000"
networks:
- proxy
- default
networks:
proxy:
external: true
Alternativamente, Plausible tiene soporte integrado para Let's Encrypt. Establece HTTP_PORT=80 y HTTPS_PORT=443 en tu archivo .env, luego expón esos puertos en el override:
services:
plausible:
ports:
- 80:80
- 443:443
Este enfoque es más sencillo pero implica que Plausible gestiona TLS por sí mismo, lo que puede generar conflictos si otros servicios comparten el mismo servidor.
Iniciar los contenedores
docker compose up -d
Se inician tres contenedores: plausible_db (PostgreSQL 16), plausible_events_db (ClickHouse 24.12) y plausible (la aplicación web). El contenedor Plausible ejecuta las migraciones de base de datos automáticamente al arrancar.
Comprueba que los tres estén operativos:
docker compose ps
NAME IMAGE STATUS
plausible ghcr.io/plausible/community-edition:v3.2.0 Up 30s (healthy)
plausible_db postgres:16-alpine Up 35s (healthy)
plausible_events_db clickhouse/clickhouse-server:24.12-alpine Up 35s (healthy)
Los tres deberían mostrar (healthy). Si ClickHouse muestra (health: starting), espera un minuto más. Ejecuta un healthcheck vía wget contra su interfaz HTTP.
Crear tu cuenta de administrador
Abre https://plausible.example.com en tu navegador. Verás el formulario de registro. Crea tu cuenta. Con DISABLE_REGISTRATION=invite_only, los nuevos usuarios solo pueden registrarse si los invitas explícitamente desde el panel de control.
Después del registro, bloquea completamente los registros si eres el único usuario:
Edita .env y cambia:
DISABLE_REGISTRATION=true
Luego reinicia:
docker compose up -d
¿Cómo se añade el script de seguimiento de Plausible a tu sitio?
Después de iniciar sesión, haz clic en «Add a website» e introduce tu dominio. Plausible genera un fragmento de código de seguimiento. La etiqueta script por defecto tiene este aspecto:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.js"></script>
Reemplaza plausible.example.com con la URL real de tu instancia Plausible. Añade esta etiqueta al <head> de cada página que quieras rastrear.
¿Cómo se añade Plausible a un sitio HTML estático?
Pega la etiqueta script directamente en el <head> de tu HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>My Site</title>
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.js"></script>
</head>
<body>
<!-- content -->
</body>
</html>
Para generadores de sitios estáticos (Hugo, Jekyll, 11ty), añade la etiqueta script a tu plantilla base o partial head.
¿Cómo se añade Plausible a un sitio WordPress?
El plugin oficial Plausible Analytics para WordPress (v2.5.4, más de 10.000 instalaciones activas) gestiona todo desde el panel de WordPress.
- Instala el plugin: Plugins > Añadir nuevo > Buscar «Plausible Analytics»
- Ve a Ajustes > Plausible Analytics
- Introduce la URL de tu instancia autoalojada (ej.
https://plausible.example.com) - Introduce el nombre de dominio a rastrear
- Guarda
El plugin inyecta el script de seguimiento automáticamente. También soporta seguimiento de conversiones WooCommerce y seguimiento automático de envíos de formularios para Contact Form 7, WPForms y Ninja Forms.
¿Cómo se añade Plausible a una aplicación Next.js?
Usa el paquete next-plausible (v3.12.5, 36.000 descargas semanales).
npm i next-plausible
Para el App Router (Next.js 13+), añade el provider en tu layout raíz:
import PlausibleProvider from "next-plausible";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html>
<head>
<PlausibleProvider
domain="yoursite.com"
customDomain="https://plausible.example.com"
selfHosted
/>
</head>
<body>{children}</body>
</html>
);
}
Para rastrear eventos personalizados en componentes, usa el hook usePlausible:
"use client";
import { usePlausible } from "next-plausible";
export default function SignupButton() {
const plausible = usePlausible();
return (
<button onClick={() => plausible("Signup")}>
Sign up
</button>
);
}
¿Cómo se añade Plausible a una aplicación de página única?
Para React, Vue, Svelte o cualquier SPA, añade la etiqueta script a tu index.html. Plausible detecta automáticamente los cambios de ruta a través de la History API. No se necesita configuración adicional.
Si tu SPA usa enrutamiento basado en hash (/#/path), usa la extensión hash:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.hash.js"></script>
¿Cómo se rastrean eventos personalizados y objetivos en Plausible?
Los eventos personalizados permiten rastrear acciones más allá de las páginas vistas: clics en botones, envíos de formularios, descargas de archivos, registros. Plausible ofrece dos métodos: un enfoque sin código mediante clases CSS y una API JavaScript para seguimiento dinámico.
Primero, activa el script mejorado que soporta eventos personalizados. Reemplaza la fuente del script por defecto:
<script defer data-domain="yoursite.com" src="https://plausible.example.com/js/script.tagged-events.js"></script>
Método de clases CSS (sin JavaScript)
Añade una clase CSS con el formato plausible-event-name=EventName a cualquier elemento HTML:
<a href="/signup" class="plausible-event-name=Signup">Create Account</a>
<button class="plausible-event-name=Download+PDF">Download Report</button>
<form class="plausible-event-name=Contact+Form+Submit">
<!-- form fields -->
</form>
Usa + para espacios en los nombres de eventos. Algunos CMS (Webflow) reemplazan = por -. En ese caso, usa un doble guion --: plausible-event-name--Signup.
API JavaScript para eventos dinámicos
Llama a la función plausible() directamente para eventos que necesiten lógica condicional o propiedades dinámicas:
// Simple event
plausible("Signup");
// Event with custom properties
plausible("Download", {
props: { format: "PDF", document: "annual-report" }
});
// Event with a callback (useful for redirects)
plausible("Outbound Link", {
props: { url: "https://example.com" },
callback: () => { window.location = "https://example.com"; }
});
Crear el objetivo en tu panel de control
Los eventos no aparecen en tu panel de control hasta que crees un objetivo correspondiente. Ve a Site Settings > Goals > Add Goal. Selecciona «Custom event» e introduce el nombre exacto del evento (ej. Signup). El nombre distingue entre mayúsculas y minúsculas y debe coincidir con tu código.
¿Cómo se usa la Stats API de Plausible?
Plausible incluye una Stats API (v2) para acceder a tus datos analíticos de forma programática. En tu instancia autoalojada, la URL base de la API es https://plausible.example.com/api/v2/query.
Crea una clave API: ve a Account Settings > API Keys > New API Key > Stats API.
Consulta el número de visitantes de los últimos 7 días:
curl --request POST \
--header 'Authorization: Bearer YOUR-API-KEY' \
--header 'Content-Type: application/json' \
--url 'https://plausible.example.com/api/v2/query' \
--data '{
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews", "bounce_rate"],
"date_range": "7d"
}'
{
"results": [
{
"metrics": [1423, 3847, 42],
"dimensions": []
}
],
"query": {
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews", "bounce_rate"],
"date_range": ["2026-03-13", "2026-03-20"]
}
}
Desglose de visitantes por página:
curl --request POST \
--header 'Authorization: Bearer YOUR-API-KEY' \
--header 'Content-Type: application/json' \
--url 'https://www.example.com/api/v2/query' \
--data '{
"site_id": "yoursite.com",
"metrics": ["visitors", "pageviews"],
"date_range": "30d",
"dimensions": ["event:page"],
"pagination": {"limit": 5}
}'
La API soporta filtrado, dimensiones temporales (time:day, time:month) y ordenación. El límite de tasa es de 600 peticiones por hora. Consulta la referencia completa de la Stats API para todas las métricas y dimensiones disponibles.
¿Cómo se configuran los informes por correo?
Los informes por correo requieren una configuración SMTP funcional en tu archivo .env (cubierta en la sección de configuración anterior). Una vez configurado SMTP, cualquier usuario puede activar informes semanales o mensuales desde el panel de Plausible.
Ve a Site Settings > Email Reports. Añade las direcciones de los destinatarios. Plausible envía un resumen de visitantes, páginas más visitadas y fuentes de tráfico en la frecuencia que elijas.
Si los correos no llegan, revisa los logs del contenedor Plausible:
docker compose logs plausible | grep -i mail
Problemas habituales: puerto SMTP incorrecto (usa 587 para STARTTLS, 465 para TLS implícito con SMTP_HOST_SSL_ENABLED=true), o fallos de autenticación.
¿Cómo se hace una copia de seguridad de una instancia Plausible autoalojada?
Plausible almacena datos en dos bases de datos y un volumen. Perder cualquiera de ellos significa perder datos. Haz copia de seguridad de los tres.
| Datos | Almacenamiento | Método de backup |
|---|---|---|
| Cuentas de usuario, configuración de sitios | PostgreSQL | pg_dump |
| Eventos analíticos | ClickHouse | Backup de volumen o comando BACKUP |
| Certificados, uploads | Volumen plausible-data |
Copia de volumen |
Copia de seguridad de PostgreSQL
docker compose exec plausible_db pg_dump -U postgres plausible_db | gzip > backup-postgres-$(date +%F).sql.gz
Copia de seguridad de ClickHouse
ClickHouse 24.12 soporta el comando BACKUP de forma nativa. Ejecútalo dentro del contenedor:
docker compose exec plausible_events_db clickhouse-client \
--query "BACKUP DATABASE plausible_events_db TO Disk('backups', 'plausible-$(date +%F).zip')"
Si el disco backups no está configurado, usa un backup a nivel de volumen:
docker compose stop plausible_events_db
docker run --rm \
-v plausible-ce_event-data:/source:ro \
-v $(pwd)/backups:/backup \
alpine tar czf /backup/clickhouse-$(date +%F).tar.gz -C /source .
docker compose start plausible_events_db
Esto detiene ClickHouse brevemente. Para copias de seguridad sin tiempo de inactividad, configura el disco backups en ClickHouse o usa clickhouse-backup.
Automatización
Crea un script en /opt/plausible-backup.sh:
#!/bin/bash
set -euo pipefail
BACKUP_DIR=/opt/backups/plausible
mkdir -p "$BACKUP_DIR"
cd /opt/plausible-ce
# PostgreSQL
docker compose exec -T plausible_db pg_dump -U postgres plausible_db \
| gzip > "$BACKUP_DIR/postgres-$(date +%F).sql.gz"
# ClickHouse volume
docker run --rm \
-v plausible-ce_event-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/clickhouse-$(date +%F).tar.gz" -C /source .
# Plausible data volume
docker run --rm \
-v plausible-ce_plausible-data:/source:ro \
-v "$BACKUP_DIR":/backup \
alpine tar czf "/backup/plausible-data-$(date +%F).tar.gz" -C /source .
# Rotate: keep 14 days
find "$BACKUP_DIR" -name "*.gz" -mtime +14 -delete
echo "Backup complete: $(ls -lh $BACKUP_DIR/*$(date +%F)*)"
chmod 700 /opt/plausible-backup.sh
Prográmalo con cron para ejecución diaria:
crontab -e
Añade:
0 3 * * * /opt/plausible-backup.sh >> /var/log/plausible-backup.log 2>&1
Para más información sobre estrategias de backup de volúmenes Docker, consulta Copia de seguridad y restauración de volúmenes Docker en un VPS.
¿Cómo se actualiza Plausible Community Edition de forma segura?
Plausible CE se publica dos veces al año. Fija tu versión a un tag específico en compose.yml para actualizaciones predecibles. La configuración por defecto ya fija la versión v3.2.0.
Estrategias de fijación de versión:
| Nivel | Ejemplo de tag | Qué se actualiza automáticamente |
|---|---|---|
| Patch (más seguro) | v3.2.0 |
Nada. Solo actualizaciones manuales. |
| Minor | v3.2 |
Releases de corrección (bugfixes) |
| Major | v3 |
Releases minor y de corrección |
Recomendado: fija a nivel de patch y actualiza manualmente tras leer las notas de la versión.
Procedimiento de actualización
-
Lee las notas de la versión en busca de cambios incompatibles
-
Haz copia de seguridad de tus bases de datos (ejecuta el script de backup anterior)
-
Descarga la nueva versión:
cd /opt/plausible-ce
git fetch --tags
git checkout v3.3.0 # replace with the target version
- Inicia los contenedores actualizados:
docker compose up -d
Plausible ejecuta las migraciones de base de datos automáticamente al arrancar. Observa los logs durante el primer inicio:
docker compose logs -f plausible
Busca [info] Migrations up to XXXXXXXX applied successfully en la salida. Si ves errores de migración, no descartes los datos antiguos. Consulta la página wiki de actualización para instrucciones específicas por versión.
- Limpia la imagen antigua:
docker image prune -f
Los parches de seguridad no se retroportan a versiones anteriores. Suscríbete a las notificaciones de releases en GitHub: ve al repositorio, haz clic en Watch > Custom > Releases.
¿Es Plausible autoalojado compatible con el RGPD sin cookies?
Sí. Plausible no establece cookies. No recopila ni almacena datos personales. Los visitantes únicos se cuentan mediante un hash de la dirección IP del visitante combinada con la cadena User-Agent. Este hash se renueva cada 24 horas y nunca se almacena en bruto. La dirección IP sin procesar se descarta después del hashing.
Esto significa:
- No se necesita banner de consentimiento de cookies bajo el RGPD, CCPA o PECR
- No hay tratamiento de datos personales, por lo que los requisitos de base legal del artículo 6 del RGPD no aplican
- El autoalojamiento garantiza que los datos nunca salen de tu servidor ni pasan por un encargado de tratamiento externo
- Sigues siendo el único responsable del tratamiento, sin necesidad de contratos de encargado de tratamiento para analítica
Si alojas tu VPS en la UE (los servidores de Virtua Cloud están ubicados en centros de datos europeos), tus datos analíticos permanecen en la UE. Sin problemas de transferencia relacionados con Schrems II.
Por eso muchos desarrolladores independientes y preocupados por la privacidad abandonan Google Analytics. Sin banners de consentimiento, sin fricción para los visitantes y sin contratos de encargado de tratamiento que gestionar.
Monitorizar el consumo de recursos de ClickHouse
ClickHouse es el componente que más recursos consume. En reposo con bajo tráfico, usa alrededor de 500 MB de RAM. Durante consultas sobre grandes conjuntos de datos, puede llegar a 2-3 GB. Si tu VPS tiene solo 2 GB de RAM total, puedes sufrir OOM kills en periodos de carga.
Monitoriza el uso de memoria:
docker stats plausible_events_db --no-stream
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
a1b2c3d4e5f6 plausible_events_db 0.50% 487MiB / 3.84GiB 12.38%
La configuración de ClickHouse incluida con Plausible CE ya contiene ajustes para entornos con recursos limitados (vía low-resources.xml y default-profile-low-resources-overrides.xml). Estos limitan el uso de memoria para merges y consultas.
Si necesitas ajustar más, crea un archivo clickhouse/custom.xml y móntalo en compose.override.yml. Para límites de recursos en Docker Compose, consulta Límites de recursos, healthchecks y políticas de reinicio en Docker Compose.
Revisa los logs de ClickHouse en busca de advertencias:
docker compose logs plausible_events_db | grep -i "memory\|oom"
¿Algo no funciona?
Los contenedores no arrancan: Revisa docker compose logs <service>. Causas habituales: conflictos de puertos, variables .env faltantes, ClickHouse fallando la comprobación SSE 4.2 en CPUs antiguas.
«Bad Request» en la página de login: Tu BASE_URL no coincide con la URL que estás usando. Plausible verifica la cabecera origin contra BASE_URL para prevenir ataques CSRF.
El script de seguimiento no registra visitas: Abre las herramientas de desarrollo del navegador, revisa la pestaña Red para peticiones a /api/event. Una respuesta 202 significa que el evento fue aceptado. Si ves errores CORS, tu reverse proxy está eliminando cabeceras. Asegúrate de que el proxy pase la cabecera Host.
Los informes por correo no se envían: Verifica las credenciales SMTP. Revisa los logs con docker compose logs plausible | grep -i smtp. Prueba tu servidor SMTP de forma independiente con swaks o openssl s_client.
ClickHouse terminado por el OOM killer: Tu VPS no tiene suficiente RAM. Actualiza a al menos 4 GB, o reduce max_memory_usage en una configuración personalizada de ClickHouse.
El panel muestra cero visitantes después de la instalación: El script de seguimiento puede estar bloqueado por bloqueadores de anuncios. Considera hacer proxy del script a través de tu dominio principal. La documentación de Plausible lo llama proxy setup.
Para monitorizar la disponibilidad de tu instancia Plausible, consulta Auto-alojar Uptime Kuma y Beszel en un VPS con Docker Compose.
¿Listo para probarlo?
Despliega tu propio servidor en segundos. Linux, Windows o FreeBSD. →