Mailcow dockerized — готовый почтовый сервер из полутора десятков Docker-контейнеров: Postfix, Dovecot, Rspamd, SOGo, ClamAV и веб-админка. Установка делается в три команды: git clone, ./generate_config.sh и docker compose up -d. Остальная работа — подготовка сервера до установки и проверка работы после.
Чаще всего установка срывается по трём причинам. Не хватает памяти: Mailcow требует от 6 ГБ RAM плюс swap, иначе первым падает ClamAV. Разворачиваете сервер не на полноценной виртуальной машине или выделенном сервере, а в контейнере LXC или OpenVZ. Часто хостеры закрывают порт 25. Проверьте все три пункта до установки, а DNS и PTR настройте заранее: от них зависит и сертификат, и попадание почты в СПАМ.
Ниже — установка на Debian 12, Debian 13 и Ubuntu 24.04 по шагам: Docker, мастер настройки, сертификат Let’s Encrypt, работа за уже установленным nginx, DKIM, резервные копии, обновление и типичные проблемы. Чем Mailcow отличается от iRedMail и ручной сборки, разобрано в обзоре как выбрать собственный почтовый сервер.
Что такое Mailcow dockerized
Mailcow — это не пакет, а репозиторий с docker-compose.yml, конфигами и скриптами обслуживания. Каждый компонент работает в своём контейнере, контейнеры общаются во внутренней сети 172.22.1.0/24. Наружу публикуются только почтовые и веб-порты.
| Контейнер | Что делает |
|---|---|
| postfix-mailcow | SMTP: приём на 25, отправка клиентов на 587 и 465 |
| dovecot-mailcow | IMAP, POP3, ManageSieve, LMTP-доставка в ящики, квоты, шифрование хранилища |
| rspamd-mailcow | Антиспам, DKIM-подпись, проверка SPF/DKIM/DMARC, ratelimit |
| sogo-mailcow | Веб-почта, календари и контакты (CalDAV/CardDAV), ActiveSync |
| clamd-mailcow | Антивирус ClamAV, самый прожорливый по памяти компонент |
| unbound-mailcow | Собственный DNS-резолвер: нужен для DNSBL и проверок SPF/DKIM |
| mysql-mailcow | MariaDB: домены, ящики, алиасы, настройки |
| redis-mailcow | Кэш и данные Rspamd, сессии, счётчики |
| nginx-mailcow | Веб-интерфейс, SOGo, autodiscover/autoconfig, отдача ACME-проверок |
| acme-mailcow | Выпуск и продление сертификатов Let’s Encrypt |
| php-fpm-mailcow | Админка и API |
| netfilter-mailcow | Блокировка IP после неудачных входов, аналог Fail2ban |
| watchdog-mailcow | Проверка здоровья сервисов и их перезапуск |
Есть и вспомогательные: olefy, memcached, ofelia, dockerapi, postfix-tlspol. Конфигурация лежит в /opt/mailcow-dockerized, письма и базы — в Docker-томах в /var/lib/docker/volumes.
Важно для Debian 13: Postfix и Dovecot работают внутри своих образов, а не из пакетов ОС. Mailcow сейчас использует Dovecot 2.3, поэтому несовместимость формата Dovecot 2.4 из Debian 13 его не касается. На хост Postfix и Dovecot ставить не нужно, они только займут порты.
Требования к серверу
| Параметр | Требование |
|---|---|
| RAM | Минимум 6 ГиБ + 1 ГиБ swap. Для 5–10 пользователей рекомендуют 8 ГиБ, для 15 телефонов с ActiveSync и ~50 IMAP-подключений — 16 ГиБ |
| Диск | 20 ГиБ без учёта почты, плюс планируемый объём ящиков и место под резервные копии |
| CPU и архитектура | От 1 ГГц, x86_64 или ARM64 |
| Виртуализация | KVM, VMware ESXi, Hyper-V и другая полная виртуализация. Не поддерживаются: OpenVZ, Virtuozzo, LXC, NAS (Synology, QNAP) |
| ОС | Debian 11–13, Ubuntu 22.04 и новее, Alma Linux 8/9, Rocky Linux 9 |
| Docker | Docker Engine 24.0.0 и новее, Docker Compose 2.0 и новее |
| Сеть | Статический IP, возможность задать PTR, открытый исходящий порт 25 |
Память уходит в основном на SOGo (воркер может занять около 350 МиБ, по умолчанию их 20) и ClamAV (больше 1 ГБ заберет под сигнатуры вирусов).
Проверьте тип виртуализации, память, swap и синхронизацию времени:
systemd-detect-virt # kvm, vmware, microsoft — подходит; lxc, openvz — нет
free -h
swapon --show
timedatectl status # нужно: System clock synchronized: yes
Если swap нет, создайте файл подкачки на 2 ГБ:
fallocate -l 2G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
Подготовка: DNS, PTR и порты
DNS-записи до установки
Имя сервера — mail.example.com, почтовый домен — example.com, IP — 82.202.204.1. Минимальный набор записей в зоне example.com:
; зона example.com
mail IN A 82.202.204.1
@ IN MX 10 mail.example.com.
autodiscover IN CNAME mail.example.com.
autoconfig IN CNAME mail.example.com.
@ IN TXT "v=spf1 mx -all"
A-запись mail нужна только для домена, на котором живёт сам сервер. Для каждого следующего почтового домена достаточно MX на mail.example.com и двух CNAME: autodiscover для Outlook и ActiveSync, autoconfig для Thunderbird. Запись DKIM появится после добавления домена в админку, DMARC добавим тогда же.
SRV-записи необязательны, они помогают клиентам найти сервер. Достаточно основных:
_autodiscover._tcp IN SRV 0 1 443 mail.example.com.
_imaps._tcp IN SRV 0 1 993 mail.example.com.
_submission._tcp IN SRV 0 1 587 mail.example.com.
_submissions._tcp IN SRV 0 1 465 mail.example.com.
Полный список SRV, включая CalDAV и CardDAV, есть в документации: DNS setup на docs.mailcow.email.
PTR
Обратная запись для 82.202.204.1 должна возвращать mail.example.com, то есть ровно то имя, которое вы введёте в мастере как hostname. Postfix в Mailcow представляется этим именем в HELO. PTR задаётся в панели хостера или через поддержку провайдера. Если у сервера есть IPv6 и Mailcow будет его использовать, PTR нужен и для IPv6-адреса.
dig +short mail.example.com A # 82.202.204.1
dig +short -x 82.202.204.1 # mail.example.com.
dig +short example.com MX # 10 mail.example.com.
Порты
Снаружи должны быть доступны: 25 (SMTP), 465 и 587 (отправка клиентов), 143 и 993 (IMAP), 110 и 995 (POP3), 4190 (ManageSieve), 80 и 443 (веб и ACME). Проверьте, что на хосте их не занимает какой-то процесс:
ss -tlpn | grep -E -w '25|80|110|143|443|465|587|993|995|4190'
Частый случай — на хосте уже стоит exim4 или postfix из образа хостера. В Debian exim4 может появиться и после обновления с 12 на 13. Удалите его, иначе postfix-mailcow не стартует с ошибкой address already in use:
apt purge -y 'exim4*' postfix # пакеты, которых нет, apt просто пропустит
Проверьте исходящий порт 25 до чужого MX. Если соединение висит до таймаута, порт закрыт у хостера: просите открыть или планируйте разворачивать relayhost.
nc -vz -w 5 gmail-smtp-in.l.google.com 25
# примерно так: Connection to gmail-smtp-in.l.google.com 25 port [tcp/smtp] succeeded!
Установка Docker и плагина Compose
Mailcow требует Docker Engine 24.0.0 и новее и Compose v2 — плагин, который вызывается как docker compose, через пробел. Пакеты docker.io и docker-compose из репозиториев Debian и Ubuntu не подходят: документация Mailcow прямо просит ставить актуальный Docker Engine из репозитория Docker. Скрипт generate_config.sh сам проверит версию и остановится, если она ниже 24.
Сначала удалите конфликтующие пакеты из дистрибутива, если они стоят, и поставьте утилиты, которые нужны скриптам Mailcow (jq обязателен с релиза 2025-09):
sudo -i
apt remove -y docker.io docker-doc docker-compose podman-docker containerd runc
apt update
apt install -y ca-certificates curl git openssl gawk coreutils grep jq
Добавьте официальный репозиторий Docker. Блок одинаков для Debian 12/13 и Ubuntu 24.04: имя дистрибутива и кодовое имя берутся из /etc/os-release.
. /etc/os-release
install -m 0755 -d /etc/apt/keyrings
curl -fsSL "https://download.docker.com/linux/${ID}/gpg" -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/${ID}
Suites: ${VERSION_CODENAME}
Components: stable
Architectures: $(dpkg --print-architecture)
Signed-By: /etc/apt/keyrings/docker.asc
EOF
apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
systemctl enable --now docker
Короткий путь из документации Mailcow — curl -sSL https://get.docker.com/ | CHANNEL=stable sh: скрипт подключает тот же репозиторий.
Проверьте версии:
docker version --format '{{.Server.Version}}' # должно быть 24.0.0 или выше
docker compose version # Docker Compose version v2.x
Загрузка Mailcow и мастер generate_config.sh
Все команды Mailcow выполняются от root из каталога установки. umask 0022 нужен, чтобы файлы в репозитории получили права, с которыми их смогут читать контейнеры:
umask 0022
cd /opt
git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
./generate_config.sh
Мастер задаёт несколько вопросов:
- Mail server hostname (FQDN) — имя сервера, а не почтовый домен:
mail.example.com, неexample.com. Имя должно совпадать с A-записью и PTR. Поменять его потом можно, но придётся перевыпускать сертификат и править DNS. - Timezone — мастер подставит часовой пояс хоста, например
Europe/Moscow. Enter подтверждает. - Отключить ClamAV? — вопрос появляется, только если памяти 2,5 ГиБ или меньше. На сервере с 6 ГиБ и больше ClamAV включается без вопроса, отключить его можно позже в
mailcow.conf. - Ветка — выбирайте
1, master: стабильные ежемесячные релизы. Nightly — для тестов. Legacy получала только исправления безопасности, и её поддержка закончилась в феврале 2026 года. - IPv6 — мастер сам проверяет, есть ли на хосте рабочий IPv6. Если есть, он предложит дописать настройки в
/etc/docker/daemon.jsonи перезапустить Docker. Результат записывается вENABLE_IPV6.
Мастер создаёт mailcow.conf с правами 600, случайными паролями к MariaDB и Redis и временным самоподписанным сертификатом. Файл .env в репозитории — символическая ссылка на mailcow.conf, по ней Docker Compose читает переменные.
Что посмотреть в mailcow.conf
Основные параметры файла /opt/mailcow-dockerized/mailcow.conf:
| Параметр | Значение по умолчанию | Когда менять |
|---|---|---|
MAILCOW_HOSTNAME | из мастера | Только вместе с DNS и PTR |
SKIP_CLAMD | n при RAM больше 2,5 ГиБ | y, если памяти впритык: Rspamd сам заметит, что антивируса нет |
SKIP_FTS | n | y на слабом сервере: отключает полнотекстовый поиск Dovecot |
HTTP_PORT, HTTP_BIND, HTTPS_PORT, HTTPS_BIND | 80, 443, пусто | Если на сервере уже есть веб-сервер, см. раздел про reverse proxy |
HTTP_REDIRECT | y | n за внешним reverse proxy |
ENABLE_IPV6 | по результату проверки | false, если у IPv6 нет PTR |
ADDITIONAL_SAN | пусто | Дополнительные имена в сертификате, например imap.*,smtp.* |
POP_PORT, POPS_PORT и другие *_PORT | стандартные порты | Формат 127.0.0.1:110 публикует порт только локально |
После любой правки mailcow.conf выполните docker compose up -d из каталога Mailcow: Compose пересоздаст только затронутые контейнеры.
Запуск
Скачайте образы и запустите стек. Первая загрузка — несколько гигабайт, это займёт несколько минут:
cd /opt/mailcow-dockerized
docker compose pull
docker compose up -d
docker compose ps
В выводе docker compose ps все контейнеры должны быть в состоянии Up, у контейнеров с проверками — (healthy). Статус health: starting сразу после старта нормален. Если контейнер перезапускается по кругу, смотрите его лог, например docker compose logs --tail=100 clamd-mailcow.
Первый вход: пароль администратора и 2FA
Админка открывается по адресу https://mail.example.com/admin. Логин по умолчанию — admin, пароль — moohoo. Пароль общеизвестен, поэтому меняйте его сразу, пока сервер не начали сканировать:
- Войдите в
/admin. Пока не выпущен сертификат Let’s Encrypt, браузер предупредит о самоподписанном сертификате — это нормально. - Откройте «Система» → «Конфигурация» → «Настройки доступа» → «Администраторы».
- Отредактируйте пользователя
admin: задайте длинный уникальный пароль. Можно создать администратора со своим именем, аadminотключить. - На той же вкладке включите двухфакторную аутентификацию: TOTP (приложение-аутентификатор) или WebAuthn (ключ FIDO2, работает только по HTTPS). Отсканируйте QR-код и подтвердите кодом.
Обычные пользователи входят на https://mail.example.com/, администраторы доменов — на /domainadmin. Если пользователь ящика включил 2FA, почтовым клиентам нужны пароли приложений: обычный пароль для IMAP и SMTP перестаёт подходить.
Потерянный пароль администратора сбрасывает ./helper-scripts/mailcow-reset-admin.sh.
Сертификат Let’s Encrypt через acme-mailcow
Отдельно ставить certbot не нужно. Контейнер acme-mailcow сам запрашивает сертификат на MAILCOW_HOSTNAME, а для каждого добавленного домена — на autodiscover. и autoconfig. этого домена. В сертификат попадают только имена, которые проходят проверку: имя должно резолвиться в IP сервера, а сервер должен отвечать на порту 80. Один и тот же сертификат используют nginx, Postfix и Dovecot, продление идёт автоматически.
Посмотреть, как прошёл выпуск, и при необходимости повторить запрос:
cd /opt/mailcow-dockerized
docker compose logs --tail=200 -f acme-mailcow
# повторный запуск ACME-клиента
docker compose restart acme-mailcow
# принудительное продление
touch data/assets/ssl/force_renew
docker compose restart acme-mailcow
Если порт 80 закрыт или нужен wildcard, Mailcow умеет DNS-01 через ACME_DNS_CHALLENGE=y и провайдера DNS в ACME_DNS_PROVIDER. Флаги SKIP_IP_CHECK и SKIP_HTTP_VERIFICATION лучше не трогать: они прячут ошибку в DNS или NAT, а при неверной настройке вы упрётесь в лимиты Let’s Encrypt.
Если на сервере уже есть nginx: reverse proxy
Если порты 80 и 443 занимает nginx хоста, веб-часть Mailcow переносят на локальные порты, а nginx проксирует на неё запросы. Почтовые порты 25, 465, 587, 993 и остальные это не затрагивает: их по-прежнему публикует Docker напрямую.
- В
mailcow.confпривяжите веб к localhost. Порты 8081, 9081, 9082 и 65510 занимать нельзя: их использует сам Mailcow. - Выключите встроенный редирект на HTTPS, его сделает nginx хоста.
- Примените изменения командой
docker compose up -d. - Создайте сайт в nginx хоста и проверьте конфигурацию.
Изменения в /opt/mailcow-dockerized/mailcow.conf:
HTTP_PORT=8080
HTTP_BIND=127.0.0.1
HTTPS_PORT=8443
HTTPS_BIND=127.0.0.1
# редирект на https делает nginx хоста, иначе возможна петля редиректов
HTTP_REDIRECT=n
Конфигурация сайта /etc/nginx/sites-available/mailcow.conf по официальному примеру. Сертификаты берутся из каталога Mailcow, поэтому acme-mailcow продолжает их выпускать: запросы проверки проходят через этот прокси.
server {
listen 80 default_server;
listen [::]:80 default_server;
server_name mail.example.com autodiscover.* autoconfig.*;
return 301 https://$host$request_uri;
}
server {
# nginx 1.25.1+ (Debian 13): listen 443 ssl; + http2 on;
# nginx 1.22/1.24 (Debian 12, Ubuntu 24.04): listen 443 ssl http2; без строки http2 on;
listen 443 ssl;
listen [::]:443 ssl;
http2 on;
server_name mail.example.com autodiscover.* autoconfig.*;
ssl_certificate /opt/mailcow-dockerized/data/assets/ssl/cert.pem;
ssl_certificate_key /opt/mailcow-dockerized/data/assets/ssl/key.pem;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:50m;
ssl_session_tickets off;
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5:!SHA1:!kRSA;
ssl_prefer_server_ciphers off;
location /Microsoft-Server-ActiveSync {
proxy_pass http://127.0.0.1:8080/Microsoft-Server-ActiveSync;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_connect_timeout 75;
proxy_send_timeout 3650;
proxy_read_timeout 3650;
proxy_buffers 64 512k;
client_body_buffer_size 512k;
client_max_body_size 0;
}
location / {
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 0;
# без этих буферов не работает вход в SOGo
proxy_buffer_size 128k;
proxy_buffers 64 512k;
proxy_busy_buffers_size 512k;
}
}
Включите сайт и проверьте синтаксис. Если в другом сайте уже есть default_server на порту 80, уберите этот параметр в одном из них:
ln -s /etc/nginx/sites-available/mailcow.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Nginx хоста не узнает о продлении сертификата сам. Документация Mailcow предлагает перечитывать конфигурацию раз в сутки. Файл /etc/cron.d/mailcow-nginx-reload:
30 4 * * * root /usr/bin/systemctl reload nginx
Прокси на другой машине добавьте в TRUSTED_PROXIES в mailcow.conf, иначе Mailcow увидит его IP вместо IP клиента. Если на веб-интерфейс нужно заходить под другим именем, например webmail.example.com, впишите его в ADDITIONAL_SERVER_NAMES.
Домен, ящики и DKIM
- «E-Mail» → «Конфигурация» → «Домены» → «Добавить домен». Укажите
example.com, квоты и лимиты ящиков. В том же окне задаются селектор DKIM (по умолчаниюdkim) и длина ключа: оставьте 2048 бит. Ключ создаётся вместе с доменом. - Вкладка «Почтовые ящики» → «Добавить почтовый аккаунт»:
user@example.com, пароль, квота. - Откройте «Система» → «Конфигурация» → «Параметры» → «ARC/DKIM ключи» и скопируйте публичный ключ домена.
Опубликуйте DKIM и DMARC в зоне example.com. Значение p= копируйте из админки целиком. Если DNS-панель не принимает строки длиннее 255 символов, разбейте ключ на несколько строк в кавычках.
dkim._domainkey IN TXT "v=DKIM1; k=rsa; t=s; s=email; p=MIIBIjANBgkqh...ключ_из_админки"
_dmarc IN TXT "v=DMARC1; p=none; rua=mailto:dmarc@example.com"
Начинайте с p=none и ужесточайте политику после чтения отчётов. Как составить SPF, DKIM и DMARC и не сломать отправку с сайта или CRM, разобрано в статье настройка SPF, DKIM и DMARC для своего домена.
В списке доменов у каждого домена есть кнопка «DNS». Она показывает все нужные записи, их текущее значение в DNS и статус проверки. Удобно сверяться после каждой правки зоны.
Проверки после установки
Порты и TLS
ss -tlnp | grep docker-proxy # порты опубликованы Docker
openssl s_client -connect mail.example.com:25 -starttls smtp -servername mail.example.com </dev/null | grep -E 'subject|issuer|Verify'
openssl s_client -connect mail.example.com:993 -servername mail.example.com </dev/null | grep -E 'subject|issuer|Verify'
В выводе должны быть CN = mail.example.com, издатель Let’s Encrypt и Verify return code: 0 (ok).
Нет открытого релея
С другой машины попробуйте отправить письмо на чужой домен без авторизации. Сервер должен отказать (пакет swaks):
swaks --server mail.example.com --port 25 --from test@example.org --to someone@gmail.com
# примерно так: <** 554 5.7.1 <someone@gmail.com>: Relay access denied
Отправка с авторизацией
Отправка от пользователя — только на 587 (STARTTLS) или 465 (TLS сразу) с логином и паролем. Swaks спросит пароль интерактивно:
swaks --server mail.example.com --port 587 --tls \
--auth LOGIN --auth-user user@example.com \
--from user@example.com --to ваш-ящик@gmail.com
В Gmail откройте письмо, затем «Показать оригинал»: SPF, DKIM и DMARC должны быть PASS. Затем отправьте письмо на адрес с mail-tester.com. Оценка ниже 9 из 10 означает, что сервис нашёл проблему: в отчёте будет сказано, какую. Подробно о разборе заголовков и отчётов — в статье почему письма попадают в спам: диагностика.
Логи
Логи читаются через Docker Compose из каталога Mailcow:
cd /opt/mailcow-dockerized
docker compose logs -f postfix-mailcow # приём и отправка
docker compose logs --tail=200 dovecot-mailcow # вход по IMAP, доставка в ящики
docker compose logs --tail=200 rspamd-mailcow # антиспам, DKIM-подпись
docker compose exec postfix-mailcow postqueue -p # очередь Postfix
Те же логи с фильтром доступны в админке: «Система» → «Информация» → «Журналы».
Обновление: update.sh
Mailcow выпускает релизы примерно раз в месяц: номера вида 2026-09, исправления — 2026-09a, 2026-09b. Обновление выполняет скрипт в корне установки. Перед обновлением сделайте резервную копию, см. следующий раздел.
cd /opt/mailcow-dockerized
./update.sh --check # есть ли обновления; код выхода 0 — есть, 3 — нет
./update.sh # обновить: git pull, новые образы, перезапуск стека
./update.sh --gc # удалить старые образы
Перед слиянием скрипт коммитит ваши локальные изменения с пометкой «Before update». Если обновление что-то сломало, найдите этот коммит через git log --pretty=oneline | grep -i "before update", затем выполните docker compose down, git checkout на этот коммит, docker compose pull и docker compose up -d.
Резервные копии: backup_and_restore.sh
Бэкап делает helper-scripts/backup_and_restore.sh. Запускайте его из места, где он находится, копировать скрипт в другой каталог нельзя. Компоненты: vmail (письма), crypt (ключи шифрования хранилища), mysql, redis, rspamd, postfix или all. Копия mailcow.conf кладётся в каждый бэкап.
Без компонента crypt бэкап писем бесполезен: Dovecot в Mailcow шифрует письма на диске, ключи лежат отдельно. Всегда сохраняйте crypt вместе с vmail.
mkdir -p /opt/backup
MAILCOW_BACKUP_LOCATION=/opt/backup \
/opt/mailcow-dockerized/helper-scripts/backup_and_restore.sh backup all --delete-days 7
Ежедневный бэкап через cron, файл /etc/cron.d/mailcow-backup:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
15 3 * * * root cd /opt/mailcow-dockerized && MAILCOW_BACKUP_LOCATION=/opt/backup ./helper-scripts/backup_and_restore.sh backup all --delete-days 7 >/var/log/mailcow-backup.log 2>&1
Каталоги mailcow-ДАТА внутри /opt/backup не переименовывайте. Бэкап на том же диске не спасёт при потере сервера: копируйте бэкапы на другую машину через rsync или restic. Восстановление интерактивное: ./helper-scripts/backup_and_restore.sh restore спросит каталог и компоненты. Проверьте восстановление на тестовой машине хотя бы один раз.
Типичные проблемы
| Симптом | Причина | Что делать |
|---|---|---|
clamd-mailcow перезапускается, в dmesg есть Out of memory: Killed process ... clamd | Мало RAM, нет swap | Добавить swap и память или выставить SKIP_CLAMD=y и выполнить docker compose up -d |
bind: address already in use на порту 25 или 80 | На хосте работает exim4, postfix, nginx или apache | Удалить почтовый сервер хоста; веб-сервер оставить и настроить reverse proxy |
Письма висят в очереди с Connection timed out к чужим MX | Хостер или провайдер закрыл исходящий порт 25 | Запросить открытие порта или настроить relayhost: «Система» → «Конфигурация» → «Маршрутизация» |
| Порт открыт снаружи, хотя в ufw он закрыт | Docker публикует порты в обход цепочки INPUT | Ограничивать в цепочке DOCKER-USER или публиковать порт только на 127.0.0.1 |
| acme-mailcow: IP проверен, но HTTP-проверка не проходит | ufw или firewalld блокирует трафик из сети Mailcow к внешнему интерфейсу | Разрешить трафик или по документации остановить Mailcow, сбросить цепочки и перезапустить Docker |
Gmail отклоняет письма: 550-5.7.25 ... does not have a PTR record, в логе адрес IPv6 | Сервер отправляет по IPv6, а PTR для IPv6 нет | Задать PTR и AAAA для IPv6 или выставить ENABLE_IPV6=false |
| «Слишком много переадресаций» за nginx хоста | В Mailcow остался HTTP_REDIRECT=y | HTTP_REDIRECT=n, затем docker compose up -d |
| Не входит в SOGo за прокси | Нет увеличенных proxy_buffers | Взять буферы из официального примера |
Docker и ufw
Docker сам пишет правила iptables для опубликованных портов: трафик идёт через DNAT и цепочку FORWARD, а правила ufw в INPUT к нему не применяются. Поэтому ufw deny 110 не закроет POP3 Mailcow. Документация Mailcow советует по возможности не включать ufw и firewalld на хосте с Mailcow, а свои правила размещать в цепочке DOCKER-USER: Docker её не очищает при перезапуске.
Для почтового сервера проще не публиковать лишние порты вовсе. Если POP3 не нужен, привяжите его к localhost в mailcow.conf и выполните docker compose up -d:
POP_PORT=127.0.0.1:110
POPS_PORT=127.0.0.1:995
Если доступ нужно ограничить по адресам, пример правила в DOCKER-USER: ManageSieve доступен только из офисной сети 195.270.100.0/24. Сохраняйте правило через iptables-persistent или свой systemd-юнит.
iptables -I DOCKER-USER -p tcp -m conntrack --ctorigdstport 4190 --ctdir ORIGINAL \
! -s 195.270.100.0/24 -j DROP
IPv6
С релиза 2025-09 Mailcow включает IPv6 сам, если находит на хосте рабочий интерфейс с IPv6. Тогда исходящая почта к Gmail и другим крупным получателям пойдёт по IPv6, и нужен полный комплект записей: AAAA для mail.example.com, PTR для IPv6-адреса, IPv6 в SPF (механизм mx его покрывает, если есть AAAA). Не можете задать PTR для IPv6 — выключите его в стеке:
cd /opt/mailcow-dockerized
sed -i 's/^ENABLE_IPV6=.*/ENABLE_IPV6=false/' mailcow.conf
docker compose down
docker compose up -d
Нужен именно down и up: сеть Docker пересоздаётся. Включать IPv6 на хосте с неправильной настройкой Docker опасно. Если Docker подменяет IPv6-адрес клиента внутренним адресом, Postfix может посчитать внешнего отправителя доверенным и пропустить его как релей. Поэтому после включения IPv6 повторите проверку на открытый релей с IPv6-адреса.
Не хочу сопровождать сам
После установки остаются ежемесячные обновления, проверка бэкапов, чёрные списки и разбор недошедших писем. Если заниматься этим некому, рассмотрите готовый корпоративный почтовый сервер с администрированием: сервер выделяется под каждого клиента отдельно, данные под вашим контролем, а обновления, DNS и проблемы с доставкой почты берёт на себя поставщик услуг.
Частые вопросы
Можно ли поставить Mailcow на сервер с 4 ГБ памяти?
Запустить можно, но это ниже официального минимума. Отключите ClamAV (SKIP_CLAMD=y) и полнотекстовый поиск (SKIP_FTS=y), добавьте 2 ГБ swap и не рассчитывайте на много телефонов с ActiveSync: каждый воркер SOGo занимает сотни мегабайт. Для рабочей почты компании закладывайте 8 ГБ.
Будет ли Mailcow работать в контейнере LXC на Proxmox?
Официально нет: OpenVZ, Virtuozzo и LXC не поддерживаются, Docker внутри таких контейнеров ведёт себя непредсказуемо, а ошибки с сетью и правами разработчики не разбирают. На Proxmox создайте полноценную виртуальную машину KVM.
Почему мастер не спросил про ClamAV?
Вопрос появляется, только если на сервере 2,5 ГиБ памяти или меньше. В остальных случаях ClamAV включается по умолчанию. Чтобы его отключить, выставьте SKIP_CLAMD=y в mailcow.conf и выполните docker compose up -d. Rspamd сам перестанет обращаться к антивирусу.
Как добавить второй почтовый домен?
Добавьте домен в админке, создайте для него MX на mail.example.com, CNAME autodiscover и autoconfig, SPF, DKIM из админки и DMARC. A-запись и PTR для второго домена не нужны: сервер остаётся mail.example.com. После появления CNAME acme-mailcow сам добавит имена autodiscover и autoconfig нового домена в сертификат.
Где хранятся письма и как перенести Mailcow на другой сервер?
Письма лежат в Docker-томе mailcowdockerized_vmail-vol-1, ключи шифрования — в mailcowdockerized_crypt-vol-1, база — в томе MariaDB. Для переноса поставьте Mailcow на новый сервер той же версии, сделайте на старом backup_and_restore.sh backup all, скопируйте каталог бэкапа и выполните restore. Затем перенесите DNS и PTR на новый IP.
Нужно ли ставить Postfix и Dovecot на хост с Debian 13?
Нет. Все почтовые сервисы работают в контейнерах со своими версиями. Пакеты Postfix и Dovecot на хосте только займут порты 25 и 993 и помешают запуску. Системные письма хоста, например от cron, отправляйте через Mailcow с авторизацией клиентом вроде msmtp.