MAATRIX / Блог / Мигрировали на docker-mailserver и вернулись на Mailcow: почему

Мигрировали на docker-mailserver и вернулись на Mailcow: почему

MAATRIX

Полгода назад мы решили, что Mailcow — это слишком много для наших задач: десяток контейнеров, 6+ ГБ RAM только на то, чтобы принимать почту для трёх доменов и полутора десятков ящиков. Переехали на docker-mailserver — минималистичный образ без веб-панели, только почтовый стек. Три месяца спустя вернулись обратно на Mailcow. Ниже — честный разбор, что пошло не так и где именно минимализм перестал окупаться.

Почему Mailcow стал выглядеть как оверкилл

К моменту решения о переезде Mailcow у нас работал уже больше года и проблем как таковых не было. Раздражало другое: docker compose ps показывал полтора десятка контейнеров — postfix, dovecot, rspamd, sogo, clamd, solr, redis, mysql, nginx, netfilter, watchdog, olefy, unbound, acme, dockerapi — и часть из них мы объективно не использовали. SOGo с календарями и адресной книгой был не нужен, потому что почта используется только как почта. ClamAV съедал память, а входящих писем с опасными вложениями за год набралось едва ли десяток. Solr индексировал полнотекстовый поиск по ящикам, которым реально пользовался один человек из пяти.

На сервере с 8 ГБ RAM Mailcow в спокойном состоянии съедал 5.5–6 ГБ, и при любом всплеске — рестарт контейнера с ClamAV, переиндексация Solr — начинались проблемы с памятью на всём хосте, включая другие сервисы, которые крутились там же. Формально это решалось увеличением сервера, но выглядело нелогично: платить за память под функции, которыми не пользуемся. Отсюда и родилась идея — а что если взять минимальный стек, который делает ровно то, что нужно: принимает, отправляет, фильтрует спам, и всё.

docker-mailserver: что это и чем он привлёк

docker-mailserver — открытый проект, который в отличие от Mailcow не является набором из десятка отдельных контейнеров, а упаковывает Postfix, Dovecot и Rspamd в один образ. Никакой веб-панели, никакого SOGo, ClamAV и антивирус опциональны и по умолчанию выключены. Управление — через shell-скрипт setup.sh, который дергает команды внутри контейнера, и через переменные окружения в .env и compose.yaml.

Базовый compose.yaml выглядел примерно так:

services:
  mailserver:
    image: docker.io/mailserver/docker-mailserver:latest
    hostname: mail.example.com
    ports:
      - "25:25"
      - "465:465"
      - "587:587"
      - "993:993"
    volumes:
      - ./docker-data/dms/mail-data/:/var/mail/
      - ./docker-data/dms/mail-state/:/var/mail-state/
      - ./docker-data/dms/mail-logs/:/var/log/mail/
      - ./docker-data/dms/config/:/tmp/docker-mailserver/
      - /etc/localtime:/etc/localtime:ro
    environment:
      - ENABLE_RSPAMD=1
      - ENABLE_CLAMAV=0
      - ONE_DIR=1
      - SSL_TYPE=letsencrypt
    cap_add:
      - NET_ADMIN
    restart: always

Что понравилось сразу: docker compose up -d поднимал буквально три процесса вместо пятнадцати, и потребление памяти в покое упало примерно втрое по сравнению с Mailcow — точную цифру не назову, зависит от нагрузки и включённых опций, но разница была заметна на глаз в docker stats уже в первый день. Rspamd для антиспама остался тем же движком, что и в Mailcow, поэтому качество фильтрации спама на старте не просело. Ящики и алиасы создавались одной командой:

docker exec -it mailserver setup email add user@example.com
docker exec -it mailserver setup alias add info@example.com user@example.com
docker exec -it mailserver setup config dkim

Никакой лишней абстракции между командой и результатом — это подкупало после Mailcow, где те же операции шли через веб-панель с несколькими вкладками.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под Mailcow

Как проходил переезд

Перенос почты делали через imapsync — копировали ящики с работающего Mailcow на новый сервер с docker-mailserver, не трогая старый до полной проверки:

imapsync --host1 old-mail.example.com --user1 user@example.com --password1 '...' \
         --host2 mail.example.com --user2 user@example.com --password2 '...' \
         --ssl1 --ssl2

