Skip to content

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


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.


À 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).

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.

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.

Terminal window
# Installer podman-compose
sudo apt update
sudo apt install -y python3-pip
pip3 install --user podman-compose
# Ajouter ~/.local/bin au PATH
echo 'export PATH=$PATH:~/.local/bin' >> ~/.bashrc
source ~/.bashrc
# Vérifier l'installation
podman-compose --version

Créez l’arborescence pour vos données persistantes :

Terminal window
mkdir ~/stalwart-mail && cd ~/stalwart-mail
mkdir -p {stalwart,db,snappy-data}

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 services
networks:
mail-network:
driver: bridge
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”
  1. Connectez-vous à la console AWS.
  2. Allez dans Simple Email Service (SES).
  3. Dans le menu de gauche, cliquez sur SMTP Settings.
  4. Cliquez sur Create My SMTP Credentials.
  5. Donnez un nom à l’utilisateur IAM (ex: ses-smtp-user).
  6. 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) ou 465 (SSL/TLS)

⚠️ 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”
  1. Dans la console SES, allez dans Domains.
  2. Cliquez sur Verify a New Domain.
  3. Entrez votre domaine (ex: mon-domaine.fr).
  4. Activez DKIM Signing (recommandé).
  5. Suivez les instructions pour ajouter les enregistrements DNS :
    • TXT pour la vérification de propriété du domaine.
    • CNAME pour DKIM (trois enregistrements).
  6. 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 :

  1. Dans la console SES, allez dans Sending Statistics.
  2. Cliquez sur Request Production Access.
  3. 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”
  1. Démarrez les conteneurs (voir section suivante).
  2. Connectez-vous à l’interface d’administration Stalwart : http://VOTRE_IP_PUBLIQUE:8080/admin.
  3. Identifiez-vous avec admin et le mot de passe défini dans STALWART_RECOVERY_ADMIN.
  4. Allez dans SettingsMTAOutboundRoutes.
  5. 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é)
  1. 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 :

  1. Allez dans SettingsDKIM.
  2. Désactivez l’option Sign outgoing messages.
  3. 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 = false

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 sudo pour 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 :

Terminal window
sudo nano /etc/sysctl.conf
# Ajouter : net.ipv4.ip_unprivileged_port_start=25
sudo sysctl -p
Terminal window
cd ~/stalwart-mail
podman-compose down # Nettoyer les éventuels conteneurs existants
podman-compose up -d # Lancer en arrière-plan
Terminal window
# État des conteneurs
podman-compose ps
# Logs de Stalwart
podman logs stalwart-mail --tail 50
# Logs de SnappyMail
podman logs snappymail --tail 20

  1. Ouvrez votre navigateur et accédez à : http://VOTRE_IP_PUBLIQUE:8091/?admin
  2. Login : admin
  3. Mot de passe par défaut : 12345 (si vous ne l’avez pas modifié via variable d’environnement).
  4. Changez immédiatement le mot de passe admin dans SecurityAdmin password.
  1. Allez dans DomainsAdd Domain.
  2. Renseignez votre domaine (ex: mon-domaine.fr).
  3. 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).
  4. Configurez le serveur SMTP :
    • Hôte : stalwart-mail.
    • Port : 465.
    • Chiffrement : SSL/TLS.
    • Authentification : Oui.
  5. Cliquez sur Test pour valider la connexion.

Astuce : Si le test échoue sur le port 465, essayez avec le port 587 et STARTTLS.


  1. Accédez à http://VOTRE_IP:8080/admin.
  2. Connectez-vous avec admin et votre mot de passe.
  3. Allez dans AccountsAdd Account.
  4. Renseignez :
    • Login name : partie avant le @ (ex: julien).
    • Email : [email protected].
    • Mot de passe : choisissez un mot de passe fort.
  5. Sauvegardez.
Terminal window
podman exec -it stalwart-mail stalwart-cli account create [email protected]

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 :

Terminal window
dig TXT mon-domaine.fr
dig MX mon-domaine.fr
dig CNAME _domainkey.mon-domaine.fr

Envoi depuis un compte externe (Gmail, Outlook)

Section titled “Envoi depuis un compte externe (Gmail, Outlook)”
  1. Envoyez un email depuis Gmail vers [email protected].
  2. Vérifiez les logs Stalwart :
    Terminal window
    podman logs stalwart-mail | grep -i "received"
  3. 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”
  1. Depuis SnappyMail, composez un email vers votre adresse Gmail.
  2. Vérifiez les logs de Stalwart (le relais SES doit être utilisé) :
    Terminal window
    podman logs stalwart-mail | grep -i "relay"
  3. Consultez les logs SES dans la console AWS (SES → Sending Statistics).

Restreignez l’accès aux interfaces d’administration :

Terminal window
sudo ufw allow from VOTRE_IP to any port 8080
sudo ufw allow from VOTRE_IP to any port 8091
sudo ufw deny 8080
sudo ufw deny 8091

Stalwart génère automatiquement des certificats Let’s Encrypt si votre domaine est public. Assurez-vous que le port 443 est ouvert.

Pour mettre à jour les images :

Terminal window
podman-compose pull
podman-compose up -d

Vous pouvez automatiser avec un script cron ou utiliser Watchtower.


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


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.

  • 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