May: Dashboard de Gestión de Flotas y Consumo de Combustible Autoalojado

Publicado por


Autoalojado · Flask · Docker

May: Dashboard de Gestión de Flotas y Consumo de Combustible Autoalojado

Aplicación web para registrar repostajes, gastos, mantenimiento y recordatorios de múltiples vehículos con soporte multiusuario y API REST.

Vídeo tutorial en YouTube

Mira el vídeo completo sobre cómo instalar y usar May: Dashboard de Gestión de Flotas y Consumo de Combustible Autoalojado en el canal GENBYTE:

¿Qué es May: Dashboard de Gestión de Flotas y Consumo de Combustible Autoalojado?

May es una aplicación web autoalojada diseñada para llevar un control detallado del consumo de combustible, gastos, mantenimiento y recordatorios de una flota de vehículos. Desarrollada en Python con Flask, ofrece una interfaz moderna tipo dashboard con soporte para múltiples usuarios, roles de acceso, vehículos de distintos tipos (coches, motos, furgonetas, maquinaria) y unidades de medida configurables. Incluye funcionalidades avanzadas como importación/exportación de datos, integración con Home Assistant, notificaciones multicanal, generación de informes PDF y compatibilidad PWA para uso móvil offline. El proyecto se distribuye como imagen Docker lista para producción y permite usar SQLite o PostgreSQL como base de datos.

Gestión completa de flotas con registro de repostajes, gastos, mantenimiento, neumáticos, recordatorios y API REST, todo autoalojado y con interfaz responsive lista para móvil.

Características principales

Soporte multi-vehículo y multi-usuario

Permite gestionar coches, motos, furgonetas y maquinaria con tipos de combustible personalizados. Cada usuario puede tener acceso a vehículos propios o compartidos, con roles Editor, Colaborador (solo repostajes y cargas) o Visor (solo lectura).

Registro de repostajes con cálculos automáticos

Registra fecha, kilometraje, litros, coste total y precio por unidad. Calcula automáticamente consumo en L/100 km y MPG. Soporta vehículos de doble combustible (gasolina+GLP) con distancia por tipo de combustible, y AdBlue/DEF como fluido secundario en diésel. Incluye IVA/impuestos opcionales por repostaje con totales anuales.

Gestión de gastos y gastos recurrentes

Categoriza gastos en mantenimiento, inspecciones, seguros, impuestos, peajes, accesorios y otros. Permite adjuntar múltiples recibos por gasto. Los gastos recurrentes generan automáticamente entradas periódicas (mensual, trimestral, anual) con proveedor opcional.

Mantenimiento programado y neumáticos

Define intervalos por kilometraje, horas de motor o tiempo (ej. cambio de aceite cada 10 000 km o 12 meses). Genera recordatorios automáticos y permite vincular gastos al completar. Rastrea juegos de neumáticos (verano, invierno, todas estaciones) con montaje/desmontaje por eje y cálculo de distancia recorrida por juego.

Registro de viajes y cargas de vehículos eléctricos

Registra viajes con origen, destino, propósito y lecturas de cuentakilómetros. Opcionalmente, lecturas de nivel de combustible para consumo por viaje. Para VE e híbridos enchufables: sesiones de carga con kWh, estado de carga, coste, tipo de cargador, red y ubicación.

Recordatorios y notificaciones multicanal

Recordatorios para ITV, revisiones, seguros, impuestos y personalizados con recurrencia flexible. Notificaciones por email (SMTP), ntfy, Pushover y webhooks (Home Assistant, Discord, Slack). Incluye acción 'Registrar gasto' desde recordatorio pendiente.

Documentos y archivos adjuntos

Almacena documentos por vehículo (seguros, matriculación, manuales, ITV) con fecha de caducidad. Admite cualquier tipo de archivo hasta 300 MB. Los adjuntos se vinculan a repostajes, gastos y cargas.

Importación, exportación y respaldos

Exporta todo en JSON o CSV. Respaldo completo en ZIP (incluye documentos, imágenes y adjuntos). Importa desde CSV de Fuelly o respaldos de May/Hammond. Vista previa antes de confirmar y deduplicación automática.

