Déployer un serveur mail léger avec Stalwart + SnappyMail sur Podman Compose (AWS t3.small avec Amazon SES)
Bonne lecture et bon apprentissage !
Junior TSAFACK – 10/08/2026
⏱️ Temps de lecture estimé : 25 minutes
Introduction
Section titled “Introduction”Pourquoi ce cours ?
Section titled “Pourquoi ce cours ?”Ce cours s’adresse aux administrateurs système, développeurs ou étudiants qui souhaitent déployer leur propre serveur mail sur le cloud AWS avec une empreinte mémoire minimale et une gestion simplifiée.
Stalwart Mail Server est un serveur mail moderne écrit en Rust :
- Léger : moins de 10 Mo de RAM au repos.
- Performant : conçu pour gérer des millions de messages.
- Sécurisé : supporte TLS, SPF, DKIM, DMARC, etc.
SnappyMail est un client webmail moderne, rapide et riche en fonctionnalités.
Podman est un moteur de conteneurs daemonless et rootless (sécurisé), idéal pour des environnements contraints comme une instance AWS t3.small (1 vCPU, 2 Go RAM).
Amazon SES (Simple Email Service) est un service d’envoi d’emails fiable et économique, qui nous servira de relais SMTP pour contourner le blocage du port 25 par AWS.
Objectifs pédagogiques
Section titled “Objectifs pédagogiques”À l’issue de ce cours, vous serez capable de :
- Déployer Stalwart Mail Server et SnappyMail avec Podman Compose.
- Configurer un serveur mail sur AWS en utilisant Amazon SES comme relais SMTP.
- Gérer la persistance des données, les logs et les mises à jour.
- Configurer les enregistrements DNS (SPF, DKIM, DMARC) pour une bonne délivrabilité.
- Comprendre et résoudre les problèmes spécifiques à Podman (rootless, ports, permissions).
Prérequis
Section titled “Prérequis”Avant de commencer, assurez-vous d’avoir :
- Une instance AWS t3.small (ou équivalent) avec Debian 13 (Trixie) ou Ubuntu 24.04 LTS.
- Un domaine (ex:
mon-domaine.fr) avec accès à la gestion des enregistrements DNS. - Un compte Amazon Web Services (AWS) avec accès à Amazon SES.
- Les ports suivants ouverts dans le groupe de sécurité AWS (entrant) :
25(SMTP) – entrant uniquement (le sortant est bloqué par défaut, d’où le relais SES).465(SMTPS),587(Submission),993(IMAPS),995(POP3s).8080(interface d’administration Stalwart).8091(interface web SnappyMail).
- Podman et Podman Compose déjà installés (voir le cours préalable sur l’installation de Podman sur Debian 13).
1. Pourquoi utiliser un relais SMTP sur AWS ?
Section titled “1. Pourquoi utiliser un relais SMTP sur AWS ?”Le problème : le port 25 est bloqué par défaut
Section titled “Le problème : le port 25 est bloqué par défaut”AWS bloque par défaut le trafic sortant sur le port 25 pour limiter le spam. Même si vous ouvrez le port 25 entrant dans le groupe de sécurité, vous ne pourrez pas envoyer d’emails directement vers l’extérieur via ce port.
La solution : Amazon SES
Section titled “La solution : Amazon SES”Amazon SES est un service de relais SMTP qui :
- Permet d’envoyer des emails vers l’extérieur via ses serveurs (port 587 ou 465).
- Assure une excellente délivrabilité (réputation des IP gérée par AWS).
- Est économique : 0,10 $ pour 1 000 emails, avec un niveau gratuit de 62 000 emails/mois pendant 12 mois.
- Gère automatiquement la signature DKIM, ce qui simplifie la configuration.
2. Installation de Podman Compose (si ce n’est pas déjà fait)
Section titled “2. Installation de Podman Compose (si ce n’est pas déjà fait)”Si vous avez déjà suivi le cours sur l’installation de Podman, passez cette étape.
# Installer podman-composesudo apt updatesudo apt install -y python3-pippip3 install --user podman-compose
# Ajouter ~/.local/bin au PATHecho 'export PATH=$PATH:~/.local/bin' >> ~/.bashrcsource ~/.bashrc
# Vérifier l'installationpodman-compose --version3. Structure des dossiers
Section titled “3. Structure des dossiers”Créez l’arborescence pour vos données persistantes :
mkdir ~/stalwart-mail && cd ~/stalwart-mailmkdir -p {stalwart,db,snappy-data}4. Fichier docker-compose.yml complet
Section titled “4. Fichier docker-compose.yml complet”Créez le fichier docker-compose.yml avec le contenu suivant :
services: # Serveur mail Stalwart stalwart-mail: image: stalwartlabs/stalwart:latest container_name: stalwart-mail restart: always # user: "0:0" permet d'écrire dans les volumes en mode rootless # (l'UID 0 du conteneur est mappé sur l'UID de l'utilisateur hôte) user: "0:0" ports: - "25:25" - "465:465" - "587:587" - "993:993" - "995:995" - "8080:8080" volumes: - ./stalwart:/etc/stalwart - ./db:/var/lib/stalwart environment: - STALWART_LOG_LEVEL=info # Mot de passe admin prédéfini (obligatoire pour le premier démarrage) - STALWART_RECOVERY_ADMIN=admin:MonMotDePasseComplexe123 # ⚠️ Ces variables peuvent ne pas fonctionner sur toutes les versions de Stalwart # Nous utiliserons l'interface d'administration pour configurer le relais SES # - STALWART_SMTP_RELAY_HOST=email-smtp.region.amazonaws.com # - STALWART_SMTP_RELAY_PORT=587 # - STALWART_SMTP_RELAY_USERNAME=... # - STALWART_SMTP_RELAY_PASSWORD=... networks: - mail-network
# Client webmail SnappyMail snappymail: image: djmaze/snappymail:latest container_name: snappymail restart: unless-stopped ports: - "8091:8888" volumes: - ./snappy-data:/var/lib/snappymail environment: - UPLOAD_MAX_SIZE=25M - MEMORY_LIMIT=128M networks: - mail-network
# Réseau interne pour la communication entre servicesnetworks: mail-network: driver: bridgeExplication des options importantes :
Section titled “Explication des options importantes :”| Option | Utilité |
|---|---|
user: "0:0" |
Permet au conteneur d’écrire dans les volumes montés en rootless (l’UID 0 du conteneur est mappé sur votre UID hôte). |
STALWART_RECOVERY_ADMIN |
Définit le mot de passe administrateur dès le premier démarrage, évitant de chercher dans les logs. |
networks: mail-network |
Place les deux conteneurs sur le même réseau pour qu’ils communiquent via leurs noms (stalwart-mail, snappymail). |
restart: unless-stopped |
Redémarre automatiquement le conteneur en cas de panne (sauf si arrêté manuellement). |
5. Configuration d’Amazon SES pour l’envoi d’emails
Section titled “5. Configuration d’Amazon SES pour l’envoi d’emails”Étape 1 : Générer les identifiants SMTP
Section titled “Étape 1 : Générer les identifiants SMTP”- Connectez-vous à la console AWS.
- Allez dans Simple Email Service (SES).
- Dans le menu de gauche, cliquez sur SMTP Settings.
- Cliquez sur Create My SMTP Credentials.
- Donnez un nom à l’utilisateur IAM (ex:
ses-smtp-user). - Téléchargez et conservez précieusement le fichier CSV contenant :
- SMTP Username (ex:
AKIA...) - SMTP Password (une longue chaîne)
- SMTP Server (ex:
email-smtp.us-east-1.amazonaws.com) - Port :
587(STARTTLS) ou465(SSL/TLS)
- SMTP Username (ex:
⚠️ Note importante : Le SMTP Username n’est pas votre adresse email, et le SMTP Password n’est pas votre mot de passe AWS.
Étape 2 : Vérifier votre domaine dans SES
Section titled “Étape 2 : Vérifier votre domaine dans SES”- Dans la console SES, allez dans Domains.
- Cliquez sur Verify a New Domain.
- Entrez votre domaine (ex:
mon-domaine.fr). - Activez DKIM Signing (recommandé).
- Suivez les instructions pour ajouter les enregistrements DNS :
- TXT pour la vérification de propriété du domaine.
- CNAME pour DKIM (trois enregistrements).
- Attendez la propagation DNS (quelques minutes à quelques heures).
Étape 3 : Passer en production (si nécessaire)
Section titled “Étape 3 : Passer en production (si nécessaire)”Par défaut, SES est en mode “sandbox” : vous ne pouvez envoyer que vers des emails vérifiés. Pour envoyer vers n’importe quel destinataire :
- Dans la console SES, allez dans Sending Statistics.
- Cliquez sur Request Production Access.
- Remplissez le formulaire (justifiez votre utilisation) et attendez l’approbation.
6. Configuration du relais SMTP dans Stalwart
Section titled “6. Configuration du relais SMTP dans Stalwart”Méthode recommandée : via l’interface d’administration web
Section titled “Méthode recommandée : via l’interface d’administration web”- Démarrez les conteneurs (voir section suivante).
- Connectez-vous à l’interface d’administration Stalwart :
http://VOTRE_IP_PUBLIQUE:8080/admin. - Identifiez-vous avec
adminet le mot de passe défini dansSTALWART_RECOVERY_ADMIN. - Allez dans Settings → MTA → Outbound → Routes.
- Créez une nouvelle route avec les paramètres suivants :
| Champ | Valeur |
|---|---|
| Type | Relay |
| Relay Host | email-smtp.us-east-1.amazonaws.com (ou votre région) |
| Port | 587 |
| Protocol | SMTP |
| Authentication | Activé |
| Username | Votre SMTP Username SES |
| Password | Votre SMTP Password SES |
| Implicit TLS | Désactivé (STARTTLS sera utilisé) |
- Sauvegardez.
Point critique : Désactiver la signature DKIM dans Stalwart
Section titled “Point critique : Désactiver la signature DKIM dans Stalwart”Amazon SES ajoute sa propre signature DKIM aux emails sortants. Si Stalwart signe également les emails avec DKIM, vous vous retrouverez avec deux en-têtes DKIM-Signature, ce qui est rejeté par SES avec l’erreur 554 Transaction failed: Duplicate header 'DKIM-Signature'.
Solution : Désactiver DKIM dans la configuration de Stalwart
Via l’interface d’administration :
- Allez dans Settings → DKIM.
- Désactivez l’option Sign outgoing messages.
- Sauvegardez.
Ou directement dans le fichier de configuration (./stalwart/config.toml) :
[auth.dkim]sign = false
[report.dkim]sign = false
[report.dsn]sign = false
[report.dmarc]sign = false
[report.dmarc.aggregate]sign = false
[report.spf]sign = false
[report.tls.aggregate]sign = false
[sieve.trusted]sign = false7. Démarrer les services
Section titled “7. Démarrer les services”Avant de démarrer : gérer le port 25
Section titled “Avant de démarrer : gérer le port 25”Si le port 25 est bloqué pour le trafic sortant, cela n’affecte pas la réception. Mais pour que Podman puisse exposer le port 25 (entrant), vous devez soit :
- Définir
net.ipv4.ip_unprivileged_port_start=25(voir section Dépannage). - Utiliser
sudopour lancer les conteneurs (mode rootfull). - Rediriger le port 25 vers un port >1024 (ex: 2525) et utiliser iptables.
Pour ce cours, nous supposons que vous avez configuré sysctl comme suit :
sudo nano /etc/sysctl.conf# Ajouter : net.ipv4.ip_unprivileged_port_start=25sudo sysctl -pLancement des conteneurs
Section titled “Lancement des conteneurs”cd ~/stalwart-mailpodman-compose down # Nettoyer les éventuels conteneurs existantspodman-compose up -d # Lancer en arrière-planVérification
Section titled “Vérification”# État des conteneurspodman-compose ps
# Logs de Stalwartpodman logs stalwart-mail --tail 50
# Logs de SnappyMailpodman logs snappymail --tail 208. Configuration de SnappyMail
Section titled “8. Configuration de SnappyMail”Première connexion
Section titled “Première connexion”- Ouvrez votre navigateur et accédez à :
http://VOTRE_IP_PUBLIQUE:8091/?admin - Login :
admin - Mot de passe par défaut :
12345(si vous ne l’avez pas modifié via variable d’environnement). - Changez immédiatement le mot de passe admin dans Security → Admin password.
Ajout du domaine
Section titled “Ajout du domaine”- Allez dans Domains → Add Domain.
- Renseignez votre domaine (ex:
mon-domaine.fr). - Configurez le serveur IMAP :
- Hôte :
stalwart-mail(nom du conteneur). - Port :
993. - Chiffrement :
SSL/TLS. - Vérifier le certificat : désactivé (si vous utilisez un certificat auto-signé en test).
- Hôte :
- Configurez le serveur SMTP :
- Hôte :
stalwart-mail. - Port :
465. - Chiffrement :
SSL/TLS. - Authentification : Oui.
- Hôte :
- Cliquez sur Test pour valider la connexion.
Astuce : Si le test échoue sur le port 465, essayez avec le port 587 et STARTTLS.
9. Gestion des utilisateurs Stalwart
Section titled “9. Gestion des utilisateurs Stalwart”Via l’interface d’administration
Section titled “Via l’interface d’administration”- Accédez à
http://VOTRE_IP:8080/admin. - Connectez-vous avec
adminet votre mot de passe. - Allez dans Accounts → Add Account.
- Renseignez :
- Login name : partie avant le
@(ex:julien). - Email :
[email protected]. - Mot de passe : choisissez un mot de passe fort.
- Login name : partie avant le
- Sauvegardez.
Via la ligne de commande (optionnel)
Section titled “Via la ligne de commande (optionnel)”10. Configuration des enregistrements DNS
Section titled “10. Configuration des enregistrements DNS”Pour que vos emails soient délivrés correctement, configurez les enregistrements suivants chez votre registrar :
| Type | Nom | Valeur | Commentaire |
|---|---|---|---|
| A | mail.mon-domaine.fr |
IP publique de votre instance AWS | Pour accéder à l’interface web |
| MX | mon-domaine.fr |
mail.mon-domaine.fr (priorité 10) |
Routage des emails entrants |
| SPF | mon-domaine.fr |
v=spf1 include:amazonses.com ~all |
Autorise SES à envoyer pour votre domaine |
| DKIM | (CNAME fournis par SES) | Valeurs SES | Ajoutés lors de la vérification du domaine |
| DMARC | _dmarc.mon-domaine.fr |
v=DMARC1; p=quarantine; rua=mailto:[email protected] |
Protège contre l’usurpation d’identité |
Vérifiez la propagation avec :
dig TXT mon-domaine.frdig MX mon-domaine.frdig CNAME _domainkey.mon-domaine.fr11. Test complet
Section titled “11. Test complet”Envoi depuis un compte externe (Gmail, Outlook)
Section titled “Envoi depuis un compte externe (Gmail, Outlook)”- Envoyez un email depuis Gmail vers
[email protected]. - Vérifiez les logs Stalwart :
Terminal window podman logs stalwart-mail | grep -i "received" - Connectez-vous à SnappyMail avec
[email protected]et vérifiez la réception.
Envoi depuis SnappyMail vers l’extérieur
Section titled “Envoi depuis SnappyMail vers l’extérieur”- Depuis SnappyMail, composez un email vers votre adresse Gmail.
- Vérifiez les logs de Stalwart (le relais SES doit être utilisé) :
Terminal window podman logs stalwart-mail | grep -i "relay" - Consultez les logs SES dans la console AWS (SES → Sending Statistics).
12. Sécurisation supplémentaire
Section titled “12. Sécurisation supplémentaire”Firewall (UFW)
Section titled “Firewall (UFW)”Restreignez l’accès aux interfaces d’administration :
sudo ufw allow from VOTRE_IP to any port 8080sudo ufw allow from VOTRE_IP to any port 8091sudo ufw deny 8080sudo ufw deny 8091Certificats TLS
Section titled “Certificats TLS”Stalwart génère automatiquement des certificats Let’s Encrypt si votre domaine est public. Assurez-vous que le port 443 est ouvert.
Mises à jour automatiques
Section titled “Mises à jour automatiques”Pour mettre à jour les images :
podman-compose pullpodman-compose up -dVous pouvez automatiser avec un script cron ou utiliser Watchtower.
13. Dépannage fréquent
Section titled “13. Dépannage fréquent”| Problème | Cause | Solution |
|---|---|---|
rootlessport cannot expose privileged port 25 |
Port <1024 non autorisé en rootless |
Appliquer net.ipv4.ip_unprivileged_port_start=25 dans /etc/sysctl.conf |
IO error: Permission denied sur /var/lib/stalwart |
Problème de mappage UID | Utiliser user: "0:0" dans le compose |
| Échec de connexion IMAP dans SnappyMail | Conteneurs sur des réseaux différents | Vérifier le network: mail-network |
Duplicate header 'DKIM-Signature' |
Stalwart et SES signent tous les deux | Désactiver DKIM dans Stalwart |
| Emails envoyés mais non reçus | Problème DNS ou SPF | Vérifier les enregistrements SPF et MX |
554 Message rejected |
Compte SES en sandbox | Demander la production access |
SnappyMail affiche Connection refused |
Stalwart n’est pas démarré | Vérifier podman ps et les logs |
14. Ressources et références
Section titled “14. Ressources et références”- Documentation officielle de Stalwart
- Documentation officielle de SnappyMail
- Podman Compose
- Amazon SES - Guide de l’utilisateur
- Guide de configuration DNS pour Stalwart
Conclusion
Section titled “Conclusion”Vous avez désormais un serveur mail complet, léger et sécurisé sur AWS, utilisant Amazon SES comme relais SMTP pour contourner les limitations de ports.
Ce déploiement consomme moins de 500 Mo de RAM en production (Stalwart seul tourne à ~10 Mo) et peut facilement être étendu (plusieurs domaines, utilisateurs, etc.).
Les avantages de cette architecture :
- Économique : coût quasi nul pour un usage modéré.
- Robuste : Podman rootless + relais SES = sécurité et fiabilité.
- Maintenable : tout est conteneurisé, les mises à jour sont simples.
Prochaines étapes
Section titled “Prochaines étapes”- Configurer des alias et des redirections dans Stalwart.
- Mettre en place des sauvegardes automatiques des volumes (
./stalwart,./db,./snappy-data). - Monitorer avec Prometheus + Grafana (Stalwart expose des métriques sur le port 9090).
- Ajouter un reverse proxy (Traefik, Nginx) pour exposer SnappyMail et l’admin via HTTPS.
- Automatiser les mises à jour avec Watchtower.
Bonne continuation !
Junior TSAFACK – 10/08/2026