Un Indien Dans Une Nacelle

En clair on va mettre Apache dans un pod, et pour commmencer dans un conteneur. Les images d’apache ne manquent pas.

Commençons par une version simple :

frv@cavalas:~/ws/apache_container$ cat Containerfile
FROM docker.io/debian:trixie-slim
RUN apt-get update && apt-get install -y apache2 apache2-utils && apt-apt-get clean
EXPOSE 80
CMD ["apache2ctl","-k","start","-D","FOREGROUND"]

Le choix de l’image de départ FROM est le compromis entre l’optimisation de l’image finale, les fonctions nécessaires et surtout les habitudes acquises. Je préfére debian bien que alpine donnerait probablement les mêmes résultats en utilisant moins de place.

L’instruction RUN décrit les commandes à exécuter pour construire l’image finale. Chaque instruction RUN peut contenir autant de commandes que l’on veut et constitue une étape de construction appelée couche (layer). Lors d’une reconstruction, seules les couches modifiées sont reconstruites, ce qui guuide la répartition des commmandes entre différents RUN. On utilise apt-get au lieu de aptpour éviter

WARNING: apt does not have a stable CLI interface. Use with caution in scripts.

La ligne EXPOSE 80 informe que le port 80 sera utilisé en TCP lors de l’exécution du container. Savoir si elle est purement informative ou opérative n’est pas très clair.

Enfin CMD spécifie la commande qui sera exécutée au lancement du conteneur. Si plusieurs instructions CMD sont présentes dans le fichier, seule la dernière sera exécutée. On peut aussi utiliser ENTRYPOINT avec de légères différences. Ici on utlise la formeexec qui pour éviter de lancer un shell, la commande apache2ctl sera lancée en tant que processus 1.

Pour construire l’image de notre conteneur, podman propose la compande build qui prend en argument un contexte et/ou un fichier de configuration (pardéfaut Containerfile ou Dockerfile). Ici on précise uniquement que le contexte est le répertoire courant (.) :

On s’assure d’abord qu’il n’existe aucune image locale :

frv@cavalas:~/ws/apache_container$ podman images
REPOSITORY  TAG         IMAGE ID    CREATED     SIZE
frv@cavalas:~/ws/apache_container$ 

Puis on lance la construction :

frv@cavalas:~/ws/apache_container$ podman build .
STEP 1/4: FROM docker.io/debian:trixie-slim
Trying to pull docker.io/library/debian:trixie-slim...
Getting image source signatures
Copying blob 1733a4cd5954 done   | 
Copying config 233eabc84b done   | 
Writing manifest to image destination
STEP 2/4: RUN apt-get update && apt-get install -y apache2 apache2-utils && apt-get clean
Get:1 http://deb.debian.org/debian trixie InRelease [140 kB]
Get:2 http://deb.debian.org/debian trixie-updates InRelease [47.3 kB]
Get:3 http://deb.debian.org/debian-security trixie-security InRelease [43.4 kB]

[…]

The following additional packages will be installed:
  adduser apache2-bin apache2-data ca-certificates krb5-locales libapr1t64
  libaprutil1-dbd-sqlite3 libaprutil1-ldap libaprutil1t64 libbrotli1
  libcom-err2 libcurl4t64 libexpat1 libffi8 libgdbm-compat4t64 libgdbm6t64
  libgnutls30t64 libgpm2 libgssapi-krb5-2 libidn2-0 libjansson4 libk5crypto3
  libkeyutils1 libkrb5-3 libkrb5support0 libldap-common libldap2 liblua5.4-0
  libncursesw6 libnghttp2-14 libnghttp3-9 libp11-kit0 libperl5.40 libproc2-0
  libpsl5t64 librtmp1 libsasl2-2 libsasl2-modules libsasl2-modules-db
  libssh2-1t64 libtasn1-6 libunistring5 libxml2 linux-sysctl-defaults
  media-types netbase openssl perl perl-modules-5.40 procps psmisc
  publicsuffix ssl-cert

[…]

Running hooks in /etc/ca-certificates/update.d...
done.
--> 0cab4c36c5c4

La première couche est crée et identifiée par 0cab4c36c5c4.

STEP 3/4: EXPOSE 80
--> 12abf61382f3

Deuxième couche…

STEP 4/4: CMD ["apache2ctl","start"]
COMMIT
--> 7de2d77b93d3
7de2d77b93d37e41300569166e4701a73152c1fd2167c0a79cfeffe3a893946d

