feat(easypanel): implement config generator and update docker-compose for EasyPanel integration
Some checks are pending
Container / meta (analyzer) (push) Waiting to run
Container / meta (api) (push) Waiting to run
Container / meta (legacy) (push) Waiting to run
Container / meta (nginx) (push) Waiting to run
Container / meta (playout) (push) Waiting to run
Container / meta (worker) (push) Waiting to run
Container / build (push) Blocked by required conditions
Project / pre-commit (push) Waiting to run
Project / test-tools (push) Waiting to run
Release-Please / release-please (push) Waiting to run

This commit is contained in:
Cesar Jhoanny Mendivil Rubio 2025-10-01 17:16:04 -07:00
parent c47f4c2e4c
commit ac2806e2f6
11 changed files with 537 additions and 41 deletions

View File

@ -50,10 +50,9 @@ services:
- postgres - postgres
- rabbitmq - rabbitmq
environment: environment:
LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml
LIBRETIME_DEBUG: ${LIBRETIME_DEBUG:-false} LIBRETIME_DEBUG: ${LIBRETIME_DEBUG:-false}
volumes: volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro - libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime - libretime_storage:/srv/libretime
legacy: legacy:
@ -65,7 +64,7 @@ services:
environment: environment:
LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml
volumes: volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro - libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime - libretime_storage:/srv/libretime
nginx: nginx:
@ -98,7 +97,7 @@ services:
depends_on: depends_on:
- rabbitmq - rabbitmq
volumes: volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro - libretime_config:/etc/libretime:ro
- libretime_playout:/app - libretime_playout:/app
environment: environment:
LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml
@ -114,7 +113,7 @@ services:
- "${LIQUIDSOAP_HARBOR_PORT:-8001}:8001" - "${LIQUIDSOAP_HARBOR_PORT:-8001}:8001"
- "${LIQUIDSOAP_TELNET_PORT:-8002}:8002" - "${LIQUIDSOAP_TELNET_PORT:-8002}:8002"
volumes: volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro - libretime_config:/etc/libretime:ro
- libretime_playout:/app - libretime_playout:/app
environment: environment:
LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml
@ -125,7 +124,7 @@ services:
depends_on: depends_on:
- rabbitmq - rabbitmq
volumes: volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro - libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime - libretime_storage:/srv/libretime
environment: environment:
LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml
@ -136,8 +135,22 @@ services:
depends_on: depends_on:
- rabbitmq - rabbitmq
volumes: volumes:
- ${LIBRETIME_CONFIG_FILEPATH:-./config.local.yml}:/etc/libretime/config.yml:ro - libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime - libretime_storage:/srv/libretime
# Generador de configuración para escribir config.yml en el volumen libretime_config
config-generator:
image: alpine:3.18
restart: "no"
entrypoint: ["/bin/sh","/tools/easypanel-config-generator.sh"]
volumes:
- libretime_config:/config
- ./tools:/tools:ro
healthcheck:
test: ["CMD-SHELL","test -f /config/config.yml"]
interval: 2s
timeout: 2s
retries: 10
environment: environment:
LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml LIBRETIME_CONFIG_FILEPATH: /etc/libretime/config.yml
@ -148,3 +161,8 @@ volumes:
driver: local driver: local
libretime_playout: libretime_playout:
driver: local driver: local
# Volumen para la configuración generada por el panel
libretime_config:
driver: local

19
easypanel/README.md Normal file
View File

