Dockerfile : ADD ou COPY ?

Lorsque l’on écrit un ficher de construction Docker, c’est toujours la question qui se pose les premières fois que l’on veut copier un fichier ou répertoire local dans le conteneur : est-ce que je dois utiliser ADD ou COPY ?

Les deux ont la même syntaxe et permettent de copier un ou plusieurs fichiers et répertoires :

COPY/ADD <src>... <dest>
COPY/ADD ["<src>",... "<dest>"]

Ils obéissent également aux mêmes règles : par exemple, les fichiers et répertoires doivent être présents dans le contexte de la construction.

Mais alors, pourquoi ?

La différence c’est que l’instruction ADD possèdent des fonctionnalités supplémentaires :

  • ADD permet d’ajouter des sources depuis une URL, et pas seulement une source locale
  • si la source locale est une archive dans un format reconnu (gzip, bzip2, xz, …) alors ADD va automatiquement en extraire le contenu dans la destination

Donc, j’utilise toujours ADD ?

En théorie, ADD est donc un COPY avec des fonctionnalités supplémentaires. Pour autant, le guide des bonnes pratiques Docker conseille d’utiliser l’instruction COPYde préférence, pour des raisons de transparence (en gros, pour copier des fichiers, COPY c’est plus humainement clair que ADD).
De plus, l’utilisation de l’instruction ADD est fortement découragé pour les URL. La bonne pratique est de passer plutôt par l’instruction RUN wget ... car cela permet ensuite de supprimer les fichiers qui ne sont plus utiles.

Conclusion

En conclusion, je citerai la bonne pratique Docker :

Pour les fichiers et répertoires, si vous n’avez pas besoin de la fonctionnalité d’auto-extraction d’archive, vous devriez utiliser COPY.

Sources :
https://docs.docker.com/engine/reference/builder/#add
https://docs.docker.com/engine/reference/builder/#copy
https://docs.docker.com/engine/userguide/eng-image/dockerfile_best-practices/#add-or-copy

Authentification SMTP avec Postfix et Dovecot SASL

Un serveur SMTP a habituellement deux fonctions dans une infrastructure de messagerie :

  • Recevoir les messages de l’extérieur pour les stocker dans les boites internes
  • Envoyer les messages soumis depuis les boîtes internes vers le monde extérieur

Si pour l’action « Recevoir » il n’y a généralement pas d’authentification de l’expéditeur (tout inconnu peut envoyer un mail vers votre serveur SMTP), il n’en est pas de même pour l’action « Soumission des messages ». Imaginez si tout inconnu pouvait envoyer des mails depuis votre serveur SMTP ! Ce serait le paradis des spammeurs 🙂 Ces paradis existent encore, il s’agit des fameux « relais ouverts ». Heureusement, ces serveurs sont très vites mis sur des liste noires par la plupart de hébergeurs de boîtes mails. Cela signifie que si votre serveur SMTP est lui-même un relais ouvert, alors même vos messages légitimes seront mis à la poubelle par les filtres anti-spam des hébergeurs.

Par défaut, le serveur SMTP Postfix autorise la soumission des messages uniquement depuis des clients positionnés dans le même réseau que le serveur lui-même. Pas très pratique pour la mobilité ! Nous verrons donc dans cet article comment mettre en place un système d’authentification SMTP des clients avec Postfix et l’implémentation SASL Dovecot.

Article écrit avec les versions Dovecot 2.2.13 et Postfix 2.11.3.

Continuer la lecture de « Authentification SMTP avec Postfix et Dovecot SASL »

Désactiver IPv6 sous RedHat EL et CentOS 7

La solution la plus simple et efficace pour désactiver totalement la prise en charge IPv6 sous RedHat Enterprise Linux et CentOS en version 7 est de le désactiver au niveau du programme d’amorçage GRUB.

Cette solution est bien spécifique aux version 7.x de RHEL/CentOS et n’est pas compatible pour les versions antérieures.

Pour cela, éditer le fichier /etc/default/grub :

# vim /etc/default/grub

