Skip to main content

        Umami: Despliegue de Umami Analytics en Docker - Featured image

Umami: Despliegue de Umami Analytics en Docker

Mantener el control absoluto sobre los datos demográficos y de comportamiento de tus visitantes es fundamental en el mundo de la tecnología Enterprise. Umami Analytics se ha convertido en la alternativa por excelencia para quienes buscan una solución ligera, respetuosa de la privacidad y, sobre todo, fácil de desplegar mediante Docker.

¿Por qué Self-Hosted sobre la versión Cloud?

Aunque Umami ofrece una versión en la nube, el despliegue por cuenta propia (Self-Hosted) ofrece ventajas indiscutibles para un perfil técnico o corporativo:

  1. Sin límites de retención: La versión gratuita del cloud suele tener límites en cuanto a cuántos eventos puedes procesar o por cuánto tiempo se guardan. En tu propio servidor, el único límite es tu almacenamiento.
  2. Soberanía de Datos: Los datos no salen de tu infraestructura. Esto es vital para cumplir con normativas de privacidad o simplemente por filosofía de control total.
  3. Privacidad por Diseño: Al no depender de servidores de terceros, eliminas un punto de rastreo externo.
  4. Cero Costo Operativo: Si ya tienes un servidor con Docker, añadir un contenedor de Umami no incrementa tus costos mensuales.

1. Preparación del Entorno

Umami requiere una base de datos para almacenar las métricas. La forma más limpia y autocontenida de desplegarlo es utilizando Docker Compose para levantar tanto la aplicación de Umami como una base de datos PostgreSQL en el mismo stack.

Crea un directorio dedicado en tu servidor para este servicio:

# Create the directory for Umami
mkdir -p ./docker/umami
cd ./docker/umami

2. Archivo Docker Compose

Crea el archivo docker-compose.yml dentro del directorio. Asegúrate de cambiar el valor de APP_SECRET por una cadena de texto larga y aleatoria (puedes generarla con openssl rand -hex 32), y modifica las contraseñas de la base de datos por seguridad.

config para exponer puertos de umami

# Docker Compose stack for Umami Analytics with PostgreSQL
networks:
  umami-net:
    driver: bridge

services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    container_name: VPC_CT_umami_app
    environment:
      # Database connection string format: postgresql://user:password@hostname:port/database_name
      DATABASE_URL: postgresql://umami_user:SuperSecretDBPassword!@umami_db:5432/umami_data
      DATABASE_TYPE: postgresql
      # Replace with your own random hash for session encryption
      APP_SECRET: replace_this_with_a_random_string_of_characters
    ports:
      # Expose port 3000 to the host
      - "3000:3000"
    depends_on:
      - umami_db
    networks:
      - umami-net
    restart: unless-stopped

  umami_db:
    image: postgres:15-alpine
    container_name: umami_db
    environment:
      # These must match the credentials in the DATABASE_URL above
      POSTGRES_DB: umami_data
      POSTGRES_USER: umami_user
      POSTGRES_PASSWORD: SuperSecretDBPassword!
    volumes:
      # Persist the database files on the host
      - umami-db-data:/var/lib/postgresql/data
    networks:
      - umami-net
    restart: unless-stopped

volumes:
  # Define the named volume for persistence
  umami-db-data:

Config con Cloudflare tunnels sin exponer puertos

Utilizar Cloudflare Tunnels es la opción más segura para exponer servicios en un entorno Enterprise. A diferencia de la apertura de puertos (Port Forwarding), un túnel establece una conexión saliente hacia Cloudflare, lo que significa que no tienes que abrir puertos en tu firewall ni exponer tu IP pública directamente a Internet.

Esta arquitectura no solo mitiga vectores de ataque como escaneos de puertos o ataques DDoS directos, sino que te permite apalancar el WAF (Web Application Firewall) de Cloudflare para filtrar tráfico malicioso antes de que llegue a tu red. Además, es la solución definitiva para self-hosters que se encuentran behind cgNAT, ya que elimina la necesidad de contar con una IP pública direccionable.

