diff --git a/.env.easypanel.example b/.env.easypanel.example new file mode 100644 index 000000000..556b1a9fb --- /dev/null +++ b/.env.easypanel.example @@ -0,0 +1,86 @@ +# Variables de entorno para LibreTime en EasyPanel +# Copia este archivo como .env y ajusta los valores según tu configuración + +# ====================== +# CONFIGURACIÓN GENERAL +# ====================== + +# Versión de LibreTime a usar (latest para la más reciente) +LIBRETIME_VERSION=latest + +# URL pública de tu instalación (REQUERIDO - cambia por tu dominio) +LIBRETIME_GENERAL_PUBLIC_URL=https://tu-dominio.com + +# Ruta al archivo de configuración de LibreTime +LIBRETIME_CONFIG_FILEPATH=./config.local.yml + +# Activar modo debug (solo para desarrollo) +LIBRETIME_DEBUG=false + +# ====================== +# CONFIGURACIÓN DE PUERTOS PARA EASYPANEL +# ====================== + +# Puerto para Nginx (interfaz web) +NGINX_PORT=8080 + +# Puerto para Icecast (streaming) +ICECAST_PORT=8000 + +# Puerto para Liquidsoap Harbor (input de audio) +LIQUIDSOAP_HARBOR_PORT=8001 + +# Puerto para Liquidsoap Telnet (control) +LIQUIDSOAP_TELNET_PORT=8002 + +# ====================== +# BASE DE DATOS POSTGRESQL +# ====================== + +# Usuario de la base de datos +POSTGRES_USER=libretime + +# Contraseña de la base de datos (CAMBIA ESTO) +POSTGRES_PASSWORD=tu_password_seguro_aqui + +# Nombre de la base de datos +POSTGRES_DB=libretime + +# ====================== +# RABBITMQ (MESSAGE BROKER) +# ====================== + +# Virtual host de RabbitMQ +RABBITMQ_DEFAULT_VHOST=/libretime + +# Usuario de RabbitMQ +RABBITMQ_DEFAULT_USER=libretime + +# Contraseña de RabbitMQ (CAMBIA ESTO) +RABBITMQ_DEFAULT_PASS=tu_password_rabbitmq_aqui + +# ====================== +# ICECAST (SERVIDOR DE STREAMING) +# ====================== + +# Contraseña para fuentes de audio (CAMBIA ESTO) +ICECAST_SOURCE_PASSWORD=tu_source_password_aqui + +# Contraseña de administrador de Icecast (CAMBIA ESTO) +ICECAST_ADMIN_PASSWORD=tu_admin_password_aqui + +# Contraseña para relay de Icecast (CAMBIA ESTO) +ICECAST_RELAY_PASSWORD=tu_relay_password_aqui + +# Usuario administrador de Icecast +ICECAST_ADMIN_USER=admin + +# Hostname de Icecast (tu dominio sin http/https) +ICECAST_HOSTNAME=tu-dominio.com + +# ====================== +# CONFIGURACIÓN DE NGINX +# ====================== + +# Número de procesos worker de Nginx +NGINX_WORKER_PROCESSES=auto \ No newline at end of file diff --git a/README.easypanel.md b/README.easypanel.md new file mode 100644 index 000000000..39428f3aa --- /dev/null +++ b/README.easypanel.md @@ -0,0 +1,206 @@ +# LibreTime para EasyPanel + +Esta guía te ayudará a desplegar LibreTime en EasyPanel usando Docker Compose. + +## 🚀 Instalación Rápida + +### 1. Preparar archivos + +1. Copia `docker-compose.easypanel.yml` a tu proyecto en EasyPanel +2. Copia `.env.easypanel.example` como `.env` y configura las variables +3. Copia `config.local.easypanel.yml` como `config.local.yml` y ajusta la configuración + +### 2. Configurar variables de entorno + +Edita el archivo `.env` con tus valores: + +```bash +# URL pública (REQUERIDO) +LIBRETIME_GENERAL_PUBLIC_URL=https://tu-dominio.com + +# Contraseñas (CAMBIA ESTOS VALORES) +POSTGRES_PASSWORD=tu_password_muy_seguro +RABBITMQ_DEFAULT_PASS=otra_password_segura +ICECAST_SOURCE_PASSWORD=password_para_fuentes +ICECAST_ADMIN_PASSWORD=password_admin_icecast + +# Configuración de dominio +ICECAST_HOSTNAME=tu-dominio.com +``` + +### 3. Configurar LibreTime + +Edita `config.local.yml`: + +```yaml +general: + public_url: https://tu-dominio.com + api_key: "genera-una-clave-api-segura-de-al-menos-64-caracteres" + secret_key: "genera-una-clave-secreta-django-de-al-menos-50-caracteres" + +database: + password: tu_password_muy_seguro # Debe coincidir con .env + +rabbitmq: + password: otra_password_segura # Debe coincidir con .env +``` + +### 4. Generar claves seguras + +Puedes generar claves seguras usando: + +```bash +# Para API key (64 caracteres) +openssl rand -hex 32 + +# Para Django secret key (50 caracteres) +openssl rand -base64 50 +``` + +## 📋 Configuración en EasyPanel + +### Servicios y Puertos + +| Servicio | Puerto | Descripción | +|----------|--------|-------------| +| nginx | 8080 | Interfaz web principal | +| icecast | 8000 | Servidor de streaming | +| liquidsoap | 8001 | Input de audio (Harbor) | +| liquidsoap | 8002 | Control Telnet | + +### Volúmenes Persistentes + +Los siguientes volúmenes necesitan ser persistentes: + +- `postgres_data`: Datos de la base de datos PostgreSQL +- `libretime_storage`: Archivos de audio y configuración +- `libretime_playout`: Cache y archivos temporales de playout + +### Configuración de Red + +En EasyPanel, asegúrate de: + +1. **Exponer puertos**: 8080 (web) y 8000 (streaming) +2. **Configurar dominio**: Apuntar tu dominio al puerto 8080 +3. **SSL/TLS**: Activar HTTPS en EasyPanel para el puerto 8080 + +## 🔧 Configuración Avanzada + +### Variables de Entorno Opcionales + +```bash +# Versión específica de LibreTime +LIBRETIME_VERSION=3.0.2 + +# Configuración de Nginx +NGINX_WORKER_PROCESSES=2 + +# Modo debug (solo para desarrollo) +LIBRETIME_DEBUG=true +``` + +### Healthchecks + +El docker-compose incluye healthchecks para: +- PostgreSQL: Verifica conexión a la base de datos +- RabbitMQ: Verifica conectividad del puerto +- Dependencias: Los servicios esperan a que las dependencias estén saludables + +### Configuración de Streaming + +Para configurar streams adicionales, edita `config.local.yml`: + +```yaml +stream: + outputs: + icecast: + - enabled: true + host: icecast + port: 8000 + mount: main + source_password: tu_source_password_aqui + audio: + format: mp3 + bitrate: 128 + - enabled: true + host: icecast + port: 8000 + mount: hq + source_password: tu_source_password_aqui + audio: + format: mp3 + bitrate: 320 +``` + +## 🔐 Seguridad + +### Contraseñas Seguras + +- Usa contraseñas únicas de al menos 16 caracteres +- Combina letras, números y símbolos +- Nunca uses las contraseñas por defecto en producción + +### Firewall + +- Solo expón los puertos necesarios (8080, 8000) +- Considera usar un firewall adicional +- Configura rate limiting si es posible + +### Actualizaciones + +- Mantén LibreTime actualizado: `LIBRETIME_VERSION=latest` +- Revisa regularmente las actualizaciones de seguridad +- Haz backups regulares de los volúmenes + +## 🐛 Troubleshooting + +### Servicios no inician + +1. Verifica las variables de entorno en `.env` +2. Comprueba los logs: `docker-compose logs [servicio]` +3. Verifica que los volúmenes tengan permisos correctos + +### No se puede acceder a la interfaz web + +1. Verifica que el puerto 8080 esté expuesto +2. Comprueba la configuración de dominio en EasyPanel +3. Verifica `LIBRETIME_GENERAL_PUBLIC_URL` en `.env` + +### Problemas de streaming + +1. Verifica las contraseñas de Icecast +2. Comprueba que el puerto 8000 esté accesible +3. Verifica la configuración de `stream.outputs` en `config.local.yml` + +### Base de datos no conecta + +1. Verifica `POSTGRES_PASSWORD` en `.env` +2. Comprueba que coincida con `database.password` en `config.local.yml` +3. Verifica que el volumen `postgres_data` tenga permisos correctos + +## 📚 Enlaces Útiles + +- [Documentación oficial de LibreTime](https://libretime.org/docs/) +- [Configuración avanzada](https://libretime.org/docs/admin-manual/setup/configuration/) +- [GitHub de LibreTime](https://github.com/libretime/libretime) +- [Documentación de EasyPanel](https://easypanel.io/docs) + +## 🔄 Comandos Útiles + +```bash +# Ver logs de todos los servicios +docker-compose -f docker-compose.easypanel.yml logs + +# Ver logs de un servicio específico +docker-compose -f docker-compose.easypanel.yml logs nginx + +# Reiniciar un servicio +docker-compose -f docker-compose.easypanel.yml restart api + +# Actualizar servicios +docker-compose -f docker-compose.easypanel.yml pull +docker-compose -f docker-compose.easypanel.yml up -d + +# Backup de la base de datos +docker-compose -f docker-compose.easypanel.yml exec postgres pg_dump -U libretime libretime > backup.sql +``` \ No newline at end of file diff --git a/config.local.easypanel.yml b/config.local.easypanel.yml new file mode 100644 index 000000000..57ae916d7 --- /dev/null +++ b/config.local.easypanel.yml @@ -0,0 +1,155 @@ +# Configuración de LibreTime para EasyPanel +# Ver documentación completa: https://libretime.org/docs/admin-manual/setup/configuration/ + +general: + # URL pública de tu instalación (REQUERIDO) + # Cambia esto por tu dominio real + public_url: https://tu-dominio.com + + # Clave de autenticación interna de la API (REQUERIDO) + # Genera una clave segura aleatoria + api_key: "tu-api-key-segura-aqui-64-caracteres-minimo-para-seguridad-optima" + + # Clave secreta de Django (REQUERIDO) + # Genera una clave secura aleatoria + secret_key: "tu-secret-key-muy-segura-aqui-minimo-50-caracteres-para-django" + + # Lista de orígenes permitidos para CORS + # El origen de public_url se incluye automáticamente + allowed_cors_origins: [] + + # Zona horaria del servidor + # Usa una clave válida de la base de datos IANA + timezone: UTC + + # Horas de cache anticipado para archivos de medios + cache_ahead_hours: 1 + + # Adaptador de autenticación para el servicio legacy + auth: local + +storage: + # Ruta del directorio de almacenamiento + # Debe coincidir con el volumen montado en Docker + path: /srv/libretime + +database: + # Hostname del servidor PostgreSQL + # Debe coincidir con el nombre del servicio en docker-compose + host: postgres + + # Puerto del servidor PostgreSQL + port: 5432 + + # Nombre de la base de datos + name: libretime + + # Usuario de la base de datos + user: libretime + + # Contraseña de la base de datos + # Debe coincidir con POSTGRES_PASSWORD en las variables de entorno + password: tu_password_seguro_aqui + +rabbitmq: + # Hostname del servidor RabbitMQ + # Debe coincidir con el nombre del servicio en docker-compose + host: rabbitmq + + # Puerto del servidor RabbitMQ + port: 5672 + + # Virtual host de RabbitMQ + vhost: /libretime + + # Usuario de RabbitMQ + user: libretime + + # Contraseña de RabbitMQ + # Debe coincidir con RABBITMQ_DEFAULT_PASS en las variables de entorno + password: tu_password_rabbitmq_aqui + +# Configuración de Liquidsoap +liquidsoap: + # Hostname donde Liquidsoap escucha conexiones + server_listen_address: liquidsoap + + # Puerto para el servidor Liquidsoap + server_listen_port: 1234 + + # Puerto para conexiones Harbor (input de audio) + harbor_listen_port: 8001 + +# Configuración de streaming +stream: + inputs: + # Configuración para input principal + main: + # Puerto donde Liquidsoap escucha el input principal + port: 8001 + # Contraseña para el input (opcional) + mount: main + + # Configuración para input de DJ/Show + show: + port: 8002 + mount: show + + outputs: + # Configuración para output a Icecast + icecast: + - enabled: true + # Hostname del servidor Icecast + host: icecast + port: 8000 + # Punto de montaje en Icecast + mount: libretime + # Contraseña de fuente (debe coincidir con ICECAST_SOURCE_PASSWORD) + source_password: tu_source_password_aqui + # Configuración de audio + audio: + format: mp3 + bitrate: 128 + # Metadatos + name: "LibreTime Radio" + description: "LibreTime Radio Stream" + website: "https://tu-dominio.com" + genre: "Various" + +# Configuración de servicios +services: + # Configuración del analizador de archivos + analyzer: + # Tiempo de espera para análisis de archivos (segundos) + timeout: 60 + + # Configuración del worker + worker: + # Número de procesos worker + processes: 1 + + # Configuración del playout + playout: + # Configuración de Liquidsoap + liquidsoap_host: liquidsoap + liquidsoap_port: 1234 + +# Configuración de logging +logging: + # Nivel de logging (DEBUG, INFO, WARNING, ERROR, CRITICAL) + level: INFO + + # Configuración de logs para diferentes componentes + loggers: + api: + level: INFO + legacy: + level: INFO + playout: + level: INFO + liquidsoap: + level: INFO + worker: + level: INFO + analyzer: + level: INFO \ No newline at end of file diff --git a/docker-compose.easypanel.yml b/docker-compose.easypanel.yml new file mode 100644 index 000000000..ac790babd --- /dev/null +++ b/docker-compose.easypanel.yml @@ -0,0 +1,176 @@ +# LibreTime Docker Compose para EasyPanel +# Basado en el docker-compose oficial de LibreTime +# Optimizado para despliegue en EasyPanel + +services: + # Base de datos PostgreSQL + postgres: + image: postgres:15 + restart: unless-stopped + environment: + POSTGRES_USER: ${POSTGRES_USER:-libretime} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-libretime} + POSTGRES_DB: ${POSTGRES_DB:-libretime} + volumes: + - postgres_data:/var/lib/postgresql/data + healthcheck: + test: ["CMD-SHELL", "pg_isready -U ${POSTGRES_USER:-libretime}"] + interval: 30s + timeout: 10s + retries: 3 + + # Message broker RabbitMQ + rabbitmq: + image: rabbitmq:3.13-alpine + restart: unless-stopped + environment: + RABBITMQ_DEFAULT_VHOST: ${RABBITMQ_DEFAULT_VHOST:-/libretime} + RABBITMQ_DEFAULT_USER: ${RABBITMQ_DEFAULT_USER:-libretime} + RABBITMQ_DEFAULT_PASS: ${RABBITMQ_DEFAULT_PASS:-libretime} + healthcheck: + test: ["CMD-SHELL", "rabbitmq-diagnostics check_port_connectivity"] + interval: 30s + timeout: 10s + retries: 3 + + # API de LibreTime + api: + image: ghcr.io/libretime/libretime-api:${LIBRETIME_VERSION:-latest} + restart: unless-stopped + init: true + ulimits: + nofile: 1024 + depends_on: + postgres: + condition: service_healthy + rabbitmq: + condition: service_healthy + environment: + LIBRETIME_GENERAL_PUBLIC_URL: ${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080} + LIBRETIME_DEBUG: ${LIBRETIME_DEBUG:-false} + volumes: + - ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro + - libretime_storage:/srv/libretime + + # Aplicación Legacy de LibreTime + legacy: + image: ghcr.io/libretime/libretime-legacy:${LIBRETIME_VERSION:-latest} + restart: unless-stopped + init: true + ulimits: + nofile: 1024 + depends_on: + postgres: + condition: service_healthy + rabbitmq: + condition: service_healthy + volumes: + - ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro + - libretime_storage:/srv/libretime + + # Servidor web Nginx + nginx: + image: ghcr.io/libretime/libretime-nginx:${LIBRETIME_VERSION:-latest} + restart: unless-stopped + depends_on: + - legacy + - api + ports: + - "${NGINX_PORT:-8080}:8080" + volumes: + - libretime_storage:/srv/libretime:ro + environment: + - NGINX_WORKER_PROCESSES=${NGINX_WORKER_PROCESSES:-auto} + + # Servidor de streaming Icecast + icecast: + image: ghcr.io/libretime/icecast:2.4.4 + restart: unless-stopped + ports: + - "${ICECAST_PORT:-8000}:8000" + environment: + ICECAST_SOURCE_PASSWORD: ${ICECAST_SOURCE_PASSWORD:-hackme} + ICECAST_ADMIN_PASSWORD: ${ICECAST_ADMIN_PASSWORD:-hackme} + ICECAST_RELAY_PASSWORD: ${ICECAST_RELAY_PASSWORD:-hackme} + ICECAST_ADMIN_USER: ${ICECAST_ADMIN_USER:-admin} + ICECAST_HOSTNAME: ${ICECAST_HOSTNAME:-localhost} + + # Servicio de playout + playout: + image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest} + restart: unless-stopped + init: true + ulimits: + nofile: 1024 + depends_on: + rabbitmq: + condition: service_healthy + volumes: + - ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro + - libretime_playout:/app + environment: + LIBRETIME_GENERAL_PUBLIC_URL: ${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080} + + # Liquidsoap para streaming + liquidsoap: + image: ghcr.io/libretime/libretime-playout:${LIBRETIME_VERSION:-latest} + command: /usr/local/bin/libretime-liquidsoap + restart: unless-stopped + init: true + ulimits: + nofile: 1024 + depends_on: + rabbitmq: + condition: service_healthy + ports: + - "${LIQUIDSOAP_HARBOR_PORT:-8001}:8001" + - "${LIQUIDSOAP_TELNET_PORT:-8002}:8002" + volumes: + - ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro + - libretime_playout:/app + environment: + LIBRETIME_GENERAL_PUBLIC_URL: ${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080} + + # Worker para tareas en background + worker: + image: ghcr.io/libretime/libretime-worker:${LIBRETIME_VERSION:-latest} + restart: unless-stopped + init: true + ulimits: + nofile: 1024 + depends_on: + rabbitmq: + condition: service_healthy + volumes: + - ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro + - libretime_storage:/srv/libretime + environment: + LIBRETIME_GENERAL_PUBLIC_URL: ${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080} + + # Analyzer para análisis de archivos de audio + analyzer: + image: ghcr.io/libretime/libretime-analyzer:${LIBRETIME_VERSION:-latest} + restart: unless-stopped + init: true + ulimits: + nofile: 1024 + depends_on: + rabbitmq: + condition: service_healthy + volumes: + - ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro + - libretime_storage:/srv/libretime + +# Volúmenes persistentes +volumes: + postgres_data: + driver: local + libretime_storage: + driver: local + libretime_playout: + driver: local + +# Red personalizada (opcional para EasyPanel) +networks: + default: + name: libretime_network \ No newline at end of file