Для каждого ящика это заняло от нескольких минут до пары часов в зависимости от объёма папки. Отдельно перегенерировали DKIM-ключ (переносить старый ключ Mailcow в чужой формат смысла не было — проще сгенерировать новый и обновить TXT-запись в DNS) и подождали, пока протухнет TTL старой записи, чтобы избежать провала подписи в переходный период. MX временно не трогали — держали оба сервера доступными по IMAP несколько дней, переключали клиентов постепенно, и только когда убедились, что все ящики синхронизированы, переставили MX-запись и погасили старый Mailcow.

Заняло это заметно больше, чем ожидали на старте: не сама техническая миграция писем, а именно организационная часть — донести до пяти человек, что интерфейс входа меняется, помочь перенастроить клиенты (Thunderbird, телефоны), а тем, кто пользовался вебмейлом SOGo, объяснить, что теперь его нет вообще и почту нужно смотреть либо через отдельно поднятый Roundcube, либо через десктопный клиент.

Первые недели: что реально упростилось

Первое время всё выглядело как правильное решение. Память на сервере освободилась, и это было измеримо: free -h показывал в разы больше свободного места под другие сервисы, которые жили на том же хосте. Обновления стали проще — один образ вместо синхронизации версий десятка контейнеров, docker compose pull && docker compose up -d, и всё. Логи концентрировались в одном месте: docker logs mailserver вместо блуждания между логами postfix, dovecot и rspamd в разных контейнерах.

Понимание системы тоже улучшилось: когда компонентов меньше и они не спрятаны за панелью, легче держать в голове, что где настроено и почему. Конфиги Postfix и Dovecot внутри контейнера — это обычные текстовые файлы, которые можно найти и прочитать напрямую, без прослойки в виде базы данных настроек, как в Mailcow. Для человека, который любит понимать систему до последнего винтика, это плюс сам по себе.

Чего стало не хватать

Проблемы начали накапливаться не сразу, а по мере того, как всплывали задачи, для которых Mailcow решал вопрос «из коробки», а здесь требовал ручной работы или отдельного сервиса.

Веб-интерфейса для управления ящиками не было в принципе — это осознанное архитектурное решение проекта, а не недоделка, но на практике это означало, что любое изменение (новый ящик, смена пароля, алиас) шло через SSH и docker exec. Пока это делает один администратор, который сам себе SSH — терпимо. Как только кому-то из команды понадобилось самостоятельно сменить пароль или добавить алиас без обращения к тому, кто держит ключи от сервера, стало неудобно: пришлось либо давать доступ к серверу, либо становиться единой точкой отказа для любой мелкой операции с почтой.

Вебмейла тоже не было из коробки. Чтобы получить веб-доступ к почте, аналогичный тому, что в Mailcow давал SOGo, нужно было поднимать и поддерживать отдельно Roundcube или Snappymail — ещё один контейнер, ещё один набор настроек, ещё одна точка, которая может сломаться и о которой нужно отдельно думать при обновлениях.

Мониторинг состояния стал менее наглядным. В Mailcow панель сразу показывает очередь писем, статус DKIM, историю доставки, количество писем в карантине спама. В docker-mailserver это всё либо смотрится через CLI-команды и логи, либо не смотрится вообще без отдельной настройки. Для разбора конкретного «куда делось письмо» приходилось руками лезть в mail.log и парсить его grep’ом — работает, но медленнее и требует привычки, которой у части команды не было.

Управление правилами спама тоже оказалось менее удобным. И в Mailcow, и в docker-mailserver под капотом Rspamd, но в Mailcow есть панель, где видно скоринг конкретного письма, попавшего в карантин, можно один клик выпустить письмо из карантина или обучить фильтр на конкретном примере. В docker-mailserver это либо консольные команды rspamc, либо прямая правка конфигов Rspamd — доступно, но каждый раз чуть дольше и требует держать в голове синтаксис, которым пользуешься нечасто.

Отдельно всплыла проблема с квотами и sieve-фильтрами (автоматическая сортировка писем по папкам, автоответы) — их тоже пришлось настраивать текстовыми файлами вручную для каждого ящика, тогда как в Mailcow это делается в интерфейсе за минуту без необходимости помнить синтаксис Sieve.

Точка невозврата: почему решили откатиться

Ни одна из этих проблем по отдельности не была критичной. Совокупный эффект — да. Экономия по ресурсам компенсировалась ростом административного времени: каждая мелкая задача с почтой, которая в Mailcow занимала минуту в панели, в docker-mailserver превращалась в пять-десять минут SSH, команд и сверки с документацией, потому что синтаксис setup.sh и конфигов вспоминался не с первого раза. На горизонте нескольких месяцев это время набежало заметно больше, чем сэкономленные гигабайты памяти стоили бы на любом разумном тарифе VPS.

