- README : section Variables d'environnement (ENCRYPTION_KEY, LOCK_DSN) + section Déploiement passée au flow Docker (deploy.sh) - mail-cron-setup : sépare dev (make, php-lesstime-fpm) et prod (lesstime-app, docker compose exec), cron prod réel - infra/prod/.env.example : ajoute ENCRYPTION_KEY et LOCK_DSN (manquaient, requis pour la sync mail) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4.8 KiB
Mail Integration — Configuration cron OS
Vue d'ensemble
La synchronisation IMAP est déclenchée par un cron OS toutes les 10 minutes.
Elle appelle la commande Symfony app:mail:sync qui s'exécute dans le container PHP.
Un Symfony Lock (mail.sync, TTL 10 min, store flock via LOCK_DSN=flock) empêche
les runs de se chevaucher si une sync prend plus de 10 min.
Dev vs prod — en dev le container s'appelle
php-lesstime-fpmet on passe parmake. En production le container s'appellelesstime-app(serviceappdudocker-compose.ymldans/var/www/lesstime), il n'y a pas demake: tout passe pardocker compose/docker exec.
Prérequis
MailConfiguration.enabled = true(configurable depuis l'admin — onglet « Mail »)ENCRYPTION_KEY(clé hex 32 bytes) défini dans l'environnement :- dev :
infra/dev/.env.docker.local - prod :
/var/www/lesstime/.env
- dev :
- Container démarré :
- dev :
make start(containerphp-lesstime-fpm) - prod : déployé via
sudo ./deploy.sh(containerlesstime-app)
- dev :
Variables d'environnement nécessaires
| Variable | Description | Exemple |
|---|---|---|
ENCRYPTION_KEY |
Clé hex 32 bytes pour déchiffrer le password IMAP | $(php -r "echo bin2hex(random_bytes(32));") |
LOCK_DSN |
DSN du store de verrous Symfony | flock (défaut, fichier local) |
La clé ENCRYPTION_KEY doit être identique à celle utilisée pour chiffrer le password
lors de la configuration depuis l'admin. Si elle change, les credentials stockés deviennent illisibles.
Dev
Lancer une sync à la main
make mail-sync # sync complète (toutes les boîtes)
make mail-sync FOLDER=INBOX # un seul dossier (doit déjà exister en base)
make mail-sync DRYRUN=1 # simulation (dry-run, pas d'écriture BDD)
Ou directement dans le container :
docker exec php-lesstime-fpm php bin/console app:mail:sync
docker exec php-lesstime-fpm php bin/console app:mail:sync --folder=INBOX
docker exec php-lesstime-fpm php bin/console app:mail:sync --dry-run
Logs (dev)
make logs-dev # tail -f var/log/dev.log
Les messages loggés par MailSyncService sont préfixés mail.sync.
Production
En prod, l'app tourne dans le container lesstime-app déployé par sudo ./deploy.sh
(dossier /var/www/lesstime). La commande s'exécute en tant que www-data (uid 33),
comme les migrations lancées par deploy.sh.
Lancer une sync à la main
Depuis /var/www/lesstime :
sudo docker compose exec -T -u www-data app php bin/console app:mail:sync
sudo docker compose exec -T -u www-data app php bin/console app:mail:sync --folder=INBOX
sudo docker compose exec -T -u www-data app php bin/console app:mail:sync --dry-run
Installer le cron
Sur la machine hôte (pas dans le container). Comme docker requiert sudo en prod,
installer le cron sous root :
sudo crontab -e
Ajouter :
*/10 * * * * cd /var/www/lesstime && docker compose exec -T -u www-data app php bin/console app:mail:sync >> /var/log/lesstime-mail-sync.log 2>&1
Le crontab de root exécute déjà les commandes en root → pas de
sudoà l'intérieur de la ligne cron. La commande est idempotente (UIDs uniques en base) : la relancer ne duplique pas les données.
Logs (prod)
cd /var/www/lesstime
docker compose logs -f --tail=100 app # logs container
docker compose exec app cat var/log/prod.log # log Symfony (volume lesstime_logs)
Checklist setup production
- Définir
ENCRYPTION_KEY(hex 32 bytes) etLOCK_DSN=flockdans/var/www/lesstime/.env - Créer le compte mail dédié (ex:
lesstime@votre-domaine.fr) chez OVH - Accéder à
/admin→ onglet « Mail » → renseigner les credentials IMAP/SMTP - Cliquer « Tester la connexion » → vérifier le succès
- Cocher « Activer la synchronisation » → Enregistrer
- Lancer une sync manuelle pour valider (commande ci-dessus)
- Installer le cron OS (voir « Installer le cron »)
- Vérifier les logs après la première sync (
docker compose logs -f app, cherchermail.sync)
Sécurité
- Le password IMAP est toujours stocké chiffré (libsodium secretbox)
- Les corps de mails, passwords et pièces jointes ne sont jamais loggés
- Le lock
flockévite les runs parallèles (fichier dans/tmp/sf.mail.sync.<hash>.lock) - La page
/mailet tous les endpoints/api/mail/*sont refusés auxROLE_CLIENTexclusifs - Le sidebar « Messagerie » est masqué pour les utilisateurs
ROLE_CLIENTsansROLE_USER - Les corps de mails sont sanitisés via DOMPurify avant affichage (
frontend/utils/sanitizeMailHtml.ts) - Les pixels de tracking distants sont remplacés par un placeholder