Ajouter ipv6.disable=1 à la fin du paramètre GRUB_CMDLINE_LINUX (avant le caractère ") :

GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet ipv6.disable=1"

Puis générer le fichier grub.cfg grâce à la commande grub2-mkconfig :

# grub2-mkconfig -o /boot/grub2/grub.cfg

Enfin, redémarrer le système pour la prise en compte du support IPv6 :

# reboot

Après redémarrage, si vous listez les interfaces vous ne devriez plus avoir de ligne inet6 comme ici :

AVANT

# ip addr show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever

APRES

# ip addr show dev lo
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever

Si tel est le cas, c’est bon, le support IPv6 est désactivé ! Pour le réactiver, il suffit de suivre cette même procédure en supprimant le motif ipv6.disable=1.

Nettoyer les volumes Docker orphelins

Comme je l’ai indiqué dans mes articles précédents sur les volumes, Docker ne supprime jamais de lui-même un volume lors de la disparition d’un conteneur. Ce qui signifie que vous avez probablement plein de volumes orphelins 🙂

Supprimer un volume en supprimant un conteneur

Lors de la suppression d’un conteneur, vous avez la possibilité de suprrimer explicitement le volume attaché en même temps grâce à l’option -v de la commande docker rm.

Par exemple cette commande supprime le volume 8b5 et le volume attaché :

# docker rm -v 8b5
8b5

Supprimer les conteneurs orphelins

Les conteneurs orphelins peuvent être listés avec la commande docker volume ls en spécifiant l’option -f dangling=true.

Exemple :

# docker volume ls -f dangling=true
DRIVER              VOLUME NAME
local               7a580f460fb61a5ed77b70c2e05320315de22ad9a684692854418bc77eeffa35
local               424713fe7be69256b5d876f01307db33ff969244f2618005823ad0dd5c4b4834
local               0afb23ec7f105227efd8702671133e0b4fa52d3d63e57419f76ba470124b1340
local               5449a081d53f1909e11aa8c7fe9f69626e69c34f843ae252036e65891f61f033
local               223aa9f8a5b6285912e0d3834e928b12f2304f3c63ef6624dbaad66b915cbd4f

Pour supprimer tous ces volumes en une fois, j’utilise une petite combinaison de commandes Linux :

# docker volume ls -qf dangling=true | xargs -r docker volume rm

L’option -q que j’ai ajouté correspond à l’option quiet qui n’affiche que les identifiants de volumes, sans en-tête ou colonne DRIVER

Si je liste de nouveau les volumes orphelins, je n’ai plus rien :

# docker volume ls -f dangling=true
DRIVER              VOLUME NAME

Et voilà, à vous de voir ensuite si vous voulez faire ce nettoyage manuellement régulièrement ou positionner cette routine dans un fichier cron.

Docker et les volumes de données (2/2)

Avec le premier article nous avons pu créer des volumes de données et les exploiter dans nos conteneurs. Maintenant, que se passe-t-il lorsque le conteneur doit être détruit pour être remplacer par un autre ? Que deviennent les données considérées comme « persistantes » ? Comme nous l’avons vu, le volume de données ne sera pas détruit automatiquement par Docker. Le volume sera donc « orphelin ».

Dans ce deuxième article sur la gestion des données persistantes avec Docker, nous allons voir ce qui tourne autour du recyclage des volumes, des conteneurs de données et des volumes nommés.

Continuer la lecture de « Docker et les volumes de données (2/2) »

Utiliser LMTP avec Postfix et Dovecot

Habituellement, Postfix livre les messages reçus dans les boites mails des utilisateurs grâce à ses agents de livraison appelés local (pour les utilisateurs locaux) et virtual (pour les utilisateurs virtuels). Cependant, ces techniques de livraison nécessitent que les boites mails soient physiquement accessibles par Postfix. Dans le cas présent, nous allons vouloir livrer les messages reçus par Postfix dans les boites des utilisateurs à travers le réseau. Nous allons pour cela utiliser le protocole LMTP entre l’agent de transfert (ou MTA pour Mail Transfer Agent) Postfix et l’agent de livraison (ou MDA pour Mail Delivery Agent) Dovecot.

LMTP (Local Mail Transfer Protocol) est un protocole similaire à SMTP (Simple Mail Tranfer Protocol) défini par la RFC 2033. A la différence du protocole SMTP, LMTP est destiné aux échanges vers un serveur destinataire qui ne gère pas de file d’attente des messages, ce qui est le cas par exemple d’un serveur de livraison des mails comme Dovecot.

Article écrit avec les versions Dovecot 2.2.13 et Postfix 2.11.3.

Continuer la lecture de « Utiliser LMTP avec Postfix et Dovecot »

Graphite : nettoyer les données Whisper

Whisper est la base de données utilisée par Graphite (à travers le démon Carbon) pour stocker les métriques accessibles classiquement par Grafana. Whisper est une base de données à taille fixe, similaire au produit RRD. Chaque nouveau métrique entraine la création d’un fichier possédant l’extension .wsp. Voici un exemple de fichier créé sous RedHat pour un métrique de type « CPU Idle » envoyé par collectd :

/var/lib/carbon/whisper/<prefix>/<server>/<suffix>/cpu-0/cpu-idle.wsp

Il n’y a pas de nettoyage automatique des métriques. Dans le cas d’une infrastructure de type cloud par exemple, la liste des métriques peut s’allonger indéfiniment au rythme des créations de nouvelles instances, entrainant une consommation de stockage tout aussi importante qu’inutile. Le nettoyage va consister simplement à supprimer les fichiers Whisper. J’utilise pour ma part cette routine :

# find /var/lib/carbon/whisper/ -type f -mtime +7 -name \*.wsp -delete
# find /var/lib/carbon/whisper/ -depth -type d -empty -delete

La première commande supprime tous les fichiers Whisper non modifiés depuis plus de 7 jours. Mon intervalle de collecte étant de 1 minute, ça laisse de la marge pour d’éventuels problèmes ponctuels.
La deuxième commande supprime les dossiers rendus vides par le nettoyage des fichiers.

Je pose cette routine dans un fichier cron sous /etc/cron.d/whisper-cleaner pour un nettoyage quotidien :

# cat /etc/cron.d/whisper-cleaner
0 9 * * * root (find /var/lib/carbon/whisper/ -type f -mtime +7 -name \*.wsp -delete; find /var/lib/carbon/whisper/ -depth -type d -empty -delete)

Grafana : remettre le mot de passe admin à sa valeur par défaut

Si vous arrivez sur cette page, c’est que comme moi vous avez probablement oublié le mot de passe que vous aviez défini un jour pour l’utilisateur admin dans Grafana 🙂 Dans ce cas, une solution est de redéfinir le mot de passe à sa valeur par défaut (admin) en modifiant directement la base de données.

Je vous propose ici une méthode pour les différents moteurs de base de données supportés par Grafana : MySQL, SQLite et PostgreSQL.

Continuer la lecture de « Grafana : remettre le mot de passe admin à sa valeur par défaut »

Docker et les volumes de données (1/2)

Vous venez de créer vos premiers conteneurs Docker et peut-être ne vous êtes pas encore demandé ce qu’il advient des données stockées à l’intérieur. Alors par défaut, les données contenues dans le conteneur disparaissent tout simplement avec lui lors de sa destruction. Ce peut être le comportement voulu dans la plupart des cas, mais il est parfois nécessaire de rendre les données persistantes. Par exemple, une base de données utilisateur ne devrait pas disparaitre lorsque l’on supprime le conteneur contenant le moteur de la base de données !

Docker offre plusieurs manières de gérer les données persistantes. Nous verrons dans un premier temps la notion de volume de données puis les conteneurs de données dans un deuxième article.

Continuer la lecture de « Docker et les volumes de données (1/2) »

Docker : premiers pas

Je me lance dans la découverte de Docker et quelques billets jalonneront donc ma progression dans cet univers. Ce premier billet couvre le lancement et la gestion de base d'un conteneur.

Juste pour introduire Docker en une phrase, disons que c'est un gestionnaire de conteneurs logiciels open source écrit en Go. Voilà 🙂

Pour plus d'informations, je vous conseille l'excellent site officiel qui regorge d'informations utiles et qui me servira de guide : https://www.docker.com/

Je m'appuie ici sur un Docker en version 1.4.1 installé sur une machine Ubuntu 14.10.

 

Continuer la lecture de « Docker : premiers pas »