Français
Auto-hébergement
Ce guide vous mène d'un serveur nu à une instance Mankomail en service, sur laquelle vous pouvez vous connecter. Il s'appuie sur le fichier Docker Compose de référence livré avec le code source, compose.reference.yaml.
Ce que vous installez
Une instance auto-hébergée se compose de trois éléments :
- Le conteneur applicatif : l'API, les workers de fond et l'interface web, dans un seul processus.
- PostgreSQL : tout l'état de l'instance y vit — boîtes, workflows, exécutions, et la file de tâches elle-même.
- Un stockage objet compatible S3 : les corps de mails et les pièces jointes. Le fichier Compose de référence fait tourner MinIO ; n'importe quel point d'accès compatible S3 peut le remplacer.
Il n'y a ni Redis, ni courtier de messages, ni ordonnanceur séparé à faire tourner.
Prérequis
| Minimum | Confortable | |
|---|---|---|
| Docker Engine | 24 | 28 ou plus |
plugin docker compose | v2.20 | v2.39 ou plus |
| Mémoire vive | 4 Go | 8 Go |
| Processeur | 2 cœurs | 4 cœurs |
| Disque | 20 Go | environ 1,5 × la taille des boîtes synchronisées |
Le miroir stocke les corps de mails et les pièces jointes tels quels. Par défaut, Mankomail synchronise les 12 derniers mois de chaque boîte (BACKFILL_MONTHS) ; baisser cette valeur est le premier levier si l'espace disque est compté.
Vous n'avez besoin ni de Node.js, ni de pnpm, ni de PostgreSQL sur la machine : tout tourne dans des conteneurs.
Il vous faut aussi :
- un nom de domaine qui pointe vers le serveur, pour le HTTPS ;
- un reverse proxy qui termine le TLS (Caddy, nginx, Traefik…). L'application ne parle pas TLS elle-même.
Démarrage rapide
Clonez le dépôt et créez le fichier
.envà partir de l'exemple commenté :bashgit clone <repository-url> instance && cd instance cp .env.example .envGénérez les secrets :
bashopenssl rand -hex 16 # pour POSTGRES_PASSWORD openssl rand -hex 16 # pour STORAGE_SECRET_ACCESS_KEY openssl rand -hex 32 # pour ENCRYPTION_KEYModifiez
.envpour que chacune de ces variables y figure une seule fois, avec vos valeurs :iniPOSTGRES_PASSWORD=<valeur générée> STORAGE_ACCESS_KEY_ID=storage STORAGE_SECRET_ACCESS_KEY=<valeur générée> ENCRYPTION_KEY=<valeur générée> PUBLIC_BASE_URL=https://mail.example.com BOOTSTRAP_ADMIN_EMAIL=vous@example.com BOOTSTRAP_ADMIN_PASSWORD=<au moins 12 caractères>Construisez l'image, démarrez la pile et vérifiez qu'elle est prête :
bashdocker compose -f compose.reference.yaml up -d --build curl -s localhost:3000/readyz
Le premier --build compile l'image et prend quelques minutes. Les migrations de la base s'appliquent d'elles-mêmes au démarrage de l'application.
La suite de cette page explique chaque étape, et les quelques endroits où une installation déraille d'habitude.
Les variables obligatoires
Le fichier Compose de référence refuse de démarrer si l'une de ces variables manque dans .env :
| Variable | Ce que c'est | Comment la produire |
|---|---|---|
POSTGRES_PASSWORD | Mot de passe de la base PostgreSQL | openssl rand -hex 16 |
STORAGE_ACCESS_KEY_ID | Clé d'accès du stockage objet | Un identifiant au choix |
STORAGE_SECRET_ACCESS_KEY | Secret du stockage objet | openssl rand -hex 16 |
ENCRYPTION_KEY | La clé d'instance qui chiffre les identifiants stockés | openssl rand -hex 32 |
PUBLIC_BASE_URL | L'adresse publique que tapent vos utilisateurs, par exemple https://mail.example.com | Votre domaine |
Chaque variable lue par l'application accepte aussi une forme <NOM>_FILE qui pointe vers un fichier, pour les secrets Docker ou Kubernetes.
La liste complète des variables, avec leurs valeurs par défaut, est dans Variables d'environnement.
Variables absentes du fichier Compose
Le fichier Compose de référence transmet au conteneur applicatif une liste explicite de variables. Une variable ajoutée à .env n'atteint l'application que si elle figure sous services.app.environment dans le fichier Compose. Pour en poser une autre, ajoutez-la à cet endroit, ou dans un fichier Compose supplémentaire (voir Évaluer sur votre poste).
La clé de chiffrement
ENCRYPTION_KEY chiffre (AES-256-GCM) les jetons OAuth et les mots de passe IMAP des boîtes connectées, ainsi que les clés des fournisseurs d'IA et des autres connexions.
- Elle accepte 64 caractères hexadécimaux (
openssl rand -hex 32) ou 32 octets encodés en base64 (openssl rand -base64 32). - Elle ne se régénère pas. Si vous la perdez, tous les identifiants stockés deviennent illisibles et chaque membre doit reconnecter ses boîtes.
- Rangez-la dans un gestionnaire de mots de passe le jour où vous la générez.
- Sans clé valide, l'instance ne peut enregistrer aucune clé de fournisseur d'IA.
DANGER
Une ENCRYPTION_KEY invalide n'empêche pas l'application de démarrer : l'instance journalise un avertissement et tourne sans chiffrement des identifiants. Vérifiez toujours les journaux de démarrage (voir Lire les journaux de démarrage) avant de connecter une boîte.
PUBLIC_BASE_URL
PUBLIC_BASE_URL n'est pas l'adresse d'écoute de l'application : c'est l'adresse que joignent vos utilisateurs. Mankomail s'en sert pour construire :
- les URI de redirection OAuth, par exemple
<PUBLIC_BASE_URL>/api/v1/oauth/google/callback; - les liens des invitations et des mails d'approbation ;
- l'URL de notification du push Microsoft Graph ;
- la politique de sécurité du contenu (CSP) de l'interface web, canal temps réel compris.
Elle doit être exactement l'URL publique — schéma, hôte et port compris — sans / final. Une valeur fausse laisse l'instance démarrer normalement, puis fait échouer la connexion des boîtes chez le fournisseur, sur une URI de redirection qui ne correspond pas.
Les variables de dimensionnement et de comportement
Ces variables ont des valeurs par défaut raisonnables. Les plus utiles à l'installation :
| Variable | Défaut | Quand la modifier |
|---|---|---|
BACKFILL_MONTHS | 12 | Profondeur d'historique synchronisée pour chaque boîte. 3 suffit pour évaluer le produit. |
POLL_INTERVAL_SECONDS | 300 | Intervalle du sondage de secours. Les notifications push accélèrent la synchronisation ; le sondage la garantit. |
WORKER_CONCURRENCY | 4 | Nombre de tâches traitées en parallèle. Gardez-le sous DATABASE_POOL_MAX. |
DATABASE_POOL_MAX | 10 | Connexions à la base par processus applicatif. |
SEND_ENABLED | true | Coupe-circuit des envois pour toute l'instance. Passez-le à false sur toute copie d'une instance de production. |
SEND_MAX_PER_HOUR | 100 | Nombre maximal de mails envoyés par heure, par boîte. |
APP_BIND | 127.0.0.1 | Interface sur laquelle le port de l'application est publié. Laissez-la telle quelle derrière un reverse proxy. |
APP_PORT | 3000 | Port local de l'application. |
BRAND_NAME | Mankomail | Nom du produit affiché dans l'interface et renvoyé par /healthz. |
Construire ou récupérer l'image
Construisez l'image à partir des sources :
bash
docker compose -f compose.reference.yaml buildSi vous utilisez plutôt une image publiée, renseignez sa référence dans la variable APP_IMAGE de .env.
Le conteneur applicatif tourne avec un utilisateur non-root, sur un système de fichiers en lecture seule, sans aucune capability Linux et avec no-new-privileges. Si vous ajoutez un composant qui écrit sur disque, donnez-lui un tmpfs ou un volume.
Démarrer l'instance
bash
docker compose -f compose.reference.yaml up -dL'ordre de démarrage est garanti par des contrôles de santé :
- PostgreSQL doit accepter les connexions.
- MinIO doit être prêt, puis une tâche ponctuelle crée le bucket et le rend privé.
- L'application démarre, puis applique les migrations de la base sous un verrou consultatif PostgreSQL.
Il n'y a pas d'étape de migration à lancer à part. Plusieurs répliques peuvent démarrer en même temps : une seule migre, les autres attendent.
PostgreSQL et MinIO ne publient aucun port : ils ne sont joignables que depuis le réseau Compose. Le port de l'application n'est publié que sur 127.0.0.1.
Lire les journaux de démarrage
bash
docker compose -f compose.reference.yaml logs app | head -40Cherchez ces lignes :
| Ligne de journal | Ce qu'elle prouve |
|---|---|
database schema is up to date | Les migrations sont appliquées. |
authentication is ready avec "credentialsEncryption":"enabled" | ENCRYPTION_KEY a été acceptée. Si la ligne indique disabled, arrêtez-vous et corrigez la clé avant de connecter la moindre boîte. |
bootstrap admin created | Le compte du premier administrateur existe. |
Server listening at http://0.0.0.0:3000 | L'application écoute. |
Quelques lignes indiquant que PostgreSQL n'accepte pas encore de connexions, juste après le démarrage, sont normales : l'application attend sa base.
Vérifier la santé
Deux points d'accès, aux rôles différents :
bash
curl -s localhost:3000/healthz
curl -s localhost:3000/readyz/healthz(vivacité) répond200avecstatus,brand,versionetuptimeSeconds. Il ne touche à rien d'extérieur./readyz(disponibilité) vérifie la base et les migrations. Il répond200avec"status":"ready", ou503avec"status":"not_ready"et la vérification en échec.
Branchez votre superviseur de processus sur /healthz, pas sur /readyz : une courte panne de la base ne doit pas faire redémarrer en boucle des processus sains. L'image déclare d'ailleurs un HEALTHCHECK Docker sur /healthz.
Le premier administrateur
Renseignez BOOTSTRAP_ADMIN_EMAIL et BOOTSTRAP_ADMIN_PASSWORD avant le premier démarrage. Le compte est créé au démarrage, avec le rôle administrateur.
- Le mot de passe doit compter au moins 12 caractères. Un mot de passe plus court est refusé avec un avertissement dans les journaux, et aucun compte n'est créé.
- Le mécanisme devient inerte dès qu'un membre existe : laisser les deux variables dans
.envne réinitialise aucun mot de passe et ne crée pas de second compte. Vous pouvez les retirer ensuite.
Il n'y a pas d'inscription publique. Les membres suivants arrivent sur invitation, depuis Administration › Membres.
Placer un reverse proxy devant
L'application ne parle pas TLS. Placez devant elle un reverse proxy qui termine le HTTPS et transmet à 127.0.0.1:3000.
Ce n'est pas facultatif. En mode production — celui du fichier Compose de référence — le cookie de session porte l'attribut Secure, et la route de connexion refuse une requête qui n'est pas arrivée en HTTPS, avec l'erreur auth.https_required. L'application reconnaît un HTTPS terminé au proxy grâce à l'en-tête X-Forwarded-Proto.
Avec Caddy, qui obtient le certificat tout seul :
caddyfile
mail.example.com {
encode gzip
reverse_proxy 127.0.0.1:3000
}Avec nginx, transmettez la montée en WebSocket (le canal temps réel vit sur /api/v1/ws) et le schéma d'origine :
nginx
server {
listen 443 ssl;
server_name mail.example.com;
# ssl_certificate et ssl_certificate_key : votre certificat
# Les pièces jointes du webmail peuvent atteindre 25 Mo.
client_max_body_size 30m;
location / {
proxy_pass http://127.0.0.1:3000;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
}L'application pose elle-même ses en-têtes de sécurité (Strict-Transport-Security en production, X-Content-Type-Options, X-Frame-Options, Referrer-Policy, et une politique de sécurité du contenu sur les pages HTML).
Faire confiance au proxy
Par défaut, l'application fait confiance aux en-têtes X-Forwarded-* (TRUST_PROXY=true), ce qui est juste derrière un proxy. Si vous exposez directement le port de l'application, posez TRUST_PROXY=false : sinon, un client peut falsifier son adresse IP et contourner la limitation de débit du formulaire de connexion. Derrière un proxy, gardez APP_BIND=127.0.0.1.
Vérifiez ensuite que PUBLIC_BASE_URL est bien l'adresse HTTPS servie par le proxy, par exemple https://mail.example.com, et redémarrez l'application si vous l'avez modifiée :
bash
docker compose -f compose.reference.yaml up -d appÉvaluer sur votre poste
Pour essayer Mankomail sur votre poste sans certificat, faites-le tourner sur http://localhost:3000 en acceptant un cookie de session sans l'attribut Secure. Créez un fichier compose.local.yaml à côté du fichier de référence :
yaml
services:
app:
environment:
COOKIE_SECURE: 'false'Renseignez PUBLIC_BASE_URL=http://localhost:3000 dans .env, puis démarrez les deux fichiers ensemble :
bash
docker compose -f compose.reference.yaml -f compose.local.yaml up -dDANGER
COOKIE_SECURE=false fait circuler le cookie de session en clair. Ne l'utilisez que sur une machine ou un réseau que vous maîtrisez, jamais pour une instance de production.
Utiliser un stockage S3 externe
Le fichier Compose de référence fait tourner MinIO, mais tout stockage objet compatible S3 convient. Pour utiliser le vôtre :
- Créez un bucket privé chez votre fournisseur, et une clé d'accès limitée à ce bucket. L'application ne crée pas le bucket.
- Faites une copie de
compose.reference.yamlet, dans la copie :- supprimez les services
minioetcreatebucket, ainsi que le volumeminio-data; - retirez
createbucketde la listedepends_ondu serviceapp; - dans
services.app.environment, renseignezSTORAGE_ENDPOINTavec le point d'accès de votre fournisseur,STORAGE_REGIONavec la région du bucket, etSTORAGE_FORCE_PATH_STYLEavec la valeur qu'attend votre fournisseur (truepour la plupart des services compatibles S3, qui n'offrent pas de nom DNS par bucket).
- supprimez les services
- Dans
.env, renseignezSTORAGE_BUCKET,STORAGE_ACCESS_KEY_IDetSTORAGE_SECRET_ACCESS_KEY.
Utilisez un bucket par instance : l'application ne préfixe pas les clés de ses objets.
Première connexion
Ouvrez <PUBLIC_BASE_URL> dans un navigateur et connectez-vous avec l'adresse e-mail et le mot de passe de l'administrateur initial. Vous arrivez sur la page Boîtes.
Si la connexion indique que l'instance exige HTTPS, la requête n'a pas atteint l'application en HTTPS : vérifiez le reverse proxy et son en-tête X-Forwarded-Proto (voir Placer un reverse proxy devant).
Étapes suivantes
- Déclarez l'application OAuth de votre fournisseur de messagerie. Mankomail n'embarque pas d'application Google ou Microsoft partagée : votre organisation déclare la sienne. En tant qu'administrateur, ouvrez Administration › Applications OAuth : l'écran affiche l'URI de redirection à recopier dans la console du fournisseur. Suivez Google ou Microsoft. Pour tout autre fournisseur, utilisez IMAP, qui ne demande aucune application.
- Connectez une boîte depuis la page Boîtes. Voir Boîtes et miroir.
- Configurez un fournisseur d'IA pour les nœuds IA. En tant qu'administrateur, ouvrez Connexions, section Intelligence artificielle. Voir OpenAI, Anthropic, Mistral, Ollama et les autres intégrations.
- Invitez vos collègues depuis Administration › Membres.
- Construisez votre premier workflow : tutoriel pas à pas.
Avant de considérer l'installation comme terminée :
- gardez une copie de
ENCRYPTION_KEYailleurs que sur le serveur ; - prenez une sauvegarde et restaurez-la une fois — voir Sauvegardes ;
- lisez comment mettre à jour et superviser l'instance.