Note

Profundizaremos en la arquitectura y despliegue de Cloudflare Tunnels en futuros posts, donde veremos cómo configurarlos paso a paso.

# Docker Compose stack for Umami Analytics with PostgreSQL and Cloudflare Tunnels
networks:
  # External network managed outside this compose file (Cloudflare Tunnel network)
  cloudflare_internal_net:
    external: true
  
  # Isolated internal network for Umami to communicate with its database
  umami_internal_net:
    driver: bridge

services:
  umami:
    image: ghcr.io/umami-software/umami:postgresql-latest
    container_name: VPC_CT_umami_app
    environment:
      # Database connection string format: postgresql://user:password@hostname:port/database_name
      DATABASE_URL: postgresql://umami_user:SuperSecretDBPassword!@umami_db:5432/umami_data
      DATABASE_TYPE: postgresql
      # Replace with your own secure random hash for session encryption
      APP_SECRET: replace_this_with_a_random_string_of_characters
    depends_on:
      - umami_db
    networks:
      # Connect to Cloudflare tunnel network to expose the service
      - cloudflare_internal_net
      # Connect to internal network to reach the database
      - umami_internal_net
    restart: unless-stopped
    # The 'ports' directive is intentionally omitted. The service is only accessible within the Docker networks.

  umami_db:
    image: postgres:15-alpine
    container_name: umami_db
    environment:
      # These must match the credentials in the DATABASE_URL above
      POSTGRES_DB: umami_data
      POSTGRES_USER: umami_user
      POSTGRES_PASSWORD: SuperSecretDBPassword!
    volumes:
      # Persist the database files on the host
      - umami-db-data:/var/lib/postgresql/data
    networks:
      # The database is only connected to the internal network for security
      - umami_internal_net
    restart: unless-stopped

volumes:
  # Define the named volume for database persistence
  umami-db-data:

3. Despliegue y Ejecución

Una vez guardado el archivo, levanta los contenedores en segundo plano:

# Start the containers in detached mode
sudo docker compose up -d

Puedes verificar que ambos contenedores estén corriendo correctamente y revisar los logs si algo falla:

# Check container status
docker ps

# View application logs
docker logs -f umami

4. Configuración Inicial en la Interfaz Web

  1. Abre tu navegador y accede a http://<IP-DE-TU-SERVIDOR>:3000, (Si expusiste tu servicio por Cloudflare, abre el subdominio que hayas seleccionado)

  2. Inicia sesión con las credenciales por defecto:

    • Usuario: admin
    • Contraseña: umami

  1. Paso Crítico: Ve a la sección de Profile (Perfil) en la esquina superior derecha y cambia la contraseña inmediatamente.

Crea un nuevo usuario, asígnalo como administrador, cierra sesión e ingresa con la nueva sesión. Ahora, regresa a la administración y elimina el usuario admin.

Tip

Es una excelente práctica de seguridad eliminar los usuarios por defecto (como admin) una vez que has creado tu propia cuenta administrativa. Los atacantes suelen automatizar intentos de inicio de sesión utilizando estos nombres de usuario comunes.

  1. Navega a Websites > Add website.

  1. Ingresa el nombre de tu sitio y el dominio.

Te saldrá el icono de tu página, haz clic sobre el nombre.

  1. Una vez creado, haz clic en el botón de Edit (Editar).

  1. Copia el script de JavaScript proporcionado; este es el que inyectarás en la cabecera (<head>) de tu sitio estático en Hugo.

Una vez que hayas agregado el código al archivo head.html, podrás ver la información en Umami.


Conclusión

Implementar Umami mediante Docker no solo te otorga métricas precisas sin comprometer la velocidad de carga de tu sitio, sino que refuerza la robustez de tu infraestructura al integrar una herramienta de grado profesional bajo tu total mando. Una vez que el script está inyectado, el análisis de tráfico se vuelve una tarea trivial dentro de tu ecosistema tecnológico.