@ -0,0 +1,19 @@
# LibreTime (EasyPanel)
Este directorio contiene metadatos y un script de actualización en el estilo que usa EasyPanel para instalar un servicio desde un repositorio.
Qué hace:
- `update.sh` copia `docker-compose.easypanel.yml` a `./code/docker-compose.yml` y elimina `container_name` y `ports` para que el `docker-compose` resultante sea compatible con EasyPanel.
Cómo funciona (resumen):
- EasyPanel suele clonar el repo en una carpeta temporal, ejecutar `update.sh` y luego usar `./code/docker-compose.yml` como el `compose` a ejecutar.
Requisitos/Notas:
- `update.sh` usa utilidades estándar de shell y `perl` (normalmente disponible en sistemas UNIX). Si tu entorno no tiene `perl`, el script puede adaptarse a `python`.
- Revisa y completa las variables de entorno requeridas por `docker-compose.easypanel.yml` (p. ej. secretos: `POSTGRES_PASSWORD`, `RABBITMQ_DEFAULT_PASS`, etc.) desde la UI de EasyPanel.
Siguientes pasos recomendados:
- (Opcional) Añadir un `update.js` si prefieres implementar clonación/actualizaciones con las utilidades de EasyPanel (no obligatorio).
- (Opcional) Añadir un `update.js` si prefieres implementar clonación/actualizaciones con las utilidades de EasyPanel (no obligatorio). Este repo incluye `easypanel/update.js` que realiza la misma función que `update.sh` usando Node.js.
- (Opcional) Añadir un archivo `README.md` con la lista de variables que EasyPanel debe exponer en la interfaz de instalación.

View File

@ -0,0 +1,199 @@
version: "3.9"
# LibreTime Docker Compose (EasyPanel-ready)
# Esta versión está pensada para usarse desde un repositorio en EasyPanel.
# Principios:
# - No almacenar secretos en archivos del repo: EasyPanel proporcionará los valores
# mediante variables/secretos de entorno.
# - Un servicio `config-generator` genera `/config/config.yml` dentro del volumen
# `libretime_config` a partir de variables de entorno. Los servicios montan ese
# volumen en `/etc/libretime`.
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}
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:-4.5}
restart: unless-stopped
init: true
ulimits:
nofile: 1024
depends_on:
postgres:
condition: service_healthy
rabbitmq:
condition: service_healthy
config-generator:
condition: service_healthy
environment:
LIBRETIME_GENERAL_PUBLIC_URL: ${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080}
LIBRETIME_DEBUG: ${LIBRETIME_DEBUG:-false}
volumes:
- libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime
# Aplicación Legacy de LibreTime
legacy:
image: ghcr.io/libretime/libretime-legacy:${LIBRETIME_VERSION:-4.5}
restart: unless-stopped
init: true
ulimits:
nofile: 1024
depends_on:
postgres:
condition: service_healthy
rabbitmq:
condition: service_healthy
config-generator:
condition: service_healthy
volumes:
- libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime
# Servidor web Nginx
nginx:
image: ghcr.io/libretime/libretime-nginx:${LIBRETIME_VERSION:-4.5}
restart: unless-stopped
depends_on:
- legacy
- api
volumes:
- libretime_storage:/srv/libretime:ro
- ./docker/nginx/default.conf:/etc/nginx/conf.d/default.conf: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
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:-4.5}
restart: unless-stopped
init: true
ulimits:
nofile: 1024
depends_on:
rabbitmq:
condition: service_healthy
volumes:
- libretime_config:/etc/libretime: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:-4.5}
command: /usr/local/bin/libretime-liquidsoap
restart: unless-stopped
init: true
ulimits:
nofile: 1024
depends_on:
rabbitmq:
condition: service_healthy
volumes:
- libretime_config:/etc/libretime: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:-4.5}
restart: unless-stopped
init: true
ulimits:
nofile: 1024
depends_on:
rabbitmq:
condition: service_healthy
volumes:
- libretime_config:/etc/libretime: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:-4.5}
restart: unless-stopped
init: true
ulimits:
nofile: 1024
depends_on:
rabbitmq:
condition: service_healthy
volumes:
- libretime_config:/etc/libretime:ro
- libretime_storage:/srv/libretime
# (No se incluye servicio composer; seguir método Docker estándar de LibreTime)
# Generador de configuración (escrito por el panel desde variables/secretos)
config-generator:
image: alpine:3.18
restart: "no"
entrypoint: ["/bin/sh","/tools/easypanel-config-generator.sh"]
volumes:
- libretime_config:/config
- ./tools:/tools:ro
healthcheck:
test: ["CMD-SHELL","test -f /config/config.yml"]
interval: 2s
timeout: 2s
retries: 10
# Volúmenes persistentes
volumes:
postgres_data:
driver: local
libretime_storage:
driver: local
libretime_playout:
driver: local
libretime_config:
driver: local
# Red personalizada (opcional para EasyPanel)
networks:
default:
name: libretime_network

123
easypanel/easypanel.json Normal file
View File

@ -0,0 +1,123 @@
{
"name": "LibreTime",
"slug": "libretime",
"version": "1.0.0",
"description": "LibreTime: sistema de automatización y streaming de radio. Servicio preparado para EasyPanel mediante docker-compose.",
"author": "LibreTime contributors",
"repository": {
"type": "git",
"url": "https://github.com/your-org/your-repo"
},
"update_script": "easypanel/update.js",
"compose_path": "easypanel/code/docker-compose.yml",
"services": {
"notes": "El archivo compose generado tendrá los servicios principales: postgres, rabbitmq, api, legacy, nginx, icecast, playout, liquidsoap, worker, analyzer y config-generator."
},
"env": [
{
"name": "POSTGRES_USER",
"description": "Usuario de la base de datos Postgres",
"required": false,
"secret": false,
"default": "libretime"
},
{
"name": "POSTGRES_PASSWORD",
"description": "Contraseña de Postgres (requerida)",
"required": true,
"secret": true
},
{
"name": "POSTGRES_DB",
"description": "Nombre de la base de datos",
"required": false,
"secret": false,
"default": "libretime"
},
{
"name": "RABBITMQ_DEFAULT_VHOST",
"description": "VHost por defecto para RabbitMQ",
"required": false,
"secret": false,
"default": "/libretime"
},
{
"name": "RABBITMQ_DEFAULT_USER",
"description": "Usuario por defecto para RabbitMQ",
"required": false,
"secret": false,
"default": "libretime"
},
{
"name": "RABBITMQ_DEFAULT_PASS",
"description": "Contraseña de RabbitMQ (requerida)",
"required": true,
"secret": true
},
{
"name": "LIBRETIME_VERSION",
"description": "Versión de las imágenes de LibreTime",
"required": false,
"secret": false,
"default": "4.5"
},
{
"name": "LIBRETIME_GENERAL_PUBLIC_URL",
"description": "URL pública de la instalación",
"required": false,
"secret": false,
"default": "http://localhost:8080"
},
{
"name": "LIBRETIME_DEBUG",
"description": "Habilitar modo debug (true/false)",
"required": false,
"secret": false,
"default": "false"
},
{
"name": "NGINX_PORT",
"description": "Puerto HTTP expuesto por Nginx (opcional si EasyPanel maneja el routing)",
"required": false,
"secret": false,
"default": "8080"
},
{
"name": "ICECAST_PORT",
"description": "Puerto de Icecast",
"required": false,
"secret": false,
"default": "8000"
},
{
"name": "ICECAST_SOURCE_PASSWORD",
"description": "Contraseña de source para Icecast",
"required": false,
"secret": true,
"default": "hackme"
},
{
"name": "ICECAST_ADMIN_PASSWORD",
"description": "Contraseña de admin para Icecast",
"required": false,
"secret": true,
"default": "hackme"
},
{
"name": "ICECAST_RELAY_PASSWORD",
"description": "Contraseña de relay para Icecast",
"required": false,
"secret": true,
"default": "hackme"
},
{
"name": "ICECAST_ADMIN_USER",
"description": "Usuario admin Icecast",
"required": false,
"secret": false,
"default": "admin"
}
],
"notes": "Después de clonar, EasyPanel debe ejecutar el `update_script` y usar el compose generado en `compose_path`. Asegúrate de proveer los secretos marcados como `secret: true` en la UI de EasyPanel.",
"last_updated": "2025-10-01"
}

