Ya le he dedicado un rato a mi #DomingoDeSelfhosted y he de decir que ha sido muy productivo.
Gracias al epsiodo de @cacharredando creo haber logrado arreglar el tema del byte-range que tanto problema me dio en el pasado.

Además he podido dar de alta en Apple Podcast el feed de @angelescustodios

Y vuestra mañana que tal?

@cacharredando @angelescustodios

Y para que no se olvide lo hecho queda una entrada en la página web

https://www.papafriki.es/posts/nginx-sidecar-para-castopod/

Arreglar el streaming en Apple Podcasts con Castopod y Caddy

Explicación del problema Tengo alojado en mi servidor Castopod en un contenedor docker. A su vez tengo otro contenedor Caddy para que haga la redirección a Castopd cuando se le solicita el feed o un episodio para no exponer públicamente mi servidor. Todo funcionaba bien menos que en Apple Podcast varios oyentes (aunque sería mejor decir escuchantes) me han comentado que cuando quieren reproducir en algunos reproductores no les dejaba hacerlo via streaming. La explicación técnica la dejaremos para los que saben y yo lo que os hago aqui es una explicación con mis palabras y según lo he comprendido yo. Todo se resume en que hay clientes que le piden el audio al servidor de una forma parcial y otros que le dicen tu dame todo que yo ya me apaño. Y aquí es donde empieza el problema, el que se apaña es capaz de reproducir via streaming aunque le den el fichero de golpe pero el que le pide 1 mb por ejemplo y le dan todo no sabe que hacer y da un error y para la reproducción. Esto se conoce como Range Requests. Existen comandos para imitar la solicitud que se haría y testear el resultado, se hace con un curl. Dejo un ejemplo de curl 1 curl -I -H "Range: bytes=0-1023" https://papafrikifeed.duckdns.org/audio/@PapaFriki/ppf-loterias-y-apuesta-y-el-bono-vicio.mp3 En la salida vereis un HTTP/2 200 si lo ha servido completo y un HTTP/2 206 si lo ha servido de modo parcial, en la petición anterior se le piden los bytes 0-1023 o lo que es lo mismo un kylobite del audio para hacer la prueba. Pues yo lo tenía con un HTTP/2 200 y necesitaba servirlo parcialmente para que, por ejemplo, Apple podcast entre otros clientes pudiera servirlo bien. Solucionando el problema Llegó sin esperarla de la mano de David Marzal que me pasó un episodio del podcast RTS/CTS donde Carlos nos contaba la ingeniosa solución que le dió al mismo problema que tenia yo. Su solución para por montar un contenedor auxiliar con Nginx para que capture las peticiones que se realizan a Castopod de los mp3 y en lugar de servilo Castpod hacerlo este Nginx del que tenemos un control completo. Os dejo el enlace a su podlink https://pod.link/1644614612 Asi que le escribí por mastondon y me facilitó los ficheros. Que mas o menos entendia lo que hacen pero que tuve que explicar a Gemini la situación en la que estaba, como Carlos la había solucionado y que me ayudara a hacerlo en mi instalación de Castopod y Caddy. El resultado fue que lo logré y aqui lo dejo plasmado para compartirlo y para que el día de mañana si tengo que echar mano de él lo encuentre facilmente. Paso 1: En la misma carpeta que uso para desplegar el contenedor de Castopod, junto al docker-compose.yml y las carpetas prpopiaas del programa se crea un fichero llamado nginx_sidecar.conf con el siguiente contenido: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 server { listen 80; server_name _; # Servir audios directamente SIN compresión location /media/ { alias /var/www/castopod/public/media/; gzip off; sendfile on; add_header Accept-Ranges bytes; } # El resto del tráfico se lo devuelve a la App de Castopod location / { proxy_pass http://castopod-app:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-Proto https; } } Paso 2: Modificar el docker-compose.yml hay que añadir el servicio sidecar y compartirle el volumen de media, lo hacemos solo para lectura. 1 2 3 4 5 6 7 8 9 10 11 12 services: nginx-sidecar: image: nginx:alpine container_name: "castopod-nginx-sidecar" volumes: - ./nginx_sidecar.conf:/etc/nginx/conf.d/default.conf - ./media:/var/www/castopod/public/media:ro # Solo lectura networks: - castopod-app ports: - "192.168.1.129:8006:80" # Nuevo puerto de entrada restart: unless-stopped Paso 3: Tuve unos problemas con los permisos de archivos en el Host con errores 403 Forbidden pues Nginx debe poder leer la carpeta de media. Para ello basta con ejecutar los siguientes comandos en el host 1 2 3 4 5 6 # Permite entrar en directorios y leer archivos sudo find /home/pi/docker/castopod/media -type d -exec chmod 755 {} + sudo find /home/pi/docker/castopod/media -type f -exec chmod 644 {} + # Asegura que el usuario del host sea el dueño sudo chown -R pi:pi /home/pi/docker/castopod/media Paso 4: Ajuste en el Caddyfile Toca ahora configurar Caddy para que apunte al puerto 8006 ( u otro que no sea el que usa tu instalación de castopod) y desactivar la compresión para audios: Dejo parte del código tal y como lo tengo implementado yo al menos esto deberá estar en vuestra configuración de caddy, habría que añadirle mas seguridad pero éso no es material de esta entrada. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 papafrikifeed.duckdns.org { # Definimos qué archivos NO deben comprimirse para no romper el streaming (Range Requests) @no_compress { path *.mp3 *.m4a *.ogg *.wav } # Compresión inteligente: Comprime todo excepto los audios encode @no_compress zstd gzip # Enviamos todo el tráfico al Nginx Sidecar (Puerto 8006) # Él decidirá si sirve el MP3 directamente o lo pasa a Castopod reverse_proxy http://192.168.1.129:8006 { header_up X-Real-IP {remote_host} header_up X-Forwarded-Proto https } header Accept-Ranges bytes } Paso 5: Verificando el sistema La prueba de fuego se hace con curl, como ya vimos antes, y buscamos recibir un HTTP 206 en las primeras líneas. 1 curl -I -H "Range: bytes=0-1023" https://papafrikifeed.duckdns.org/audio/@PapaFriki/ppf-loterias-y-apuesta-y-el-bono-vicio.mp3 Si toddo ha ido bien la respuesta va a empezar por HTTP/2 206 y habremos logrado que Apple Podcasts y otros clientes puedan servir el fichero en streaming. Implementar un Nginx Sidecar puede parecer un paso extra en nuestra infraestructura, pero es la diferencia entre tener un servidor que ‘suelta’ archivos y uno que ‘gestiona’ streaming de forma eficiente. Gracias a la solución inspirada por Carlos de RTS/CTS, ahora mis dos feeds, PapaFriki y Ángeles Custodios, son 100% compatibles con el estándar de peticiones parciales (206 Partial Content). Si usas Docker y Caddy, esta es la pieza del puzle que te faltaba para que tu podcast puedan llegar a todos los reproductores. Gracias por el tiempo dedicado a la lectura de la entrada si te surgen dudas y crees que hay cosas que debería explicar más no dudes en ponerte en contacto en mastodon (@[email protected]) o por correo electrónico [email protected] Nos vemos, nos leemos, nos escuchamos… adios!

