Stalwart Common — Configuration d'application partagée
Stalwart_Common est la couche d'application partagée pour Stalwart Mail Server.
Elle n'est pas déployée seule ; elle fournit plutôt la configuration spécifique à
Stalwart sur laquelle Stalwart_GKE s'appuie. Il n'existe pas de
variante Cloud Run (voir §6). Les utilisateurs finaux ne
configurent jamais cette couche directement — elle n'a pas ses propres entrées
d'interface utilisateur de déploiement — mais comprendre ce qu'elle fournit
explique les valeurs par défaut que vous voyez dans le guide de la plateforme.
Pour l'infrastructure qui provisionne et exécute Stalwart, consultez le guide de la plateforme (Stalwart_GKE) et les guides de base (App_GKE, App_Common).
1. Ce que cette couche fournit
| Domaine | Fourni par Stalwart_Common | Où cela apparaît |
|---|---|---|
| Secrets d'application | Aucun. L'identifiant de la base de données est créé par la fondation ; l'administrateur de démarrage est fourni par l'opérateur comme STALWART_RECOVERY_ADMIN | Les sorties secret_ids / secret_values sont vides |
| Image de conteneur | Enveloppe l'image officielle stalwartlabs/stalwart (tag par défaut v0.16.22) avec un point d'entrée qui génère config.json ; construit via Cloud Build | Sortie container_image du déploiement de la plateforme |
| Moteur de base de données | Cloud SQL pour MySQL 8.0 (database_type = "MYSQL_8_0"), accessible via l'IP privée sans Auth Proxy (enable_cloudsql_volume = false) | §Base de données dans le guide de la plateforme |
| Démarrage de la base de données | Aucun job. L'étape db-create de la fondation crée la base de données et l'utilisateur ; Stalwart crée son propre schéma lors de la première connexion | initialization_jobs est vide sauf si vous fournissez des jobs |
| Stockage d'objets | Ne déclare aucun bucket | Sortie storage_buckets (vide) |
| Paramètres de base | container_port = 443 ; STALWART_PUBLIC_URL (vide) et STALWART_DATASTORE_TYPE (MySql) | Comportement de l'application dans le guide de la plateforme |
| Vérifications de santé | Transmet les sondes qui lui sont données (le module de plateforme fournit des sondes TCP sur 443) | §Observabilité dans le guide de la plateforme |
2. Modèle de configuration de Stalwart
Stalwart divise sa configuration en deux :
/etc/stalwart/config.jsonne contient que l'objet DataStore — le fichier est cet objet, indexé par un discriminateur@type(MySql,PostgreSql, et d'autres variantes que ce module n'utilise pas). Il n'est pas livré dans l'image.- Tout le reste — domaines, écouteurs, TLS, le répertoire d'authentification —
réside dans la base de données et est géré via l'API de Stalwart avec
stalwart-cli.
Le CMD de l'image est --config /etc/stalwart/config.json. Parce que App_GKE n'a
aucun moyen de monter un ConfigMap dans le conteneur de l'application, Terraform ne peut pas projeter
le fichier, donc cette couche construit une image wrapper mince qui le génère au
démarrage du conteneur.
3. Image de conteneur et point d'entrée
Le Dockerfile est FROM stalwartlabs/stalwart:${STALWART_VERSION}. L'argument de construction
est spécifique à l'application (le générique APP_VERSION que la fondation injecte n'est pas
utilisé) ; le tag par défaut est v0.16.22, et le application_version propre au module de plateforme
est la valeur qui prend effet. Le Dockerfile passe en root uniquement pour copier le point d'entrée,
revient à l'utilisateur non privilégié stalwart de l'image (uid 2000, qui possède /etc/stalwart et /var/lib/stalwart),
définit le nouveau ENTRYPOINT, et redéfinit CMD ["--config", "/etc/stalwart/config.json"] —
Docker réinitialise un CMD hérité chaque fois qu'un Dockerfile définit ENTRYPOINT, et un
Stalwart démarré sans son argument de configuration ouvre le port 8080 en mode bootstrap.
scripts/entrypoint.sh (POSIX sh, nu set -e) alors :
-
Refuse de démarrer sans les paramètres de la base de données.
DB_IP,DB_NAME,DB_USERetDB_PASSWORDdoivent tous être non vides ; sinon, il se termine avec un messageFATAL. Démarrer sans fichier de configuration ne ferait pas échouer — il ouvrirait 8080 et semblerait sain pour leHEALTHCHECKpropre à l'image. -
Crée
/var/log/stalwartde manière défensive. Le binaire y fait référence mais l'image ne le crée jamais ; la journalisation reste sur stdout, où Cloud Logging la collecte. -
Sélectionne le type de DataStore à partir de
STALWART_DATASTORE_TYPE—MySql(port par défaut 3306) ouPostgreSql(5432) — et se termine sur toute autre valeur. -
Écrit
config.json(umask 077), par exemple :{
"@type": "MySql",
"host": "10.x.x.x",
"port": 3306,
"database": "<database>",
"authUsername": "<user>",
"authSecret": { "@type": "EnvironmentVariable", "variableName": "DB_PASSWORD" },
"useTls": false,
"allowInvalidCerts": false
}hostestDB_IP, l'IP privée brute de Cloud SQL (DB_HOSTn'est pas utilisable : sa forme de répertoire de socket n'est pas un hôte TCP).portestDB_PORTlorsqu'il est défini.useTlsetallowInvalidCertsproviennent deSTALWART_DB_USE_TLSetSTALWART_DB_ALLOW_INVALID_CERTS, tous deux par défaut àfalse. Aucun identifiant n'est écrit dans le fichier —authSecretnomme la variable d'environnementDB_PASSWORD, que Stalwart lit à l'exécution. -
Journalise ce qu'il a fait — la cible du DataStore, si
STALWART_RECOVERY_ADMINest défini, et un rappel que 443 (pas 8080) est l'écouteur attendu — etexec/usr/local/bin/stalwartavec les arguments de l'image.
Le fichier est réécrit à chaque démarrage. /etc/stalwart n'est délibérément pas
persisté : le fichier est entièrement dérivé des variables de la plateforme, et une
copie persistée ne pourrait que dériver de la base de données réellement provisionnée.
4. Moteur de base de données
STALWART_DATASTORE_TYPE est dérivé du database_type de cette couche : toute variante MySQL
(MYSQL, MYSQL_5_6, MYSQL_5_7, MYSQL_8_0, MYSQL_8_4) rend
MySql ; tout le reste rend PostgreSql. La valeur par défaut — et, parce que le wrapper GKE
ne transmet pas son propre database_type, la valeur toujours en vigueur
— est MYSQL_8_0, le moteur contre lequel le module a été déployé et vérifié
(Stalwart a créé 27 tables lors de la première connexion).
enable_cloudsql_volume est fixé à false : le DataStore prend un hôte TCP simple,
donc un sidecar Auth Proxy ne serait jamais appelé — et dans le chemin du job, un qui
ne se termine jamais bloquerait db-create jusqu'à sa date limite.
Aucun job d'initialisation n'est défini. Fournir initialization_jobs ajoute vos propres
jobs ; aucun n'est nécessaire pour Stalwart lui-même.
5. Accès administrateur, secrets et réplicas
- Administrateur.
STALWART_RECOVERY_ADMIN, avec la valeurusername:password, appartient àsecret_environment_variables(de Secret Manager). S'il n'est pas défini, Stalwart génère un mot de passe administrateur aléatoire et l'imprime une fois dans le journal du conteneur. Les entréesadmin_usernameetadmin_emailde cette couche sont uniquement informatives. - Secrets. Cette couche ne crée aucun secret et n'active aucune API.
- URL publique.
STALWART_PUBLIC_URLest l'URL de base que Stalwart publie pour la découverte OAuth, OIDC et JMAP. Elle est vide par défaut à dessein — une mauvaise valeur est transmise aux clients dans les documents de découverte. - Réplica unique. L'exécution de plusieurs réplicas Stalwart nécessite son
coordinateur, qui a besoin de Redis. La connexion Redis de Stalwart est une URL
(
redis://user:pass@host:port), donc une chaîne AUTH Memorystore devrait être encodée en pourcentage ; le module ne le fait pas et est conçu pour exécuter un réplica. (Cette couche transmetmax_instance_countsans modification, donc la valeur du module de plateforme décide.)
6. Pourquoi GKE uniquement
- Protocole. SMTP, IMAP, POP3 et ManageSieve sont des protocoles ligne par ligne ; Cloud Run ne transmet que HTTP/gRPC.
- Le contrat
$PORTest inversé. Stalwart sert normalement sur le port 443. Le port 8080 s'ouvre dans exactement deux états anormaux — "Aucun fichier de configuration n'a été trouvé. Le port 8080 est ouvert pour la configuration initiale" et "Le démarrage a échoué. Le port 8080 est ouvert pour le dépannage et la récupération." Un conteneur Cloud Run satisferait$PORT=8080précisément lorsqu'il n'était pas configuré ou qu'il avait planté.
7. Comportement de la sonde de santé
Le HEALTHCHECK de l'image est
curl -fsSk https://127.0.0.1:443/healthz/live || curl -fsS http://127.0.0.1:8080/healthz/live,
il signale donc un serveur bloqué sur 8080 comme étant sain. Cette couche définit container_port = 443, et le module de plateforme fournit des sondes TCP contre celui-ci :
- Un serveur qui a échoué au démarrage ne lie que 8080, donc la vérification TCP sur 443 échoue — correctement.
- Un serveur qui a démarré avec son DataStore connecté mais sans configuration de serveur lie également 443 (les deux 443 et 8080 ont répondu 200 sur le déploiement vérifié), donc la sonde passe. Le signe est que 8080 est toujours ouvert, ce qu'aucune sonde Kubernetes ne peut exprimer ; vérifiez-le manuellement (voir le guide de la plateforme).
Une sonde HTTP n'est pas une option : la sonde HTTP de App_GKE n'a pas de champ scheme et
ne peut pas vérifier un port HTTPS. Ne redirigez jamais une sonde défaillante vers 8080.
8. Ce qui n'est pas câblé
Domaines, écouteurs et TLS. Le chemin déclaratif du fournisseur est : écrire
config.json, démarrer avec STALWART_RECOVERY_MODE=1 et STALWART_RECOVERY_ADMIN,
exécuter stalwart-cli apply avec un plan JSON, puis redémarrer sans les
variables de récupération. stalwart-cli est un binaire séparé publié comme sa propre image
(ghcr.io/stalwartlabs/cli), donc cette étape serait un job d'initialisation utilisant
cette image. Il n'est pas câblé, car chaque valeur d'un tel plan concerne un vrai
domaine de messagerie. Tant qu'il n'est pas appliqué, le serveur fonctionne avec son DataStore configuré et
ses valeurs par défaut pour tout le reste.
Envoi de courrier. Google Cloud bloque le port TCP 25 sortant de chaque VM et pod, donc la livraison MX directe est impossible ; le courrier sortant nécessite un hôte intelligent sur 587. Le port 25 entrant n'est pas affecté. Un déploiement de production nécessite également un domaine avec des enregistrements MX, DNS direct et inverse, et SPF/DKIM/DMARC.
Pour la configuration spécifique à Stalwart et destinée à l'utilisateur (variables par groupe, la carte des ports, les sorties et comment explorer chaque service depuis la Console et la CLI), consultez le guide de la plateforme : Stalwart_GKE.
Guides associés
- Stalwart sur GKE Autopilot — cette configuration déployée sur GKE.
Need RAD to do something it does not do yet? Request it on the roadmap, or vote on what is already there.