Envoyer un email en local en quelques secondes avec Maildev et Docker


Contexte

En tant que développeur informatique, Il nous arrive souvent de mettre en place une fonctionnalité liée à un email – exemple: envoi d’un email de confirmation à la soumission d’un formulaire.

Aussi, on aimerait bien tester plusieurs choses sur cette fonctionnalité :

  • Les caractères contenus dans l’objet du mail sont-ils bien encodés ?
  • Les images dans le corps du mail sont-elles affichées correctement ?
  • Les destinataires que nous avons spécifiés dans notre script sont-ils bien affichés dans le champ « To » ou reçoivent-ils tous le mail envoyé ?
  • Les pièces jointes ont-elles été bien ajoutées ?
  • etc…

Lorsqu’on travaille en local, Ce test est assez fastidieux. Des solutions existent. Cependant, la mise en place est moins aisée.

On peut par exemple :

  • Configurer un smtp externe par exemple – l’adresse smtp.gmail.com, notre adresse gmail comme identifiant et le mot de passe de notre adresse email – On ajoute ces informations dans notre fichier de configuration php (php.ini) et le tour est joué.
  • Configurer Pegasus Mail et Mercury . Ce qui nous contraint à créer des utilisateurs locaux. Ces utilisateurs doivent avoir l’adresse : moi@localhost. Il va falloir également modifier dans nos scripts. Ce n’est pas vraiment top comme solution.
  • Ou utiliser maildev. Et là, on va être bien…

Nous nous intéresserons à maildev dans cet article. Parce que maildev est facile à mettre en place. Elle est intuitive, simple et claire. De plus, elle est développée en nodejs.

Maildev

Maildev est une application nodejs. Elle intercepte le port smtp (généralement ce port a le numéro : 25 ) . Elle redirige ensuite les mails écoutés par ce port vers l’application maildev.

Avec maildev, il est possible de :

  • Visualiser le format de l’email en texte brut ou en html.
  • Tester l’affichage de l’email sur n’importe quelle taille d’écran – un téléphone par exemple ou une tablette.
  • Recevoir un email avec des pièces jointes.
  • Exporter un email au format .eml

Maildev peut être utilisé de 2 façons:

  • via une interface en ligne accessible via une URL – exemple: http://localhost:8001/#/
  • Dans le code source javascript d’une application.

Il est possible d’installer maildev :

  • via nodejs
    npm install -g maildev et ensuite executer la commande maildev (depuis n’importe quel dossier) pour la lancer
  • Via docker
    docker pull djfarrelly/maildev puis executer la commande docker run -p 1080:80 -p 1025:25 djfarrelly/maildev(depuis n’importe quel dossier) pour la lancer.
  • Via git et nodejs
    git clone git@github.com:djfarrelly/MailDev.git puis npm install -g ./maildev
    et ensuite executer la commande maildev(depuis n’importe quel dossier) pour la lancer.

Nous choisissons la méthode d’installation via docker. Nous allons nous servir de docker-compose plutôt que d’utiliser la commande 2 dans la liste ci-dessus.

docker-compose

Docker compose (ou Compose) est un outil pour définir et lancer un container Docker multi-applications. Un fichier yaml est utilisé pour configurer les différents services à lancer. Il est ensuite possible de lancer tous les services configurés grâce à une commande.

Nous créons 2 services :

  • maildev
  • php7.3

php7.3 nous permet de tester un script php pour l’envoi de mail.

Créons un fichier docker-compose.yml et ajoutons le contenu suivant :

version: '3'
services:
###########################
# Setup the PHP container
###########################
    phpt3:
        container_name: phpt3
        build: dockerapps/php/
        expose:
            - 9000

        volumes:
            - ./www:/var/www/
            - ./dockerapps/php/additionnal.ini:/usr/local/etc/php/conf.d/additionnal.ini
        environment:
            - maildev_host=maildevt3
        depends_on:
            - maildevt3
###########################
# Setup the maildev container
# Lancer l'URL http://localhost:8003/#/ et c'est tout
###########################
    maildevt3:
        container_name: maildevt3
        image: djfarrelly/maildev
        ports:
            - 8003:80

Nous allons ensuite définir notre environnement pour le service phpt3. Cet environnement se définit dans un fichier Dockerfile que nous allons placer dans le dossier dockerapps/php/ Ce dossier étant relatif à docker-compose.yml.

