Raspberry Pi Zero 2 W Docker

Oui oui ! Docker !

Les Raspberry Pi sont des ordinateurs qui fonctionnent sous Linux. La carte la moins puissante de la fondation, la Pi Zero 2*, devient l'espace de cet article notre terrain de jeux pour de nouvelles expérimentations : on va essayer Docker avec 512Mo de RAM et un petit processeur ARM.

Cet article décrit comment installer Docker + Portainer sur une Raspberry Pi et installer Squeezelite, pour en faire un client audio du logiciel Logitech Media Server.

Le résultat est un squeezelite qui se gère via une interface web, très confortable, avec laquelle il est facile de paramétrer, par exemple un recalcul à la volée d'un fichier audio 16/44 vers 32/768.

Ci-dessous, une copie d'écran pour montrer l'interface à disposition dans un navigateur web : moins effrayant que la ligne de commandes, n'est ce pas ?

*sans compter la Raspberry Pi Zero, mono coeur et vraiment trop trop trop lente.

OS 64 bits avec 512Mo de RAM ?

Pour la Raspberry Pi Zero 2, même avec seulement 512Mo de RAM, on choisira la version de l'OS en 64 bits. Pourquoi ? Parce que en gros "il n'y a plus rien pour le 32 bits". Aujourd'hui quand on cherche un logiciel quelconque, on s'aperçoit vite que les logiciels pour les processeurs ARM sont en 64 bits !

Nous voulons Installer Docker ainsi que Portainer qui permet de gérer Docker via une belle interface, plutôt que de taper des lignes et des lignes sur la CLI.

Docker permet de gérer des containers qui sont des objets atomiques qui embarquent un logiciel spécifique et ses dépendances. Dans le schéma ci-contre, rien n'interdit d'avoir Squeezlite en tant qu'application A et B, et une version différente en C... On peut gérer plusieurs DACs et ou plusieurs paramètres de fonctionnement. L'application D peut être un serveur de base de données, la E un serveur ouaibe etc... La limite sont les performances offertes par la carte.

Préparer la SD Card

Pour installer le système, on va sur le site de la fondation https://www.raspberrypi.com/software/

On récupère l'outil qui se nomme Raspberry Pi Imager.

Une fois que c'est fait, on sélectionne Raspberry Pi OS Other et ensuite Rapsberry Pi OS Lite 64 Bits : c'est la version "CLI", sans le bureau.

Nous n'avons pas besoin pour notre projet d'une interface graphique de bureau : c'est autant de ressources économisées pour la partie lecteur audio. N'oublions pas que quand cette carte était disponible, elle était à 16.5€, on comprendra que les performances sont limitées.


Ensuite on choisi le stockage (une carte SD quelconque) en cliquant sur choisir le stockage...

Soyez attentif en sélectionnant votre carte SD, il s'agit de ne pas installer le système sur un disque déjà présent sur votre ordinateur !

Ensuite cliquez sur la molette : on va gérer quelques paramètres.


Dans cette fenêtre :

  1. définissez un nom de machine

  2. autorisez la prise en main à distance via SSH

  3. via une authentification par mot de passe

  4. définissez

    1. un compte utilisateur

    2. et son mot de passe

Ensuite configurez votre réseau (la Zero 2W ne gère que le 2.4 GHz) en indiquant le SSID et le mot de passe du réseau wifi.

Ensuite indiquez :

  • le pays de votre réseau WIFI, par exemple FR pour FRANCE

  • la time zone, par exemple Europ/Paris

  • le type de clavier (fr pour un clavier français)

  • désactivez le pouet quand c'est fini et la télémétrie

  • éjecter le média quand c'est fini.

Tous ces paramètres se faisaient auparavant sur la ligne de commande dans le cas d'un OS Lite. C'est une bonne évolution de la procédure d'installation, proposée par le logiciel de la fondation Raspberry.

Une fois la carte prête, installez la dans la Rasp et laisser bouillir le temps de prendre un café (le temps d'un fs expansion, laissez 5 minutes).

Premiers pas

Après quelques minutes la Rasp a booté et doit être visible sur le réseau.

Dans la liste des machines vues par le routeur de la maison, on retrouve "squeezelite" que l'on avait configuré tantôt.

Son adresse IP est 192.168.0.105, c'est cela que l'on va utiliser pour prendre la main via une session SSH (pour installer Docker et Portainer).

Sur la ligne de commande, utilisez les informations que vous avez entrées précédemment : user et password, l'adresse IP est celle affectée par votre routeur !

Tapez (sous Windows c'est dans une fenêtre de commandes CMD que cela se passe) :

ssh nomutilisateur@192.168.0.105

  1. nomutilisateur est celui que vous avez indiqué dans RPI Imager,

  2. l'adresse IP est celle attribuée par votre routeur

  3. ensuite vous devez taper yes pour valider la machine distante sur votre ordinateur,

  4. et enfin entrez le mot de passe utilisateur défini dans RPI Imager.

Quand ces opérations sont terminées, vous êtes sur la ligne de commande en session distante, via SSH, sur votre cartounette.

Installer Docker sur la Raspberry

Selon la version du système, selon le fabricant de la carte, la saveur de Linux installée etc, la procédure d'installation varie. Par contre, une constante, c'est de mettre à jour le système tout de suite après l'installation. Nous allons commencer par là avec les deux lignes update et upgrade :

sudo apt update

sudo apt upgrade

La mise à jour peut prendre quelques minutes. Souvenez vous E=MC², soit Energie = Matin*Café², prenez le temps de boire un autre café.

Ce que l'on peut faire aussi, c'est installer bpytop, un utilitaire qui permet d'avoir simplement un état de la machine (processeur, RAM, réseau...) sur la ligne de commande :

sudo apt install bpytop

Maintenant, les choses sérieuses peuvent commencer. On va installer Docker :

  1. sudo apt-get remove docker docker-engine docker.io containerd runc

  2. sudo apt-get install apt-transport-https ca-certificates curl gnupg-agent software-properties-common

  3. curl -fsSL https://get.docker.com -o get-docker.sh

  4. sudo sh get-docker.sh

  5. sudo usermod -aG docker $USER

D'abord on le supprime (si l'on a déjà une installation), ensuite on met à jour une bibliothèque dont à a besoin, ensuite on télécharge le script d'installation, enfin on lance le script d'installation (4).

Quand c'est terminé, la commande 5 permet d'ajouter votre utilisateur au groupe docker.

Lorsque l'installation est terminée, vous pouvez taper la commande suivante pour confirmer le bon déroulement des opérations :

docker version

Voilà, c'est tout bon !

On peut passer à l'installation de Portainer : pour l'instant on ne peut utiliser Docker que sur la ligne de commande, Portainer nous offre une interface web !

Installer Portainer

Voici le sommet de l'ingratitude de la commande Docker : installer Portainer sur la ligne de commande, bon appétit :


sudo docker run -d -p 9051:9000 --name=portainer --restart=always -v /var/run/docker.sock:/var/run/docker.sock -v portainer_data:/data portainer/portainer-ce:latest

Avec cette commande, on demande à docker d'installer et exécuter le container portainer et on lui demande de communiquer avec l'extérieur sur le port 9051 (le port 9000 d'origine, nous souhaitons le conserver pour le LMS).

La commande est indigeste, mais c'est la dernière fois : ensuite on va utiliser le serveur web pour gérer nos affaires.

Petite note : j'ai eu plusieurs fois l'erreur "TLS handshake timeout". Mon réseau est assez aléatoire, j'ai fini par essayer d'installer "hello-world" :

sudo docker run hello-world

Et à la troisième tentative, docker a réussi à descendre l'image du hub et ensuite lancer le container. Encouragé par cette réussite fruit de la répétition jusqu'à ce que ça fonctionne, j'ai relancé n fois la commande pour portainer et cela a fini par fonctionner. Bon, en étant en Chine, le fonctionnement d'internet, derrière la grande muraille numérique est parfois imprévisible. Quoiqu'il en soit, si vous aussi vous avez l'erreur TLS : insistez !

Et voilà, une fois portainer installé, on peut aller sur l'interface avec un navigateur.

Il faut utiliser l'adresse IP de la carte et le port 9051.

Pour nous c'est 192.168.0.105:9051

Pour rappel, le port par défaut de portainer et 9000 mais nous voulons conserver ce port pour la communication avec le LMS. C'est pourquoi nous avons demandé sur la ligne de commande à mapper le port 9051->9000.

L'écran affiché propose la création d'un compte admin. par défaut admin est affiché mais vous pouvez mettre ce que bon vous chante, robert ou georges ou tarzan.

Le mot de passe doit faire au minimum 12 caractères de long, vous pouvez supprimer la télémétrie (pas le cas sur ma copie d'écran).

Et zou !

Première utilisation de portainer

Le premier écran est celui-ci.

On va cliquer sur le bouton "baleine qui porte des containers", allez, Get Started !


Et là nous voici dans le coeur de notre sujet.

Il s'agit de l'interface de gestion des containers.

A nouveau on clique sur la baleine en bas à gauche.

Dans l'écran ci-dessous on voit que l'on a pour l'instant 1 container installé et que :

  • son nom est portainer

  • il est en train de tourner (running)

  • le nom de l'image est indiquée (l'image récupérée du hub docker pour construire le container)

  • on voit la date de création (ne pas tenir compte de l'adresse IP)

  • le port 9051 est celui qui permet d'accéder au container depuis l'extérieur

La plupart des opérations suivantes sont accessibles via le menu à gauche, essentiellement Containers et Images.

Il y a plusieurs moyens de parvenir au même résultat. Ce qu'il faut accepter, c'est que l'on s'amuse sur un petit ordinateur pas cher et que si l'on s'est trompé, ce n'est pas grave, on peut recommencer en essayant de ne pas se tromper : l'apprentissage par essais / erreurs est sans impact ici.

Personne ne va venir en ronchonnant parce que ça ne fonctionne pas.

Par contre la satisfaction sera présente lorsque cela va fonctionner.

Donc, n'hésitez pas à cliquer partout et essayer plein de choses, c'est vraiment comme cela que l'on apprend, pas en restant dans un cadre défini par les autres.

Installation de Squeezelite : 1/2 récupérer l'image

Nous allons récupérer une "image" de squeezelite.

Rendez-vous sur le hub docker et cherchez squeezelite. Il y a plusieurs réponses, mais nous voulons la version de giof71.

A partir de cette image, nous allons ensuite construire notre container en le paramétrant.


Si nous étions sur la ligne de commande, pour récupérer l'image il tapez "docker pull..." comme indiqué sur la page de l'image.

Nous allons procéder plutôt avec le navigateur, en allant dans la partie Images. Mais avant, il faut choisir un Tag sur la page du hub docker.

Dans l'onglet Tags, on voit que la dernier version est obtenue avec le Tag latest et qu'elle fonctionne pour notre arm en 64 bits.

Nous avons tous nos renseignements pour commencer, nous voulons cette image :

giof71/squeezelite:latest

Nous pouvons retourner dans l'interface de portainer pour installer squeezelite.

Pour récupérer l'image :

  1. sélectionner le menu Images

  2. indiquez quelle image vous voulez récupérer

  3. cliquez sur Pull the Image.

Le système va récupérer l'image sur votre carte SD et vous pourrez l'utiliser autant que de fois que vous voudrez faire des containers avec.

Au bout de quelques dizaines de secondes, votre image est disponible dans la liste des images.

Installation de Squeezelite : 2/2 créer le container

Allez dans le menu Containers et cliquez sur le bouton Add container.


Hum, dans la copie d'écran ci-dessous, je me suis trompé. J'ai pris le tag stable au lieu du tag latest, voir dans la conclusion le bénéfice de la version stable).

Indiquez le nom du container et le nom de l'image à utiliser.

Si l'image n'est pas présente sur votre poste, alors elle sera téléchargée : vous pouvez vous dispenser de l'étape précédente, vous pouvez créer le container directement avec le nom de l'image.

Mais maintenant vous connaissez deux manières de faire dans le navigateur, et une autre sur la ligne de commande.

Une fois le champ image renseigné, cliquez sur le bouton Deploy Container et patientez une minute environ.

Voilà, le container a démarré, mais il s'est arrêté, il est planté. C'est normal, pour l'instant rien n'a été configuré.

On peut regarder ce qu'il s'est passé en cliquant sur le petit bouton dans la colonne quick actions sur la ligne de notre squeeze_c200, pour voir les logs.

Normal, la commande squeezelite a été lancée mais il n'y aucun DAC ni connecté ni paramétré !

C'est le moment de connecter un DAC à la Raspberry. Aujourd'hui nous connections un SMSL C200. Ensuite, il va falloir éditer le container pour le configurer.

Cliquez sur squeeze_c200 et ensuite sur le bouton Duplicate/Edit (en haut à droite).

En bas de la fenêtre se trouve une partie "Advanced container settings" avec plusieurs onglets.

Sélectionnez dans Commands & Loggins "Interactive"

Dans la partie Network :

  1. sélectionnez host, c'est impératif

  2. éventuellement donnez un hostname

C'est tout cette partie là, on va passer au repas du serpent...


L'onglet Env a de quoi faire peur mais il n'est pas nécessaire de tout saisir :

  1. il faut saisir la chaine permettant à squeezelite de se connecter au DAC (regardez sur le hub docker, dans la documentation de l'image se trouve une liste de DAC)

  2. indiquez un nom pour le lecteur (le nom c'est pour vous, l'adresse MAC c'est pour le LMS)

  3. indiquez l'adresse IP du serveur LMS

A propose de l'adresse MAC : le LMS identifie les lecteurs réseaux via l'adresse Mac de chaque lecteur : si vous projetez d'avoir plusieurs containers squeezelite sur la même carte, il est impératif d'attribuer à chaque container une adresse MAC unique.

Les points 4 et 5 sont totalement facultatifs et potentiellement contre-productif.

Le point 4 définit toutes les fréquences possibles (du DAC) et le point 5 donne la recette. Cela est expliqué sur le docker hub, en gros, avec les paramètres de l'écran :

  • toutes les fréquences en 44100 seront upsamplées en 705600 et les 48000 en 768000

  • tout ce qui arrive en 16, 20,24 bits sera élevé à 32 bits

C'est plus ou moins la recette d'Archimago pour Goldilock, Boucles d'Or au pays du filtre numérique.

Demander ça à la petite cartounette, c'est seulement pour savoir si la carte est capable de le faire (ou tester un DAC) mais il n'y a pas de retombées dans la qualité de restitution : la plupart des circuits DAC effectuent ce travail en interne, ils ne bossent pas sur 16 bits, mais sur 32 : ça laisse 16 bits de mou pour faire un volume numérique sans perte d'information.

Il reste encore un paramètre, dans la partie Runtime & Resources

  • cliquez sur add device

  • mappez /dev/snd vers /dev/snd

Puis cliquez sur Deploy The Container et ensuite, dans la boîte de dialogue, sur Replace.

Et voilà, vous avez un joli petit container qui fait lecteur audio...

Il y aurait plein d'autres points à indiquer, mais l'essentiel est là...

Trouver le bon paramètre pour un DAC quelconque

Il reste une question à élucider : comment configurer un DAC lambda dont on ne connaît pas les paramètres ? En gros, il faut configurer la sortie audio sur null, consulter les logs, récupérer la chaine et la copier dans la bonne case... Allons-y, c'est plus facile avec des images.

Editez votre container, allez dans les paramètres avancés et dans Env, tapez null pour le paramètre audio device. Ensuite Deploy et Replace.

Le container va fonctionner, mais tout les échantillons audio seront "jetés".

Comme le container fonctionne, on peut consulter les logs

Dans la liste des containers, cliquer sur le bouton pour voir les logs.

Dans la page des logs, commencez par désactiver l'auto-refresh (qui est pénible).

Ensuite déplacez vous avec l'ascenseur dnas le log pour trouver la liste des périphériques reconnus.

Votre DAC USB se trouve dans la liste, récupérez la chaine "hw:quelque_chose".

Pour le SMSL C200, la chaine est :

hw:CARD=AUDIO,DEV=0.

Ensuite retournez sur la partie ENV et remplacez null par cette chaine, puis les boutons Deploy et Replace.

Quelques mesures

Notre player audio fonctionne... Les paramètres de lecture sont délirants avec un upsampling jusqu'à 705kHz et 32 bits, testons !

Est-ce que la petite carte supporte la charge ?

On va lancer bpytop (que l'on avait installé plus haut) pour obtenir des renseignements sur le système.

Ci-dessous on voit que le taux d'occupation processeur avec docker + portainer + squeezelite "au taquet" représente 15%. C'est une bonne nouvelle.

Ci-dessous l'écran de statistiques du container. L'occupation mémoire est si faible que le graphe ne décolle pas. L'occupation CPU est pour 1 coeur. quand on est à 20%, cela signifie que c'est 20/4 d'occupation totale, soit 5%.

A noter que la version "latest" occupe deux coeurs à 100%, il vaut mieux conserver la version stable.

Pour information, le code se comporte proprement et n'effectue que des calculs entiers : une fréquence de base de 44.1kHz sera convertie en 88200, 176400, 352800, et 705600. Un 48kHz sera converti en 96000, 192000, 384000 et 768000. Amen.

Sans resampling, un fichier audio 24/48 pour test. Dans ce cas la consommation de ressources baisse encore, le processeur ronronne. On peut même envisager de descendre la fréquence du processeur pour moins chauffer et consommer moins (un dizième de Watt ?).

Conclusion

Docker + portainer + Squeezelite fonctionnent correctement, c'est fluide, on peut même imaginer gérer deux DAC avec la même carte, ou d'autres containers pour d'autres services (Homer, Filezilla, Transmission...). On a le confort d'une interface web pour paramétrer, tester différents réglages, expérimenter. Ou pas si l'on est content du fonctionnement tel quel.

Encore une fois, avec une cartounette à 16.5€, on vient de construire un player réseau ultime. Si la Raspberry n'est plus disponible, de nombreuses autres cartes le sont, à tous les tarifs, à commencer par une Orange Pi Zero 2, bien plus puissante, à 35€.

Un player ultime, sur lequel on peut régler ou pas les paramètres de fréquence et de nombre de bits. Je vois dans des salons des appareils à 4000€ qui font la même chose, moins bien, en mode produit d'entrée de gamme, parce que la version "PRO" va "plus loin en terme de définition globale bla bla bla".

Ces appareils ne font pas de la magie, ils intègrent des composants identiques fonctionnellement à ceux de la carte. Dans de beaux boitiers, bien emballés, somptueusement mis en oeuvre dans des magasins spécialisés qui vont vous faire entendre la différence entre les deux players. La version PRO à 7000€ va plus loin, mais un poil moins que la version PRO MkII à 10000€.

Bon, la cartounette consomme un quart de Watt, coûte le prix d'un repas et une aprèm de galère à configurer si vous débutez complètement. Vous pouvez la mettre à jour quand vous voulez, vous comprenez comment elle marche et si elle tombe en panne, on s'en fiche, on en achète une autre dans cinq ans. C'est déjà noël ?