42
easypanel/update.js Executable file
View File

@ -0,0 +1,42 @@
#!/usr/bin/env node
"use strict";
// update.js - script de utilidad para EasyPanel
// Copia docker-compose.easypanel.yml a ./code/docker-compose.yml y elimina
// container_name y ports para que EasyPanel gestione nombres y puertos.
const fs = require('fs');
const path = require('path');
const SRC = path.resolve(__dirname, '../docker-compose.easypanel.yml');
const DEST_DIR = path.resolve(__dirname, './code');
const DEST = path.join(DEST_DIR, 'docker-compose.yml');
function removeContainerNamesAndPorts(content) {
// Eliminar container_name: <valor> líneas
content = content.replace(/^[ \t]*container_name:[^\n]*\n/gm, '');
// Eliminar bloques de ports:
// ports:\n - "..."\n - ...
content = content.replace(/^[ \t]*ports:[^\n]*\n(?:^[ \t]+-.*\n)*/gim, '');
return content;
}
async function main() {
if (!fs.existsSync(SRC)) {
console.error('ERROR: no se encuentra', SRC);
process.exit(2);
}
if (!fs.existsSync(DEST_DIR)) fs.mkdirSync(DEST_DIR, { recursive: true });
const raw = fs.readFileSync(SRC, 'utf8');
const sanitized = removeContainerNamesAndPorts(raw);
fs.writeFileSync(DEST, sanitized, 'utf8');
console.log('Preparado', DEST);
}
main().catch(err => {
console.error(err);
process.exit(1);
});

45
easypanel/update.sh Executable file
View File

@ -0,0 +1,45 @@
#!/usr/bin/env bash
set -euo pipefail
# Este script prepara el compose para EasyPanel.
# Si Node.js está disponible y existe easypanel/update.js, lo ejecuta.
# De lo contrario, realiza la copia y saneado en bash/perl (fallback).
BASE_DIR="$(cd "$(dirname "$0")" && pwd)"
SRC="$BASE_DIR/../docker-compose.easypanel.yml"
DEST_DIR="$BASE_DIR/code"
DEST="$DEST_DIR/docker-compose.yml"
if command -v node >/dev/null 2>&1 && [ -f "$BASE_DIR/update.js" ]; then
echo "Node.js detectado, ejecutando easypanel/update.js"
# Ejecutar con node (permitirá usar la versión JS en lugar del sed/perl)
node "$BASE_DIR/update.js"
echo "Preparado $DEST para EasyPanel (vía update.js)."
exit 0
fi
echo "Node.js no disponible o easypanel/update.js no encontrado; usando fallback shell copy"
mkdir -p "$DEST_DIR"
if [ ! -f "$SRC" ]; then
echo "ERROR: no se encuentra $SRC"
exit 2
fi
# Copiar
cp "$SRC" "$DEST"
# Eliminar container_name y ports keys (simplemente eliminamos las líneas que contienen 'container_name:' o 'ports:')
# Esto es similar a lo que hacen muchos ejemplos de EasyPanel.
if command -v perl >/dev/null 2>&1; then
perl -0777 -pe "s/^[ \t]*container_name:[^\n]*\n//mg" -i "$DEST"
perl -0777 -pe "s/^[ \t]*ports:[^\n]*\n(?:^[ \t]+-.*\n)*//mg" -i "$DEST"
else
# Fallback con awk/sed si perl no está disponible
# Elimina líneas 'container_name:' y bloques 'ports:' simples
sed -E '/^[ \t]*container_name:/d' -i "" "$DEST" 2>/dev/null || sed -E '/^[ \t]*container_name:/d' -i '$DEST'
awk 'BEGIN{skip=0} /^[ \t]*ports:[ \t]*$/ {skip=1; next} /^[ \t]*[^ \t]/ { if(skip){skip=0} } { if(!skip) print $0 }' "$DEST" > "$DEST.tmp" && mv "$DEST.tmp" "$DEST"
fi
echo "Preparado $DEST para EasyPanel. Revisa variables de entorno en el README y súbelas en la UI de EasyPanel."

