Compiler CMatrix sous Alpine Linux
Objectif de cet atelier pratique
- 
Prise en main d'Alpine Linux, une distribution ultra-légère spécialement conçue pour servir de base aux conteneurs Docker 
- 
Compiler le code source de l'économiseur d'écran CMatrix sous Alpine Linux 
Télécharger Alpine Linux
Pour commencer, récupérez la dernière image d'Alpine Linux :
$ docker pull alpine
Using default tag: latest
latest: Pulling from library/alpine
43c4264eed91: Pull complete 
Digest: sha256:beefdbd8a1da6d2915566fde36db9db0b524eb737fc57cd1367effd16dc0d06d
Status: Downloaded newer image for alpine:latest
docker.io/library/alpine:latest
Sur mon système, l'image pèse moins de 10 Mo. C'est un excellent point de départ pour construire une image Docker légère :
Préparer le Dockerfile
La prochaine étape consiste à créer un Dockerfile. C'est en quelque sorte la
recette de cuisine de notre image Docker : un fichier texte qui contient
toutes les instructions nécessaires pour construire l'image.
L'instruction FROM nous indique l'image de base à utiliser pour les
instructions subséquentes :
Pour les métadonnées de l'image, la bonne pratique consiste à utiliser
l'instruction LABEL en conformité avec les standards décrits ici.
Commencez par renseigner l'auteur de l'image :
Ajoutez une description succincte :
Construire une première image
Pour l'instant notre image ne fait pas grand-chose, mais rien ne nous empêche de construire un premier jet pour autant :
Nos deux images sont de la même taille. C'est normal, puisque nous avons uniquement ajouté les métadonnées pour l'instant.
$ docker images
REPOSITORY          TAG       IMAGE ID       CREATED      SIZE
alpine              latest    706db57fb206   7 days ago   8.32MB
kikinovak/cmatrix   latest    6ffa90735c23   7 days ago   8.32MB
Démarrer un conteneur
À présent nous allons démarrer un conteneur basé sur cette image. Dans un premier temps, notre démarche consistera à essayer de compiler CMatrix directement dans le shell du conteneur, en avançant pas à pas dans une approche de tentative et échec.
Un système brut de décoffrage
Alpine Linux est plus exigeant qu'une base Ubuntu ou Debian. Au départ nous ne disposons même pas d'un shell Bash, et la plupart des outils que nous pouvons avoir l'habitude d'utiliser sont également absents.
Compiler CMatrix pas à pas
Nous avons besoin du code source de CMatrix. Essayons de le récupérer :
Alpine Linux utilise le gestionnaire de paquets APK (Alpine Package Keeper) pour installer et gérer les paquets logiciels. Nous allons donc l'utiliser pour récupérer Git :
Récupérez le code source de CMatrix :
Notez dans un coin de votre tête qu'à ce stade nous avons effectué trois étapes dans la construction de notre image :
- 
la mise à jour des métadonnées des paquets 
- 
l'installation du paquet git
- 
la récupération du code source de CMatrix 
Continuons allègrement et jetons un œil au code source :
# cd cmatrix/
# ls -l
total 176
-rw-r--r-- 1 root root 65 Oct 18 08:00 AUTHORS
-rw-r--r-- 1 root root 3141 Oct 18 08:00 CMakeLists.txt
-rw-r--r-- 1 root root 3220 Oct 18 08:00 CODE_OF_CONDUCT.md
-rw-r--r-- 1 root root 4235 Oct 18 08:00 CONTRIBUTING.md
-rw-r--r-- 1 root root 35149 Oct 18 08:00 COPYING
-rw-r--r-- 1 root root 65 Oct 18 08:00 ChangeLog
-rw-r--r-- 1 root root 7831 Oct 18 08:00 INSTALL
...
Tentative et échec
Lorsque vous construisez une image Docker, c'est tout à fait normal d'avancer à tâtons et de rencontrer une succession d'obstacles. Je ne vais pas forcément rentrer dans les détails de tous les obstacles que j'ai pu rencontrer lors de la compilation de CMatrix.
Pour compiler le code source de CMatrix, commençons par invoquer autoreconf
-i :
La commande n'est pas disponible non plus. Je vais donc l'installer :
# apk add autoconf
(1/7) Installing m4 (1.4.19-r4)
(2/7) Installing libbz2 (1.0.8-r6)
(3/7) Installing perl (5.40.3-r0)
(4/7) Installing autoconf (2.72-r1)
(5/7) Installing perl-error (0.17030-r0)
(6/7) Installing perl-git (2.49.1-r0)
(7/7) Installing git-perl (2.49.1-r0)
Executing busybox-1.37.0-r19.trigger
OK: 58 MiB in 35 packages
La taille des paquets installés
Notez la taille de tous ces paquets dans un autre coin de votre tête. Tous ces outils contribuent à agrandir considérablement notre image de conteneur.
Et voici le prochain obstacle :
# autoreconf -i
Can't exec "aclocal": No such file or directory at 
/usr/share/autoconf/Autom4te/FileUtils.pm line 299.
autoreconf: error: aclocal failed with exit status: 2
Ici il nous faut installer le paquet automake :
Et c'est reparti pour un tour :
# autoreconf -i
configure.ac:5: warning: 'AM_CONFIG_HEADER': this macro is obsolete.
configure.ac:5: You should use the 'AC_CONFIG_HEADERS' macro instead.
./lib/autoconf/general.m4:2434: AC_DIAGNOSE is expanded from...
aclocal.m4:745: AM_CONFIG_HEADER is expanded from...
configure.ac:5: the top level
configure.ac:27: warning: The macro 'AC_HEADER_STDC' is obsolete.
configure.ac:27: You should run autoupdate.
./lib/autoconf/headers.m4:663: AC_HEADER_STDC is expanded from...
configure.ac:27: the top level
configure.ac:31: warning: The macro 'AC_TYPE_SIGNAL' is obsolete.
configure.ac:31: You should run autoupdate.
./lib/autoconf/types.m4:805: AC_TYPE_SIGNAL is expanded from...
configure.ac:31: the top level
configure.ac:172: warning: AC_OUTPUT should be used without arguments.
configure.ac:172: You should run autoupdate.
configure.ac:18: installing './compile'
configure.ac:8: installing './config.guess'
configure.ac:8: installing './config.sub'
configure.ac:6: installing './install-sh'
configure.ac:6: installing './missing'
Makefile.am: installing './depcomp'
C'est quoi tout ce gloubi-boulga ?
Si vous n'avez pas trop l'habitude de compiler du code source, ce gloubi-boulga vous semblera probablement inquiétant. Or, les choses se passent plutôt bien. Pour en avoir le cœur net, affichez le code retour de la dernière commande :
Le code retour 0 nous indique ici que la commande précédente s'est
correctement effectuée.
La prochaine étape consiste à lancer ./configure, une procédure classique
dans la compilation d'applications en C. Notez tout de même que je souhaite
construire un binaire statique qui contient toutes les dépendances nécessaires
à son exécution :
# ./configure LDFLAGS="-static"
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /bin/mkdir -p
checking for gawk... no
checking for mawk... no
checking for nawk... no
checking for awk... awk
checking whether make sets $(MAKE)... no
checking whether make supports nested variables... no
checking build system type... x86_64-pc-linux-musl
checking host system type... x86_64-pc-linux-musl
checking for gcc... no
checking for cc... no
checking for cl.exe... no
checking for clang... no
configure: error: in '/cmatrix':
configure: error: no acceptable C compiler found in $PATH
See 'config.log' for more details
Cette étape échoue également pour la simple raison que notre système réduit ne dispose pas de compilateur pour l'instant :
Sous Alpine Linux, les compilateurs de base sont fournis par le méta-paquet
alpine-sdk (Software Development Kit). Là encore, notez la taille
relativement importante des paquets installés par rapport au système de base
initial :
On retente le coup :
# ./configure LDFLAGS="-static"
checking for a BSD-compatible install... /usr/bin/install -c
checking whether build environment is sane... yes
checking for a race-free mkdir -p... /bin/mkdir -p
...
configure: WARNING:
*** No termcap lib available, consider getting the official ncurses
*** distribution from ftp://ftp.gnu.org/pub/gnu/ncurses if you get
*** errors compiling cmatrix.
...
configure: WARNING:
*** You do not appear to have a consolefonts directory in a standard location
*** (/usr/lib/kbd or /usr/share), even though you appear to have the
*** consolechars and/or setfont command.  The matrix font for the console
*** will not be installed.  This means you will not be able to use the
*** matrix console font (and the -l command line switch) unless the font
*** is located in your current directory when you run CMatrix.
...
config.status: creating Makefile
config.status: creating cmatrix.spec
config.status: creating config.h
config.status: executing depfiles commands
C'est déjà pas mal, à deux détails près :
- 
Il nous manque deux répertoires sur le système. 
- 
Il manque également une dépendance NCurses. 
Créez les deux répertoires pour les polices d'affichage :
# mkdir -pv /usr/lib/kbd/consolefonts
created directory: '/usr/lib/kbd/'
created directory: '/usr/lib/kbd/consolefonts'
# mkdir -pv /usr/share/consolefonts
created directory: '/usr/share/consolefonts'
Installez les dépendances NCurses :
# apk add ncurses-dev ncurses-static
(1/8) Installing ncurses-terminfo-base (6.5_p20250503-r0)
(2/8) Installing libncursesw (6.5_p20250503-r0)
(3/8) Installing libformw (6.5_p20250503-r0)
(4/8) Installing libmenuw (6.5_p20250503-r0)
(5/8) Installing libpanelw (6.5_p20250503-r0)
(6/8) Installing libncurses++ (6.5_p20250503-r0)
(7/8) Installing ncurses-dev (6.5_p20250503-r0)
(8/8) Installing ncurses-static (6.5_p20250503-r0)
Executing busybox-1.37.0-r19.trigger
OK: 305 MiB in 75 packages
La dépendance d'exécution ncurses-terminfo-base
Notez au passage que le paquet ncurses-terminfo-base est également
installé. Ce paquet va constituer une dépendance d'exécution de notre
application. Nous aurons l'occasion d'en reparler en temps et en heure.
On relance la commande ./configure :
# ./configure LDFLAGS="-static"
...
"Using ncurses as the termcap library"
checking for use_default_colors in -lncurses... yes
checking for resizeterm in -lncurses... yes
checking for wresize in -lncurses... yes
checking for consolechars... no
checking for setfont... /usr/sbin/setfont
checking for /usr/lib/kbd/consolefonts... yes
checking for /usr/share/consolefonts... yes
checking for mkfontdir... no
checking for /usr/share/fonts/misc... no
checking for /usr/share/X11/fonts/misc... no
checking for /usr/X11R6/lib/X11/fonts/misc... no
checking that generated files are newer than configure... done
configure: creating ./config.status
config.status: creating Makefile
config.status: creating cmatrix.spec
config.status: creating config.h
config.status: executing depfiles commands
Tout a l'air parfait. On passe à la compilation :
# make
...
gcc  -g -O2  -static -o cmatrix cmatrix.o  -lncurses  -lncurses
make[1]: Leaving directory '/cmatrix'
Là aussi, tout a l'air parfait. La compilation n'a retourné aucune erreur, et
nous disposons à présent d'un binaire cmatrix dans le répertoire de
travail :
Nous pouvons l'exécuter pour avoir une première idée de ce que ça donne :
- 
Contemplez quelques secondes le défilement de tous ces caractères cryptiques. 
- 
Appuyez sur Q pour quitter CMatrix. 
Enregistrer les étapes
Nous avons réussi à compiler CMatrix avec succès. Pour retrouver la procédure de construction du binaire depuis le code source, il nous suffit d'afficher l'historique du shell :
# history
   0 git clone https://github.com/abishekvashok/cmatrix
   1 apk update
   2 apk add git
   3 git clone https://github.com/abishekvashok/cmatrix
   4 cd cmatrix/
   5 ls -l
   6 autoreconf -i
   7 apk add autoconf
   8 autoreconf -i
   9 apk add automake
  10 autoreconf -i
  11 echo $?
  12 ./configure LDFLAGS="-static"
  13 apk add alpine-sdk
  14 ./configure LDFLAGS="-static"
  15 mkdir -pv /usr/lib/kbd/consolefonts
  16 mkdir -pv /usr/share/consolefonts
  17 apk add ncurses-dev ncurses-static
  18 ./configure LDFLAGS="-static"
  19 make
  20 ls -lh ./cmatrix
  21 ./cmatrix
  22 history
