MailHog est un serveur SMTP. On peut lui envoyer des e-mails mais il ne les transmet jamais aux destinataires. Il les garde en mémoire et les restitue via une interface Web.
On l’utilise généralement en environnement de développement ou en test d’intégration.
Docker
Le projet a démarré en 2014. Il est fait en Go. Sa maintenance est au ralenti, plein de tickets sont ouverts et des MR sont soumises. A suivre : fork ?
Les auteurs ont publié une image Docker : mailhog/mailhog
.
Mais elle n’est pas mise à jour.
Il existe plein d’alternatives comme druidfi/mailhog
qui est mise à jour régulièrement et est plus petite (8 Mo, from scratch) que l’originale (400 Mo).
docker run --publish 127.0.0.1:2025:1025 --publish 127.0.0.1:8025:8025 --detach druidfi/mailhog
Le port 1025 est utilisé pour l’envoi de messages en SMTP. Le port 8025 est utilisé pour consulter les messages via l’interface Web.
Docker Compose
smtp:
image: druidfi/mailhog
ports:
- "127.0.0.1:2025:1025"
- "127.0.0.1:8025:8025"
JUnit / Testcontainer
Ça peut aussi se démarrer avec Testcontainer pour des tests d’intégration automatisés.
GenericContainer<?> smtp = new GenericContainer<>("druidfi/mailhog")
.withExposedPorts(1025, 8025);
smtp.start();
int smtpPort = smtp.getMappedPort(1025);
API
MailHog expose ses services en API Web. Les principales opérations sont les suivantes :
-
Lire tous les messages :
GET /api/v2/messages
-
Supprimer tous les messages :
DELETE /api/v1/messages
-
Lire un message :
GET /api/v1/messages/{id}
-
Supprimer un message :
DELETE /api/v1/messages/{id}
Il y a un piège dans l’API. Elle produit du contenu au format JSON, pour lequel on attend habituellement un type Mime "application/json". Or MailHog déclare un header "text/json", qui n’est pas compris nativement par tous les clients.
Par exemple, avec RestTemplate de Spring Framework, il faut déclarer ce type spécifiquement.
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setSupportedMediaTypes(List.of(new MediaType("text", "json")));
RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory());
restTemplate.setMessageConverters(List.of(converter));
Avancé
Stockage des messages
Par défaut, les messages sont stockés en mémoire uniquement.
MailHog peut être paramétré pour rendre les messages persistants, grâce au paramètre -storage
ou à la variable d’environnement MH_STORAGE
.
Stockage en fichiers
docker run --name mailhog --rm --detach \
--publish 127.0.0.1:2025:1025 --publish 127.0.0.1:8025:8025 \
mailhog/mailhog -storage=maildir -maildir-path=/var/mail
Le stockage en répertoire ne fonctionne pas avec l’image druidfi/mailhog
car elle est construite from scratch.
Stockage MongoDB 4.x (docker)
docker run --network mail --name mh-mongo \
--env MONGO_INITDB_ROOT_USERNAME=mongoadmin \
--env MONGO_INITDB_ROOT_PASSWORD=secret \
--rm --detach mongo:4
docker run --network mail --name mailhog --rm --detach \
--publish 127.0.0.1:2025:1025 --publish 127.0.0.1:8025:8025 \
mailhog/mailhog -storage=mongodb -mongo-uri=mh-mongo
Ça ne marche pas avec un MongoDB version 5 avec authentification.
Stockage MongoDB 4.x (clever cloud)
# Information à récupérer dans la console de l'add-on
username=kfif5tflgdf4lskfme23
password=lhy5cGkEsVB65r8gt6r
db=bpa2demglxd23se
host=$db-mongodb.services.clever-cloud.com
docker run --name mailhog --rm --detach \
--publish 127.0.0.1:2025:1025 --publish 127.0.0.1:8025:8025 \
mailhog/mailhog -storage=mongodb \
-mongo-uri=$username:$password@$host/$db -mongo-db=$db
J’ai testé avec une base MongoDB de Dev (gratuite), et ça fonctionne sans problème. C’est un vieux add-on, en version 4.0.3.
Il semble que MailHog ne sache pas utiliser MongoDB Atlas, mais je ne sais pas pourquoi.
En tout cas, j’ai testé avec un cluster gratuit, en version 5.0, et ça ne fonctionne pas.
L’erreur rencontrée est Error connecting to MongoDB: no reachable servers
.
Envoi réel des e-mails
L’introduction que MailHog ne transmettait jamais les messages aux destinataires.
C’est vrai dans la configuration par défaut, mais ça peut aussi être modifié pour qu’il fonctionne en relais, grâce au paramètre -outgoing-smtp
ou à la variable d’environnement MH_OUTGOING_SMTP
.
La première étape est de définir un fichier de configuration en JSON.
{
"ovh": {
"name": "ovh",
"host": "smtp.ovh.net",
"port": "25",
"email": "noreply@jtips.info",
"username": "mail@jtips.info",
"password": "fjzlgre36vqz",
"mechanism": "PLAIN"
}
}
la valeur de "name" doit être identique à la clé ("ovh" ).
|
Puis on rend le fichier disponible depuis le conteneur, via un volume.
docker run --name mailhog --rm --detach \
--publish 127.0.0.1:2025:1025 --publish 127.0.0.1:8025:8025 \
--volume $(pwd)/outgoing.json:/conf/outgoing.json \
druidfi/mailhog -outgoing-smtp=/conf/outgoing.json
Ensuite, on peut libérer (release) les messages depuis l’interface graphique.
L’API peut aussi être utilisée avec un POST sur /api/v1/messages/{message-id}}/release
, en passant le nom du serveur SMTP à utiliser {"name":"ovh"}
.
id=$(curl -s http://localhost:8025/api/v2/messages | jq --raw-output .items[0].ID)
curl http://localhost:8025/api/v1/messages/$id/release -X POST --data '{"name": "ovh"}'
Références