Tengo unos pantalones, ja ja (II – O de como molar con Docker y montarnos un Navidrome)
Bueno, gentes de Internet, vamos con el primer post de verdad de éste, su humilde vlog de cosas de tecnología mal explicadas pero que funcionan.
Hoy vamos a… montarnos un servidor de streaming de música. Para todos ésos empetreses que seguramente aún tengáis. Y si no tenéis os recomiendo reflexionar sobre qué carallo vais a escuchar como mañana, por el motivo que sea, un banco que quiebra, por ejemplo, chape Spotify o lo que sea que uséis.
Asumo que:
Habéis montado un servidor de alguna clase Ver una consola de Linux no os produce parálisis cerebral
Lo primero que vamos a hacer es instalar docker, luego instalamos docker-compose (ahora vamos) y luego vamos a usar docker-compose para desplegar un servidor de streaming musical.
¡Cómo nos lo vamos a pasar!
Instalación de Docker:
Tres mil guías online hay para hacerlo. Os facilito el tema, si teneis una RaspberryPi podéis leerlo aquí. En un servidor x86, aquí un ejemplo para Debian, si no para la distribución que hayamos decidido instalar.
Ya está. A partir de aquí vamos a seguir usando la consola, pero para las cosas de los contenedores. Más adelante usaremos una herramienta de administración con entorno gráfico, pero de momento no necesitamos más. Lo que si que podemos ir haciendo es una carpeta para meter todos los archivos de configuración de nuestros contenedores. La podéis hacer donde os de la gana. Yo voy a suponer que os habéis hecho una carpeta con nombre /docker y dentro vamos a hacer una carpeta con nombre /data que contendrá una carpeta con nombre /navidrome (que es lo que vamos a instalar en éste ejemplo. Así que os vais a donde sea que queráis tener la carpeta y escribís cinco mandatos de Unix con su enter al final de cada uno para que todo se ejecute guapamente:
mkdir docker
cd docker
mkdir data
cd data
mkdir navidrome
Hala, ya nos hemos hecho las carpetas iniciales. Vamos a mirar lo de usar un contenedor.
A la búsqueda de contenedores
Gentes de Internet, os presento Docker Hub. Docker Hub es una página que funciona como un repositorio de contenedores. Muchos de los contenedores que vamos a usar, cuando el desarrollador acaba de montarlos los pone disponibles desde ahí, lo cual no quiere decir que no los podamos descargar desde otro sitio, pero es un sitio habitual donde buscar contenedores.
Más que nada porque tiene un buscador y nos facilita la vida. Así que vamos a buscar nuestro objeto de deseo de streaming: Navidrome.
Yo he escogido Navidrome porque es lo que uso, pero hay un montón de software de streaming de audio que podéis probar. Subsonic, que es el padre de toda ésta fiesta, sus forks libres LibreSonic y Airsonic (y otros)… hay muchos, luego os enlazo una cosa guay, pero centrándonos en Navidrome, si lo busco en Docker Hub, me encuentro ésto:
Mira, ahí nos sale, en todo lo alto. Si pinchamos en él a ver qué tiene, podemos leer una descripción de qué hace éste software empaquetado y hacia la mitad de la descripción nos encontramos ésto:
# This is just an example. Customize it to your needs.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
ports:
- "4533:4533"
environment:
# Optional: put your config options customization here. Examples:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_BASEURL: ""
volumes:
- "./data:/data"
- "/path/to/your/music/folder:/music:ro"
restart: always
Que ya nos dice el desarrollador que para lo que viene siendo personalizarlo (Navidrome tiene muchas opciones) que toqueteemos el ficherito. En cualquier caso, vamos a empezar por diseccionar lo que nos está diciendo éste fichero.
Éste fichero es un .yaml (un formato) para docker-compose. ¿Qué es docker-compose? Docker-compose es una herramienta con la que desplegar contenedores de Docker (fascinante, epatante, terrible, apocalíptico). En éste fichero de arriba, tenemos sólo un contenedor (Navidrome) pero imaginad que quisiéramos desplegar a la vez un servicio, una base de datos, una base de datos en memoria y un Jesucristo bailongo en formato .gif. Bueno, pues en el mismo fichero podríamos meter los cuatro contenedores que queremos desplegar en vez de ir uno por uno. Una cosa muy guay, vamos.
Leamos línea a línea la movida ésta:
# This is just an example. Customize it to your needs.
version: "3"
services:
De momento, le decimos a docker-compose la versión de docker-compose que queremos usar (la 3) y en la siguiente línea los contenedores que éste fichero de configuración va a lanzar
# This is just an example. Customize it to your needs.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
En el caso de éste docker-compose, sólo tenemos un servicio. El propio Navidrome. Para poder tener nuestro servidor de streaming musical, no necesitamos nada más, pero podría haber más cosas en el mismo fichero.
Dejando dos espacios en la tercera línea, ponemos el nombre del servicio (navidrome:) y a continuación el nombre de la imagen del contenedor que queremos descargar (deluan/navidrome:latest). Lo que hay detrás de los dos puntos es una etiqueta que nos permite, por ejemplo, descargar una versión en concreto o descargar una rama específica de desarrollo. Con «latest» le estamos diciendo que se baje la última versión que tenga disponible.
Si alguien está muy atento a ésta movida igual está pensando que dónde se le dice que se baje algo que ejecute con procesadores ARM si tiene una RaspberryPi o con procesadores x86 si tiene ésa arquitectura. Bueno, como el desarrollador de Navidrome ofrece su contenedor en todas ésas arquitecturas, docker, que es muy listo, va a mirar primero cuál se tiene que bajar y se baja la que toque.
A mi, en los docker-compose, como no uso Kubernetes y no clusterizo servicios (ya hablaremos de ésto) me gusta darle un nombre a los contenedores. Si no le doy ninguno va a coger uno por defecto, pero cosas del TOC, oigan. Puedo usar una entrada más en mi docker-compose de ésta manera:
# This is just an example. Customize it to your needs.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
Evidentemente, para el nombre del contenedor, ponéis lo que os de la gana. Vamos a una parte importante, los puertos.
# This is just an example. Customize it to your needs.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
ports:
- "4533:4533"
Lo que le estamos diciendo aquí a docker-compose es qué puertos de red usar. El desarrollador ha decidido que el puerto por el que su cacharro se va a comunicar es el 4533. Ése es el puerto de funcionamiento del contenedor. Tal y como está escrito el docker-compose le estamos diciendo que use el puerto de nuestra red 4533 («4533:) para comunicarse con el puerto interno 4533 (4533″). Si por ejemplo ése puerto no nos gusta, le tenemos manía o queremos hacer el imbécil podríamos cambiarlo dejando el docker-compose tal que:
# This is just an example. Customize it to your needs.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
ports:
- "666:4533"
Escribiéndo ésa idiotez, el contenedor, evidentemente va a seguir usando su mismo puerto interno ya que se desarrolló así, pero nosotros nos vamos a comunicar con el servicio a través del puerto 666 de nuestra red. Porque sí. Porque escuchamos metal. Porque adoramos la música del mal. O algo.
Bueno, dejemos atrás éste momento bochornoso. Sigamos. Vamos con las variables de entorno.
# This is just an example. Customize it to your needs.
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
ports:
- "666:4533"
environment:
# Optional: put your config options customization here. Examples:
ND_SCANSCHEDULE: 1h
ND_LOGLEVEL: info
ND_BASEURL: ""
Todo lo que haya indentado dentro de environment: son variables que vamos a usar para configurar el contenedor. Éstas las define el desarrollador. Deluan, que es muy cuco y diligente ya nos avisa de que podemos configurar ésto como queramos, así que vamos a echarle un vistazo a su página de documentación.
Todas las opciones que véis ahí se pueden meter como variable de entorno. En lo que llevamos de configuración estamos desplegando un Navidrome que busca cambios en nuestra carpeta de discos cada hora, nos escribe logs con poco nivel de detalle y no hemos definido la url que usaremos para acceder. Digamos que yo quiero que escanee mi colección cada 6 horas, que me cierre la sesión automáticamente a las 24 horas de haber entrado, escriba un log como para quedarme dormido leyéndolo y tengo una url para acceder con nombre https://navimegatron.quieroserpropietario.com y además, quiero que el mensaje de bienvenida que aparezca en mi server de música sea: «Bienvenidos, hijos del rock ‘n roll», bueno, pues modifico mi docker-compose tal que:
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
ports:
- "666:4533"
environment:
TZ: Europe/Madrid
ND_SCANSCHEDULE: 6h
ND_LOGLEVEL: debug
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: "navimegatron.quieroserpropietario.com"
ND_UIWELCOMEMESSAGE: "Bienvenidos, hijos del rock 'n roll"
He añadido una variable más que es la franja horaria, para que luego, si tengo que leer logs no me explote la cabeza. Lo hago en todos mis contenedores y es tan sencillo como poner TZ: Europe/Madrid si estáis en Españita o vuestra zona geográfica que más os seduzca y os plazca
Ya no nos queda casi nada, vamos a por un téma crítico, los volúmenes.
Si se han leído la entrada anterior habíamos quedado en que como nos dé por parar un contenedor, se borra todo lo que hubiése dentro. Excepto aquellas cosas que nosotros le indiquemos que queremos que se guarden en el disco. Éso lo podemos hacer definiendo los volúmenes. Vamos a por ello:
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
ports:
- "666:4533"
environment:
TZ: Europe/Madrid
ND_SCANSCHEDULE: 6h
ND_LOGLEVEL: debug
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: "navimegatron.quieroserpropietario.com"
ND_UIWELCOMEMESSAGE: "Bienvenidos, hijos del rock 'n roll"
volumes:
- "./data:/data"
- "/path/to/your/music/folder:/music:ro"
restart: always
Los volúmenes me los tiene que decir el desarrollador. Yo puedo mapear lo que me de la gana en un contenedor pero es el propio desarrollador el que nos dice qué carpetas debemos persistir en el disco duro. Funciona como lo de los puertos. Lo que está antes de los dos puntos es una carpeta en nuestra máquina, lo que está detrás, una carpeta en el contenedor. Importante. Tenemos que crear en nuestra máquina las carpetas antes de lanzar el docker-compose o le da un parraque y se queda tonto (crea ficheros vacíos en lugar de mapear carpetas). Pero leámoslo detenídamente.
El desarrollador nos dice que su contenedor usa dos carpetas. Una que se llama /data. Donde va a guardar los ficheros de configuración y otra que se llama /music (y que además nos indica que es :ro, es decir que es read only, es decir que es de sólo lectura). Si nos vamos a su página de documentación nos explica que en data escribe el contenedor todas sus cosas para configurarse y en /music echamos dentro nuestros discos.
Nosotros ya teníamos carpetas. Más en concreto en el path /algoentu_maquina/docker/data/navidrome, ¿os acordáis? Bueno, pues vamos a hacer dos más dentro de la carpeta navidrome:
cd /algo_en_tu_maquina/docker/data/navidrome
mkdir data
mkdir music
Y ésas van a ser las carpetas que usemos en docker-compose. Voy a suponer que tu usuario tiene de nombre pepinillo y te has creado ésas carpetas en tu carpeta de home. Aunque se pueden poner rutas relativas, voy a poner en el docker-compose las completas para que quede claro, me queda tal que así:
version: "3"
services:
navidrome:
image: deluan/navidrome:latest
container_name: navimegatron
ports:
- "666:4533"
environment:
TZ: Europe/Madrid
ND_SCANSCHEDULE: 6h
ND_LOGLEVEL: debug
ND_SESSIONTIMEOUT: 24h
ND_BASEURL: "navimegatron.quieroserpropietario.com"
ND_UIWELCOMEMESSAGE: "Bienvenidos, hijos del rock 'n roll"
volumes:
- "/home/pepinillo/docker/data/navidrome/data:/data"
- "/home/pepinillo/docker/data/navidrome/music:/music:ro"
restart: always
¡Oeeeeeeeeeeeeeee oeeeeeeeeeeeeeeeeeee ya hemos acabado!
Vale, pero antes de fliparnos, ¿qué hemos hecho? Hemos definido las carpetas donde el contenedor va a guardar algunos ficheros. Lo cual quiere decir que aunque borre el contenedor, los ficheros se quedan ahí. Lo cual quiere decir que si me copio ésas carpetas a cualquier otra máquina, la que sea, donde sea que esté y ejecuto el mismo docker-compose, vuelvo a tener mi servidor de música tal y como lo tenía antes de borrarlo. Y como me lo puedo descargar de Internet, todo ésto quiere decir que con hacer copia de unas carpetitas de nada, puedo migrar ésto a donde me dé la gana de una manera muy sencilla.
Al final del todo está la política de reinicio. He puesto always. Éso quiere decir que salvo que yo lo pare o borre a mano, siempre que el contenedor se pare, se va a reiniciar sólo (se nos va la luz, por ejemplo). Algo muy práctico y muy apañado.
Bueno, al lío, que ésto es larguísimo, menos mal que sólo va a ser así el primero. Ya tenemos definido conceptualmente nuestro docker-compose lo único que necesitamos hacer es meterlo todo en un fichero y ejecutarlo así que copiamos todo el texto de la caja de arriba y escribimos en la consola:
nano docker-compose.yml
(A ver, yo uso vi, otra gente usa vim, los hay que usan emacs porque tienen problemas con el tema de vivir bien, otros pico, tu usa lo que te de la gana para editar ficheros en la consola)
La cuestión es que copiamos el texto de la caja de arriba, el docker-compose, lo pegamos en nuestro nuevo fichero y si has usado nano para editarlo pulsas Ctrl+X y cuando te pregunte si quieres salvar el fichero le dices que sí.
Ya está. Ahora sí que sí. Qué emoción, oigan.
Ahora en tu carpeta de navidrome tiene que haber tres cosas. Un fichero llamado docker-compose.yml y dos carpetas (data y music) vacías. Desde ésa misma carpeta escribimos:
docker-compose up -d
Y veréis que automágicamente pasan cosas maravillosas.
Lo que va a suceder es que se va a bajar el contenedor de Internet, lo va a ejecutar y va a leer de las carpetas que le hemos dicho que lea. Hay dos cosas que no hemos indicado, con qué usuario tiene que ejecutar el contenedor (ya lo haremos, es importante) y en qué red desplegar el contenedor (y como no lo hemos hecho, va a crear una subred nueva con nombre navidrome_network y lo va a poner ahí, ya tocaremos éso).
La cuestión es que si la máquina de tu server tiene la ip 10.5.1.130, por ejemplo, cuando pongas en el navegador:
Vas a ver tu nuevo y delicioso servidor de música en streaming. Si metes discos en la carpeta /music te aparecerán ahí y podrás escuchar tu propia música desde cualquier lugar del mundo en una página web o en cualquier móvil con cualquier app que haga uso de la api Subsonic (yo uso una que se llama substreamer que está disponible para iOS y para Android y me va muy bien)
Gentes de la gleba: A ver, pazguato, ¿cómo que desde cualquier lugar del mundo? Dentro de mi casa si, pero desde Internet o abro ése puerto a Internet o me como los mocos. Y me tengo que saber mi IP pública que además cambia y no me mola abrir ése puerto y ésto es una mierda y ahora mismo cancelo mi pago en Patreon a tu mierda de blog
A ver.
Vamos a relajarnos.
Lo primero es que no tengo Patreon. Ni tengo intención de tenerlo.
En todo lo demás, tenéis razón.
Pero es que tenía que hacer un post muy, muy largo para poder explicar ésto. A partir de aquí es coser y cantar, porque todos los docker-compose funcionan igual así que podemos empezar a desplegar cosas a toda leche y sin complicaciones.
Podemos usar nuestro propio servidor de DNS para resolver el nombre de la URL tanto dentro como fuera de casa y podemos montar un proxy inverso para no tener que abrir puertos raros en el router.
La cantidad de cosas que podemos hacer a partir de aquí es inmensa y veremos muchas, pero por hoy y por ahora, con tener el servidor en ejecución y funcionando vamos que nos matamos.
Como curiosidad final, les dejo un enlace de reddit a un listado enorme de cosas que nos podemos montar en nuestro propio server, casi todas con docker.
Ésto ya es bastante largo. Estoy cansado y hay mucha tarea para empezar. La semana que viene resolvemos las cuitas del acceso desde Internet (vamos a tener que comprar un nombre de dominio baratito, éso sí, pero pensad que os habéis montado vuestro propio Spotify en un ratito para poder disfrutar de vuestra música a calidad máxima y no con la mierda de compresión que le meten y es vuestro, es vuestro servicio, no os lo pueden quitar, ni cerrar, ni os pueden censurar un artista.
Sois los dueños de vuestra propia cultura.
Es todo muy bello.