Copiez l'intégralité de cet historique dans le presse-papier de votre environnement graphique et quittez le conteneur.
Gare à la suppression du conteneur !
N'oubliez pas que le conteneur a été créé avec l'option --rm. À partir du
moment où nous le quittons (exit), l'arrêt provoque également la
suppression. Tout ce que nous avons fait jusqu'ici est donc parti au
paradis des octets... ou presque.
Collez le contenu de l'historique tel quel dans le Dockerfile, à la suite des
trois premières instructions :
FROM alpine
LABEL org.opencontainers.image.authors="Nicolas Kovacs"
LABEL org.opencontainers.image.description="Container image for CMatrix"
   0 git clone https://github.com/abishekvashok/cmatrix
   1 apk update
   2 apk add git
   3 git clone https://github.com/abishekvashok/cmatrix
   4 cd cmatrix/
   5 ls -l
   6 autoreconf -i
   7 apk add autoconf
   8 autoreconf -i
   9 apk add automake
  10 autoreconf -i
  11 echo $?
  12 ./configure LDFLAGS="-static"
  13 apk add alpine-sdk
  14 ./configure LDFLAGS="-static"
  15 mkdir -pv /usr/lib/kbd/consolefonts
  16 mkdir -pv /usr/share/consolefonts
  17 apk add ncurses-dev ncurses-static
  18 ./configure LDFLAGS="-static"
  19 make
  20 ls -lh ./cmatrix
  21 ./cmatrix
  22 history
La suite dans le prochain atelier pratique, où nous allons voir en détail la
rédaction d'un Dockerfile propre et efficace depuis notre historique du
shell.
Remerciements
Cet atelier pratique s'inspire d'une série de cours de James Spurin, un formateur Linux & Open Source assez exceptionnel. Je tiens à le remercier ici.