Papá Friki

@PapaFriki Un workaround (ñapa) en toda regla. Que de posibilidades nos da el SoftwareLibre 🦾
Enhorabuena por solucionarlo.

Por si alguien más tiene este problema y quiere alternativas:

(1) - Instalar Castopod sin docker:
https://blog.castopod.org/castopod-installation-script/

(2) - Cambiar la instalación de un único docker con todo a uno por partes:
https://docs.castopod.org/main/en/getting-started/docker/
Evitando usar la imagen castopod/castopod y usando un docker-compose con varios contenedores: castopod/app + castopod/web-server + mariadb:11.2 + redis:7.2-alpine

(3) - Esperar, ya que Castopod está cambiando su imagen de docker todo-en-uno para arreglar el problema (y de paso cargarse la opción 2 de más arriba):
https://code.castopod.org/adaures/castopod/-/merge_requests/370

Yo aconsejo opción 1 o 3, ahora mismo la 2 no tiene mucho sentido.

Introducing the Castopod Installation Script

Install Castopod with a single command. The official installation script handles all dependencies, SSL certificates, database configuration, and security hardening automatically.

Castopod Blog
@DavidMarzalC @PapaFriki
Vaya, ahora que lo había instalado con la opción 2....
Se rompe??
@zicoxy3 @PapaFriki No creo que se rompa, lo que es posible es que los dos contenedores de la opción 2 no se actualicen. O lo mismo ya no los recomiendan pero les dan un tiempo de mantenimiento. Cuando lo hagan oficial, habrá que ver si documentan como pasar de un modo a otro.
@DavidMarzalC @zicoxy3 @PapaFriki Eso en bare metal no pasa.
@iam @zicoxy3 @PapaFriki Por eso es la opción number 1 
@iam @DavidMarzalC @zicoxy3 @PapaFriki Eso no pasa. Pasan otras cosas, pero eso no.
@lynze @DavidMarzalC @zicoxy3 @PapaFriki Pues cero problemas con lo que sea que pase
@iam @lynze @DavidMarzalC @PapaFriki pero un bare metal no es un vps para tí solo?? enbtonces pasará lo mismo... la instalación es la misma.
@zicoxy3 @lynze @DavidMarzalC @PapaFriki Cuando me refiero a bare metal, es a instalar directo en el disco duro, sin dockers, ni kubernetes, ni nada de eso.
@zicoxy3 @iam @DavidMarzalC @PapaFriki Siendo quisquillosos, un bare metal es una máquina/servidor/PC donde instalar lo que sea. Un VPS no dejaría de ser una máquina virtual.