35
easypanel/vars.md Normal file
View File

@ -0,0 +1,35 @@
# Variables de entorno / Secretos requeridos para EasyPanel
Lista de variables que el `docker-compose.easypanel.yml` usa y que deberías exponer desde la UI de EasyPanel (Secrets/Environment):
- POSTGRES_USER (opcional, default: libretime)
- POSTGRES_PASSWORD (requerido)
- POSTGRES_DB (opcional, default: libretime)
- RABBITMQ_DEFAULT_VHOST (opcional, default: /libretime)
- RABBITMQ_DEFAULT_USER (opcional, default: libretime)
- RABBITMQ_DEFAULT_PASS (requerido)
- LIBRETIME_VERSION (opcional, default: 4.5)
- LIBRETIME_GENERAL_PUBLIC_URL (opcional, default: http://localhost:8080)
- LIBRETIME_DEBUG (opcional, default: false)
- NGINX_PORT (opcional, default: 8080) <-- Nota: EasyPanel típicamente gestiona mapeos de puertos; puedes dejarlo o permitir que EasyPanel lo reescriba.
- ICECAST_PORT (opcional, default: 8000)
- LIQUIDSOAP_HARBOR_PORT (opcional, default: 8001)
- LIQUIDSOAP_TELNET_PORT (opcional, default: 8002)
- ICECAST_SOURCE_PASSWORD (opcional, default: hackme)
- ICECAST_ADMIN_PASSWORD (opcional, default: hackme)
- ICECAST_RELAY_PASSWORD (opcional, default: hackme)
- ICECAST_ADMIN_USER (opcional, default: admin)
- ICECAST_HOSTNAME (opcional, default: localhost)
- NGINX_WORKER_PROCESSES (opcional, default: auto)
Notas:
- Marca `POSTGRES_PASSWORD` y `RABBITMQ_DEFAULT_PASS` como secretos en EasyPanel.
- El `config-generator` espera que estas variables existan para generar `/config/config.yml`.
- Si quieres que EasyPanel maneje el mapeo de puertos, deja `ports` en el `docker-compose.easypanel.yml` y el `update.sh` los eliminará cuando prepare `./code/docker-compose.yml` para la plataforma (esto sigue el patrón del repositorio oficial de EasyPanel).
Sugerencia: revisa los valores por defecto y decide qué variables quieres obligatorias en la UI de instalación.

0
scripts/docker-local-up.sh Normal file → Executable file
View File

View File

@ -26,9 +26,8 @@ if [ -n "${POSTGRES_PASSWORD:-}" ]; then
# Hacer copia de seguridad si existe # Hacer copia de seguridad si existe
if [ -f ./config.local.yml ]; then if [ -f ./config.local.yml ]; then
ts=$(date +%Y%m%d%H%M%S) ts=$(date +%Y%m%d%H%M%S)
mkdir -p ./backups cp ./config.local.yml ./config.local.yml.bak.$ts
cp ./config.local.yml ./backups/config.local.yml.bak.$ts echo "Backup creado: ./config.local.yml.bak.$ts"
echo "Backup creado: ./backups/config.local.yml.bak.$ts"
fi fi
awk -v pw="$POSTGRES_PASSWORD" ' awk -v pw="$POSTGRES_PASSWORD" '

25
tmp_config/config.yml Normal file
View File

@ -0,0 +1,25 @@
general:
public_url: "https://libretime.example.com"
api_key: ""
secret_key: ""
database:
host: postgres
port: 5432
name: libretime
user: libretime
password: "secretpass"
rabbitmq:
host: rabbitmq
port: 5672
vhost: /libretime
user: libretime
password: "rabbitpass"
icecast:
source_password: "srcpass"
admin_password: "adminpass"
relay_password: "changeme"
admin_user: "admin"
hostname: "localhost"

View File

@ -1,51 +1,32 @@
#!/bin/sh #!/bin/sh
# Generador de config para EasyPanel # Generador de config para EasyPanel
# Lee variables de entorno y escribe /config/config.yml # Lee variables de entorno y escribe /config/config.yml de forma atómica
set -eu set -eu
CONFIG_PATH=/config/config.yml CONFIG_PATH=/config/config.yml
TMP_PATH=/config/config.yml.tmp
cat > "$CONFIG_PATH" <<'EOF' # Generar usando heredoc sin comillas para permitir expansión de variables
cat > "$TMP_PATH" <<EOF
general: general:
public_url: "${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080}" public_url: "${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080}"
api_key: "${LIBRETIME_API_KEY:-}" api_key: "${LIBRETIME_API_KEY:-}"
secret_key: "${LIBRETIME_SECRET_KEY:-}" secret_key: "${LIBRETIME_SECRET_KEY:-}"
database: database:
host: ${POSTGRES_HOST:-postgres} host: "${POSTGRES_HOST:-postgres}"
port: ${POSTGRES_PORT:-5432} port: ${POSTGRES_PORT:-5432}
name: ${POSTGRES_DB:-libretime} name: "${POSTGRES_DB:-libretime}"
user: ${POSTGRES_USER:-libretime} user: "${POSTGRES_USER:-libretime}"
password: "${POSTGRES_PASSWORD}" password: "${POSTGRES_PASSWORD:-}"
#!/bin/sh
# Generador de config para EasyPanel
# Lee variables de entorno y escribe /config/config.yml
set -eu
CONFIG_PATH=/config/config.yml
# Usar heredoc sin comillas para permitir expansión de variables
cat > "$CONFIG_PATH" <<EOF
general:
public_url: "${LIBRETIME_GENERAL_PUBLIC_URL:-http://localhost:8080}"
api_key: "${LIBRETIME_API_KEY:-}"
secret_key: "${LIBRETIME_SECRET_KEY:-}"
database:
host: ${POSTGRES_HOST:-postgres}
port: ${POSTGRES_PORT:-5432}
name: ${POSTGRES_DB:-libretime}
user: ${POSTGRES_USER:-libretime}
password: "${POSTGRES_PASSWORD}"
rabbitmq: rabbitmq:
host: ${RABBITMQ_HOST:-rabbitmq} host: "${RABBITMQ_HOST:-rabbitmq}"
port: ${RABBITMQ_PORT:-5672} port: ${RABBITMQ_PORT:-5672}
vhost: ${RABBITMQ_DEFAULT_VHOST:-/libretime} vhost: "${RABBITMQ_DEFAULT_VHOST:-/libretime}"
user: ${RABBITMQ_DEFAULT_USER:-libretime} user: "${RABBITMQ_DEFAULT_USER:-libretime}"
password: "${RABBITMQ_DEFAULT_PASS}" password: "${RABBITMQ_DEFAULT_PASS:-}"
icecast: icecast:
source_password: "${ICECAST_SOURCE_PASSWORD:-changeme}" source_password: "${ICECAST_SOURCE_PASSWORD:-changeme}"
@ -55,6 +36,16 @@ icecast:
hostname: "${ICECAST_HOSTNAME:-localhost}" hostname: "${ICECAST_HOSTNAME:-localhost}"
EOF EOF
# Validación mínima: debe contener la clave 'general:'
if ! grep -q '^general:' "$TMP_PATH"; then
echo "ERROR: config generation failed (missing 'general:')"
rm -f "$TMP_PATH"
exit 1
fi
# Mover de forma atómica
mv "$TMP_PATH" "$CONFIG_PATH"
echo "wrote $CONFIG_PATH" echo "wrote $CONFIG_PATH"
# Mantener el contenedor en ejecución para que dependientes puedan verificar salud # Mantener el contenedor en ejecución para que dependientes puedan verificar salud