Exemple: Si on a créé le fichier docker-compose.yml ici C:dockerdocker-compose.yml

On aura l’aroborescence suivante :

  • C:dockerdocker-compose.yml
  • C:dockerdockerappsphp

Dockerfile

DockerFile est un fichier texte. Il contient des instructions (lignes de commandes) qui seront lues par Docker pour construire l’image définie dans notre fichier docker-compose.yml.

Notre Dockerfile contiendra les instructions suivantes :

  • Installation de quelques packages : ssmtp, mailutils, vim, curl…
  • Installation de php7.3-fpm et de ses extensions : GD, mysqli, zip, intl
  • Création d’un fichier additionnal.ini qui permet de surcharger une directive déclarée dans php.ini
  • Installation de composer
  • Configuration du sendmail pour pouvoir utiliser maildev

Voici son contenu

FROM php:7.3-fpm

# install the PHP extensions we need
RUN apt-get update 
    && apt-get install -y --no-install-recommends ssmtp mailutils vim curl debconf subversion git apt-transport-https apt-utils 
    build-essential locales acl mailutils wget nodejs 
    gnupg gnupg1 gnupg2 
    zlib1g-dev zlib1g-dev libicu-dev g++ 
    sudo

# Install GD
RUN apt-get install -y libfreetype6-dev libjpeg62-turbo-dev libpng-dev
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ 
RUN docker-php-ext-install -j$(nproc) gd
RUN docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/
RUN docker-php-ext-install gd

# MYSQLI 
RUN docker-php-ext-install mysqli && docker-php-ext-enable mysqli

# Install ext-zip
RUN apt-get install -y unzip libzip-dev
RUN docker-php-ext-install zip

RUN docker-php-ext-configure intl
RUN docker-php-ext-install pdo_mysql json calendar intl

ADD php.ini /usr/local/etc/php/php.ini
COPY additionnal.ini /usr/local/etc/php/conf.d/

COPY php-fpm-pool.conf  /usr/local/etc/php/pool.d/www.conf

RUN rm -rf /var/lib/apt/lists/* 
    echo "en_US.UTF-8 UTF-8" > /etc/locale.gen && 
    echo "fr_FR.UTF-8 UTF-8" >> /etc/locale.gen && 
    locale-gen

# Install Composer
RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
RUN composer --version

# set up sendmail config, see http://linux.die.net/man/5/ssmtp.conf for options
RUN echo "hostname=localhost.localdomain" > /etc/ssmtp/ssmtp.conf
RUN echo "mailhub=maildevt3" >> /etc/ssmtp/ssmtp.conf
# The above 'maildevt3' is the name you used for the link command
# in your docker-compose file or docker link command.
# Docker automatically adds that name in the hosts file
# of the container you're linking MailDev to.

# Set up php sendmail config
RUN echo "sendmail_path=sendmail -i -t" >> /usr/local/etc/php/conf.d/php-sendmail.ini

# Fully qualified domain name configuration for sendmail on localhost.
# Without this sendmail will not work.
# This must match the value for 'hostname' field that you set in ssmtp.conf.
RUN echo "localhost localhost.localdomain" >> /etc/hosts 

WORKDIR /var/www/

EXPOSE 9000
CMD ["php-fpm"]

dockerapps/php/additionnal.ini

display_errors = On
display_startup_errors = On
error_reporting = E_ALL

upload_max_filesize = 100M
post_max_size = 100M

date.timezone = Europe/Paris
memory_limit=256M

smtp_port = 25
max_execution_time = 0

Construction du container et lancement

Grâce aux 2 commandes suivantes :

docker-compose build
docker-compose up -d

maildev

Ouvrir un navigateur et aller à l’URL http://localhost:8003/

Tester l’envoi de mail

Créons un fichier nommé test_mail.php comme ceci

<?php
$t = mail('moi@gmail.com','test Maildev ' . __FILE__,'test','From:toi@gmail.com');
var_dump($t);

Et executer ce fichier en ligne de commande grâce à l’exécutable php comme ceci – par exemple

php /chemin/vers/test_mail.php

puis vérifier le résultat dans http://localhost:8003/

Et voici le résultat dans maildev