Dernière couche qui correspond à l’image finale 7de2d77b93d37e41300569166e4701a73152c1fd2167c0a79cfeffe3a893946d. On vérifie le résultat de la construction :

frv@cavalas:~/ws/apache_container$ podman images
REPOSITORY                TAG          IMAGE ID      CREATED         SIZE
<none>                    <none>       7de2d77b93d3  12 minutes ago  184 MB
docker.io/library/debian  trixie-slim  233eabc84b66  3 days ago      81.1 MB
frv@cavalas:~/ws/apache_container$ 

Le constructeur a judicieusement conservé l’image de base trixie-slim pour l’utiliser lors de constructions ultérieures ce qui peut poser un problème quand l’image distante est mise à jour. Notre image est bien présente et identifiée par 7de2d77b93d3 , ce qui n’est pas très parlant mais le minimum est prêt pour exécuter une instance de notre conteneur. Comme il utilisera les droits de l’utilisateur courant, le conteneur ne pourra pas communiquer sur le port privilégié 80, on transfert le port 80 du conteneur vers le port 8080 de l’hôte (option -p8080:80) :

frv@cavalas:~/ws/apache_container$ podman run -p8080:80 7de2d77b93d3
AH00558: apache2: Could not reliably determine the server\'s fully qualified domain name, using 192.168.65.34. Set the 'ServerName' directive globally to suppress this message

Le terminal reste attaché au conteneur (ce qui permet de voir les messages) et on peut vérifier à partir d’une autre console que

  • le conteneur est en cours d’exécution :
frv@cavalas:~/ws/apache_container$ podman ps
CONTAINER ID  IMAGE         COMMAND               CREATED         STATUS         PORTS                 NAMES
9b059fb2fcb3  7de2d77b93d3  apache2ctl -k sta...  23 minutes ago  Up 23 minutes  0.0.0.0:8080->80/tcp  determined_albattani
frv@cavalas:~/ws/apache_container$ 
  • le port 8080 est bien ouvert :
frv@cavalas:~/ws/apache_container$ nmap -p 8080 localhost
Starting Nmap 7.95 ( https://nmap.org ) at 2025-12-12 12:59 CET
Nmap scan report for localhost (127.0.0.1)
Host is up (0.000076s latency).
Other addresses for localhost (not scanned): ::1

PORT     STATE SERVICE
8080/tcp open  http-proxy

Nmap done: 1 IP address (1 host up) scanned in 0.03 seconds
frv@cavalas:~/ws/apache_container$
  • il est servi par apache :
frv@cavalas:~/ws/apache_container$ curl -s http://localhost:8080|head

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <title>Apache2 Debian Default Page: It works</title>
    <style type="text/css" media="screen">
  * {
    margin: 0px 0px 0px 0px;
    padding: 0px 0px 0px 0px;
frv@cavalas:~/ws/apache_container$

On est bien content, on peut arrêter le conteneur et vérifier qu’il est bien stoppé :

frv@cavalas:~/ws/apache_container$ podman stop determined_albattani 
WARN[0010] StopSignal SIGTERM failed to stop container determined_albattani in 10 seconds, resorting to SIGKILL 
determined_albattani
frv@cavalas:~/ws/apache_container$ podman ps -a
CONTAINER ID  IMAGE         COMMAND               CREATED         STATUS                      PORTS                 NAMES
9b059fb2fcb3  b69d7a76c912  apache2ctl -k sta...  53 minutes ago  Exited (137) 5 minutes ago  0.0.0.0:8080->80/tcp  determined_albattani
frv@cavalas:~/ws/apache_container$ 

Il reste à affiner la configuration pour donner des noms plus parlants, supprimer l’alerte à l’arrêt du conteneur et surtout servir autre chose que la page par défaut sur localhost.

Si on utilise apache2ctl pour lancer le serveur, apache2 de recevra pas le signal de fin, probablement parce qu’il n’a pas le pid 1), il vaut mieux utiliser directement la comande apache2 (constat personnel, pas de source).

frv@mai:~ $ sudo adduser --uid 3333 --gid 100 --disabled-password --comment '' web-server

frv@mai:~ $ cat .ssh/authorized_keys |sudo -u web-server tee /home/web-server/.ssh/authorized_keys

frv@mai:~ $ sudo deluser --remove-home web-server