Integraciones: DVLA, precios UK, Home Assistant, Calendario

Consulta automática de ITV e impuesto de circulación UK (requiere API key DVLA). Precios de carburante en vivo de estaciones UK sin API key. Endpoints REST para Home Assistant (/api/ha/). Suscripción a recordatorios vía webcal/HTTPS para Apple/Google/Outlook Calendar.

API REST, PWA, internacionalización y personalización

API documentada en /api/docs con clave API por usuario. PWA instalable con capacidades offline. 24 idiomas disponibles. Modo oscuro, branding personalizado (logo, nombre, color), menú configurable y página de inicio preferida.

Requisitos del sistema

  • Docker y Docker Compose (recomendado)
  • Python 3.12+ para instalación manual
  • Base de datos: SQLite (por defecto) o PostgreSQL
  • Directorio de datos con permisos de escritura para el usuario del contenedor (PUID/PGID, por defecto 1000:1000)
  • Puerto 5050 libre en el host
  • Dependencias de sistema para WeasyPrint (PDF): libpango-1.0-0, libpangocairo-1.0-0 (Debian/Ubuntu) o pango (macOS)

Instalación con Docker Compose

Inicio rápido con Docker Compose

Crea un directorio, descarga el archivo docker-compose.yml oficial y levanta el contenedor. La imagen se publica en ghcr.io/dannymcc/may:latest.

mkdir may && cd may
curl -O https://raw.githubusercontent.com/dannymcc/may/main/docker-compose.yml
docker compose up -d

Ejecución directa con Docker (sin Compose)

Lanza el contenedor mapeando el puerto 5050, un volumen para datos y variables de entorno obligatorias. El contenedor sigue la convención linuxserver.io para PUID/PGID.

docker run -d \
–name may \
-p 5050:5050 \
-v may_data:/app/data \
-e SECRET_KEY=your-secret-key \
-e PUID=1000 \
-e PGID=1000 \
ghcr.io/dannymcc/may:latest

Instalación manual (entorno virtual)

Clona el repositorio, crea un entorno virtual, instala dependencias, compila catálogos de traducción y ejecuta la aplicación. Requiere Python 3.12+ y dependencias de sistema para WeasyPrint.

python3 -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pybabel compile -d app/translations
python run.py

Acceder al proyecto

Acceso a la interfaz web

La aplicación escucha en el puerto 5050. Accede mediante http://localhost:5050 (o la IP del host). En el primer inicio, si no se define ADMIN_PASSWORD, se genera una contraseña aleatoria para el usuario 'admin' que se muestra en los logs del contenedor. Consúltala con 'docker logs may'.

Credenciales iniciales

Usuario: admin. Contraseña: la mostrada en los logs del contenedor al primer arranque (busca 'SECURITY NOTICE: Default admin account created'). Cambia la contraseña tras el primer acceso. Para evitar la generación automática, define la variable de entorno ADMIN_PASSWORD en docker-compose.yml o .env.

Casos de uso

  • Control de consumo y costes de combustible de flotas familiares o empresariales
  • Gestión de mantenimiento preventivo con recordatorios por kilometraje, horas de motor o fecha
  • Registro de gastos deducibles para declaraciones fiscales (IVA, gastos por kilómetro)
  • Seguimiento de neumáticos por eje y cálculo de vida útil por juego
  • Integración con Home Assistant para automatizaciones y paneles de control doméstico
  • Centralización de documentación del vehículo (seguros, ITV, manuales) con alertas de caducidad
  • Importación de histórico desde Fuelly o migración entre instancias de May
  • Generación de informes PDF con recibos para contabilidad o reembolsos de empresa

Configuración avanzada

Configuración mediante variables de entorno

Las variables principales se definen en docker-compose.yml (bloque environment) o en .env junto a config.py. Las variables de entorno reales tienen prioridad sobre .env. En Docker Compose, .env solo sirve para sustitución de variables en el propio compose (ej. SECRET_KEY). DATABASE_URL y UPLOAD_FOLDER deben editarse en docker-compose.yml.

environment:
– SECRET_KEY=${SECRET_KEY:-change-me-in-production}
– DATABASE_URL=sqlite:////app/data/may.db
– UPLOAD_FOLDER=/app/data/uploads
– PUID=${PUID:-1000}
– PGID=${PGID:-1000}
# – ADMIN_PASSWORD=your-secure-password

Base de datos PostgreSQL

May soporta PostgreSQL además de SQLite. Define DATABASE_URL con la cadena de conexión PostgreSQL en docker-compose.yml o .env. Asegúrate de que el contenedor tenga conectividad de red al servidor de base de datos.

DATABASE_URL=postgresql://user:password@host:5432/may

Clave secreta de sesión (SECRET_KEY)

Si no se define, May genera una al primer arranque y la guarda en data/.secret_key para persistir sesiones tras reinicios. Define SECRET_KEY en .env (junto a config.py) o en docker-compose.yml si quieres gestionarla tú o compartir sesiones entre varias instancias detrás de un balanceador.

SECRET_KEY=your-secure-random-string

Personalización de assets frontend (Tailwind, HTMX)

Por defecto Tailwind carga desde /static/vendor/tailwindcss.js y cae a CDN si falta. Se puede sobrescribir con TAILWIND_ASSET_URL y TAILWIND_CDN_URL. HTMX usa CDN configurable con HTMX_CDN_URL.

TAILWIND_ASSET_URL=/static/vendor/tailwindcss.js
TAILWIND_CDN_URL=https://cdn.tailwindcss.com
HTMX_CDN_URL=https://unpkg.com/[email protected]

Compilación de traducciones

Los archivos .mo son artefactos de compilación. En Docker se compilan al construir la imagen. En instalación manual, ejecuta pybabel compile -d app/translations tras editar archivos .po. La app recompila automáticamente catálogos obsoletos al iniciar si el directorio es escribible.

pybabel compile -d app/translations

Gestión y mantenimiento

Actualización de la imagen Docker

Descarga la última imagen y recrea el contenedor preservando el volumen de datos. Docker Compose facilita el proceso.

docker compose pull
docker compose up -d

Copia de seguridad de datos

El volumen may_data contiene la base de datos SQLite, uploads, imágenes de vehículos y la clave secreta. Realiza copias de seguridad del volumen o exporta desde la interfaz (JSON/ZIP) periódicamente.

docker run –rm -v may_data:/data -v $(pwd):/backup alpine tar czf /backup/may_backup_$(date +%F).tar.gz -C /data .

Visualización de logs

Consulta los logs del contenedor para diagnosticar problemas o recuperar la contraseña inicial de admin.

docker logs may
# Seguimiento en tiempo real
docker logs -f may

Reinicio del contenedor

Reinicia el servicio sin recrear el contenedor.

docker compose restart may

Migración de SQLite a PostgreSQL

No hay herramienta de migración automática documentada. La opción recomendada es exportar todo (JSON/ZIP) desde la interfaz, configurar PostgreSQL en una nueva instancia y restaurar el respaldo.

# 1. Exportar desde la UI: Settings > Integrations > Export Data
# 2. Configurar DATABASE_URL=postgresql://… en nueva instancia
# 3. Importar: Settings > Integrations > Import Data > Restore May Backup

Stack técnico

  • Backend: Python 3.12 / Flask
  • Base de datos: SQLite (por defecto) / PostgreSQL
  • Frontend: Tailwind CSS, HTMX, Chart.js
  • Servidor WSGI: Gunicorn (2 workers, 4 hilos)
  • Contenedor: Docker (python:3.12-slim), gosu para drop de privilegios
  • Notificaciones: SMTP, ntfy, Pushover, Webhooks
  • Generación PDF: WeasyPrint (requiere libpango, libgdk-pixbuf)
  • Internacionalización: Babel (gettext), 24 idiomas
  • PWA: Service Worker, manifest, capacidades offline
  • Salud: Healthcheck HTTP en /health cada 30s

Apoya el canal GENBYTE

Sígueme en mis redes sociales

Dejar un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *