sieve, search, sessions, dramatiq, deploy/install, ELK, monitoring)
Веб-почта + админка почтового сервера для внутренней платформы. Встраивается через iframe в основной сайт. Аналог Roundcube/Nextcloud-Mail с управлением сервером.
Возможности
- Почта: системные и пользовательские IMAP-папки, треды по теме, фильтры (Все/Непрочитанные/С флагом/Важные/С вложениями), пометки звезды/важности, поиск через Meilisearch, drag-drop чипов между To/Cc/Bcc, paste-файлов из буфера.
- Compose: чипы получателей с автодополнением (контакты + DMS-mailboxes), Markdown с тулбаром и preview, подписи, вложения (drag-drop + buffer), отложенная отправка через Redis (переживает закрытие вкладки), свернуть-в-вкладку, автосейв черновиков в IMAP Drafts.
- Realtime: IMAP IDLE → SSE → новые письма без перезагрузки + автоматическая индексация в Meilisearch.
- Админка (
/admin/): дашборд, ящики, алиасы, домены с DNS-визардом (3 шага: записи → проверка черезdnspython→ DKIM + первый ящик), редактируемые настройки приложения, аудит-лог, активные сессии, карточка ELK с одной кнопкой «Применить». - Аутентификация: логин по IMAP-паролю, server-side сессии в Postgres (Fernet-шифрованный пароль), rate-limit 5/60с, fail2ban-релакс на DMS.
- Авто-очистка: корзина чистится в фоне раз в 6 ч (Dramatiq), retention настраивается.
- ELK-shipping: rsyslog-конфиг отправляет логи Flask/Dramatiq/Postfix/Dovecot
на удалённый Logstash. Альтернатива через Filebeat в
deploy/elk/. - Бэкапы: ежедневный cron (postgres dump + redis snapshot + maildir tar.gz).
- Мониторинг:
/api/healthс глубокими проверками (DB/Redis/IMAP/Meili/queues/postqueue).
Стек
- Python 3.13 + Flask 3 (Jinja SSR), gunicorn + gevent
- SQLAlchemy 2 + Alembic —
signatures,groups,shared_mailboxes,autoreply,rules,user_sessions,audit_log - Dramatiq (Redis broker) — отложенная отправка, очистка корзины, realtime-индексация
- docker-mailserver v14 — Postfix + Dovecot + Rspamd
- Postgres 16, Redis 7, Meilisearch 1.x
Быстрая установка (production)
Свежий Debian/Ubuntu, всё готово через единый installer:
git clone <repo-url> /home/deeily/mail
cd /home/deeily/mail
sudo bash deploy/install.sh
Что делает установщик:
- Ставит docker / python3-venv / build-essential (если нет)
- Создаёт venv, ставит
requirements.txt - Копирует
.env.example → .env+ генерируетFLASK_SECRET_KEY - Поднимает docker-compose (postgres, redis, meili, mailserver)
- Применяет fail2ban-override для DMS (Docker bridge в whitelist)
- Применяет
alembic upgrade head - Ставит systemd-юниты
mail-flask+mail-dramatiqи стартует их - Прописывает cron для ежедневного бэкапа в 03:30
- Ставит sudoers-entry для UI-кнопки «Применить ELK»
После установки заполнить в /home/deeily/mail/.env:
ADMINS=admin@your-domain— кто видит /admin/*IMAP_PASSWORD=…— пароль системного IMAP-юзераMAIL_SERVER_HOSTNAME=smtp.your-domain
И перезапустить: sudo systemctl restart mail-flask.
Разработка (локально)
python3 -m venv .venv
.venv/bin/pip install -r requirements.txt
cp .env.example .env
# выставить USE_MOCK_MAIL=1 для офлайн-режима
cd docker && docker compose up -d postgres redis meili
cd ..
.venv/bin/alembic upgrade head
.venv/bin/python wsgi.py
Открыть http://localhost:5000/, логин — admin@mail.local / admin123.
Структура
app/
__init__.py # Flask factory + before_request middleware
config.py # все env-параметры
db.py # SQLAlchemy engine + scoped_session
models.py # ORM
tasks.py # Dramatiq actors (send_deferred, cleanup_trash, index_new_messages)
blueprints/
mail/ # /f/<folder>?uid=… — клиент
admin/ # /admin/ + /admin/audit + /admin/domains/new (визард)
auth/ # /auth/login + /auth/logout
api/ # /api/health, /api/search, /api/contacts, /api/mail/*
settings/ # /settings/sessions, /settings/signatures, /settings/autoreply
groups/, rules/, shared/
services/
imap_client.py # IMAPClient + per-user RLock + кэши
imap_idle.py # IDLE-thread per (user,folder), SSE-фанаут, хук в Meili
smtp_sender.py # smtplib порт 587
mail_service.py # фасад для blueprints (mock ↔ real)
store.py # CRUD над Postgres-моделями
sessions.py # server-side sessions + Fernet + audit_log
sieve_builder.py # rules → managesieve.sieve, deploy через docker exec
search.py # Meilisearch wrapper
dms_config.py # обёртка над `setup` CLI DMS + verify_dns (dnspython)
templates/ # Jinja
static/ # styles.css + app.js
docker/
docker-compose.yml # postgres, redis, meili, mailserver
dms-config/ # bind-mount в DMS — postfix-main.cf, fail2ban-jail.cf, …
deploy/
install.sh # единый установщик
backup.sh # ежедневный бэкап
systemd/ # mail-flask.service + mail-dramatiq.service + install.sh
rsyslog/ # 49-mail-stack.conf + install.sh (ELK shipping)
elk/ # альтернатива через Filebeat (если rsyslog не подходит)
migrations/ # Alembic
gunicorn.conf.py # gevent, 1 worker, 2000 connections
wsgi.py # gevent monkey-patch + create_app()
Эксплуатация
# Статус
systemctl status mail-flask mail-dramatiq
journalctl -u mail-flask -f
curl localhost:5000/api/health | jq
# Перезагрузка после правки .env
sudo systemctl restart mail-flask mail-dramatiq
# Бэкап вручную
/home/deeily/mail/deploy/backup.sh
# Подключить ELK
# через UI: /admin/ → карточка «ELK · отправка логов» → ELK_HOST/PORT/PROTO + «Применить»
# или вручную: sudo bash deploy/rsyslog/install.sh logstash.internal 5140 tcp
Лицензия
Internal — не для публичного использования.
Description
Languages
Python
41.8%
HTML
33.1%
JavaScript
12.8%
CSS
8.6%
Shell
3.4%
Other
0.3%