Финальным триггером стал случай, когда одному из пользователей нужно было срочно сменить пароль от почты, а единственный человек с доступом к серверу оказался недоступен несколько часов. В Mailcow это решалось бы через отдельную роль администратора домена в панели — дать ограниченный доступ конкретному человеку без выдачи полного SSH к серверу. В docker-mailserver такого разделения ролей нет по архитектуре: либо у тебя есть доступ к серверу и ты можешь всё, либо у тебя нет доступа и ты не можешь ничего с своей же почтой.

После этого случая сели и честно посчитали: команда из пяти человек, из которых для двоих периодически нужно делегировать базовые операции с ящиками, — это ровно тот сценарий, для которого веб-панель Mailcow существует не для красоты, а как рабочий инструмент. Подняли новый Mailcow, повторили миграцию через imapsync в обратную сторону, перегенерировали DKIM ещё раз и вернули MX. Заняло это меньше времени, чем первоначальный переезд — сказался опыт.

Что взяли с собой из этого опыта

Главный вывод не в том, что docker-mailserver — плохой проект. Технически он делает то, что обещает: минимальный, предсказуемый почтовый стек без лишнего веса. Проблема была в несоответствии инструмента задаче — у нас оказалась не задача «один администратор, который любит консоль и не хочет лишних контейнеров», а задача «небольшая команда, которой периодически нужно делегировать простые операции без риска дать лишний доступ». Для первого сценария docker-mailserver — отличный выбор. Для второго веб-панель — это не роскошь, а функциональное требование.

Практический критерий, который вынесли для себя на будущее: если почтой пользуется только один человек, который сам её администрирует, и важна каждая мелочь в потреблении ресурсов — минимальный стек вроде docker-mailserver окупается. Если ящиками пользуется больше одного-двух человек и хотя бы иногда нужно кому-то из них дать возможность что-то поменять самостоятельно — переплата в ресурсах на готовую панель Mailcow почти всегда обходится дешевле, чем время администратора на ручные операции. Если для вас это первый переезд на свою почту вообще, разумнее сразу смотреть на установку Mailcow на VPS и держать под рукой разбор частых ошибок Mailcow, а не проходить оба круга, как пришлось нам.

Стоит также заранее прикинуть требования к серверу под выбранный стек — минимальному docker-mailserver хватит 2 ГБ RAM, полноценному Mailcow с антивирусом и поиском комфортнее от 6 ГБ и больше; разница в счёте за VPS обычно меньше, чем кажется на старте, если сравнивать её с трудозатратами на администрирование. Общий выбор между голым MTA, минимальным контейнером и полным стеком с панелью подробно разобран в статье про Postfix или Mailcow — логика применима и здесь: сначала честно оцените, кто и как будет пользоваться почтой, и только потом выбирайте инструмент под этот сценарий, а не наоборот.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под Mailcow

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

docker-mailserver — плохой проект?

Нет, технически он делает ровно то, что заявляет: лёгкий, предсказуемый почтовый стек без веб-панели. Проблема была не в качестве инструмента, а в том, что для команды из нескольких человек с делегированием операций нужен интерфейс управления, которого там нет по архитектуре.

Сколько памяти реально экономит переход на docker-mailserver?

Заметно меньше, чем Mailcow с включёнными ClamAV и Solr, — в нашем случае в разы, но точная цифра зависит от количества ящиков, нагрузки и того, какие компоненты Mailcow вы реально используете. Проверяйте на своей нагрузке, а не берите чужие цифры как гарантию.

Можно ли добавить веб-интерфейс к docker-mailserver?

Отдельный вебмейл (Roundcube, Snappymail) можно поднять рядом как ещё один контейнер, но это не даст полноценной админ-панели для управления ящиками и ролями — только чтение и отправку почты для конечного пользователя.

Сколько занял обратный переезд на Mailcow?

Меньше, чем первый переезд на docker-mailserver, потому что процесс миграции через imapsync и перегенерация DKIM были уже отработаны. Основное время ушло на выдержку старого MX и синхронизацию последних писем перед переключением.

Стоит ли вообще пробовать минимальные стеки вроде docker-mailserver?

Да, если ваш сценарий — один администратор без необходимости делегировать доступ и приоритет на экономию ресурсов. Мы сами не жалеем об эксперименте — он дал чёткий критерий выбора, просто наш реальный сценарий оказался ближе к готовому стеку с панелью.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →