SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Настройка mailcow на VPS: как отправлять почту в Gmail

Перед установкой mailcow проверьте доступность порта 25, иначе письма останутся в очереди. Настройте DNS и PTR записи, чтобы избежать ошибки 550 5.7.25 при отправке в Gmail.

Что вы создаете

Полноценный почтовый сервер на собственном оборудовании: SMTP для отправки и получения, IMAP для синхронизации между телефоном и ноутбуком, веб-клиент для почты и спам-фильтр, оценивающий каждое сообщение в обоих направлениях. mailcow-dockerized объединяет Postfix, Dovecot, Rspamd, SOGo, MariaDB, Redis и ACME-клиент в единый стек Docker Compose, поэтому настройка программного обеспечения не вызовет затруднений. Вы запустите его за полчаса.

Сложность заключается во всем остальном. Электронная почта — это сервис, к которому остальная часть интернета относится с активным недоверием, если сервер новый. Разрыв между состоянием «все работает» и ситуацией, когда «Gmail молча удаляет все сообщения», сводится в основном к четырем DNS-записям и одной настройке репутации IP-адреса, которую вы, возможно, не полностью контролируете. Ознакомьтесь с предварительными требованиями ниже, прежде чем арендовать сервер. Если после прочтения вы решите, что борьба за репутацию того не стоит, это вполне разумное решение; в нашем обзоре того, что действительно стоит размещать самостоятельно в 2026 году, электронная почта отнесена к категории «только если вы серьезно настроены» именно по этим причинам.

Предварительные требования — это и есть проект

Пропуск любого из этих пунктов приведет к тому, что почта не будет доставлена. Ниже приведен список в порядке убывания частоты возникновения проблем:

Исходящий порт 25 должен быть открыт. Ваш сервер доставляет почту в Gmail и Microsoft по протоколу TCP через порт 25. Большинство VPS и облачных провайдеров блокируют исходящий 25 порт по умолчанию для борьбы со спамом. Эта блокировка происходит без уведомлений: при загрузке ошибок нет, всё выглядит исправно, а письма остаются в очереди в состоянии deferred, пока Postfix не сдастся и не вернет их отправителю (mailcow устанавливает максимальное время жизни очереди на пять дней). Проверьте порт до начала установки. Если он заблокирован, единственный способ решения — создать тикет в поддержку с просьбой открыть его; некоторые провайдеры делают это для старых аккаунтов, некоторые — никогда.

Чистый IP-адрес с хорошей репутацией. IP-адреса, ранее использовавшиеся на VPS, часто уже находятся в черных списках из-за спама предыдущего владельца. Проверьте свой адрес в таких сервисах, как Spamhaus или mxtoolbox, прежде чем приступать к работе. Нахождение IP в черном списке приведет к отклонению писем, которое невозможно исправить программными методами.

Контроль над DNS и корректная PTR-запись. Вам необходимо добавлять записи в зону вашего домена, а также настроить обратную DNS-запись (PTR) для IP-адреса сервера, указывающую на ваш почтовый hostname. PTR-запись почти никогда не настраивается в вашей DNS-панели; она управляется владельцем IP-адреса, поэтому настраивается в панели управления вашего VPS-провайдера или через тикет в поддержку.

6 GiB RAM и 2 vCPU — комфортный минимум. Минимальные требования mailcow для частной установки составляют 6 GiB RAM плюс 1 GiB swap, при этом рекомендуется 8 GiB, если системой пользуется несколько человек. При объеме менее 2.5 GiB generate_config.sh предлагает отключить антивирусный сканер ClamAV, чтобы ядро не начало принудительно завершать контейнеры. Документированный минимум дискового пространства для mailcow составляет 20 GiB до начала хранения почты, поэтому выделите больше места при установке, чтобы оставить запас для роста почтовых ящиков.

DNS-имя, а не просто IP-адрес. Выберите имя хоста, например mail.example.com. Это имя станет вашим MAILCOW_HOSTNAME, субъектом TLS-сертификата, целью PTR-записи и SMTP-баннером. Поддерживайте единообразие во всех настройках.

Шаг 1. Проверка доступности исходящего порта 25

Выполните это действие в первую очередь. Если проверка не пройдена, дальнейшие усилия будут напрасны. С нового VPS попробуйте инициировать SMTP-сессию с реальным почтовым сервером:

sudo apt update && sudo apt install -y netcat-openbsd
nc -vz -w 5 gmail-smtp-in.l.google.com 25

Успешный результат выглядит так:

Connection to gmail-smtp-in.l.google.com (142.250.x.x) 25 port [tcp/smtp] succeeded!

Заблокированный порт вызывает зависание на 5 секунд, после чего соединение прерывается:

nc: connect to gmail-smtp-in.l.google.com port 25 (tcp) timed out: Operation now in progress

На новом VPS без собственных правил исходящего сетевого экрана такой таймаут означает блокировку со стороны провайдера. Это сетевой фильтр на стороне провайдера, а не ваш локальный firewall, поэтому локальные изменения не помогут. Создайте тикет в поддержку: «Пожалуйста, откройте исходящий TCP-порт 25 для моего VPS с IP <IP>; я разворачиваю легитимный почтовый сервер». Не устанавливайте mailcow, пока не получите ответ «succeeded». Учтите, что входящий порт 25 (соединения от других серверов к вам) — это отдельный канал, который обычно открыт; провайдеры ограничивают именно исходящий трафик.

Шаг 2, настройка DNS-записей

Распространение DNS-записей занимает время, поэтому опубликуйте все необходимые данные до начала установки. Предположим, что ваш домен — example.com, почтовый хост — mail.example.com, а IP-адрес — 10.0.0.10. Создайте в своей зоне следующие записи:

mail.example.com.        A      10.0.0.10
mail.example.com.        AAAA   2001:db8::10          ; only if you have IPv6
example.com.             MX  10 mail.example.com.
example.com.             TXT    "v=spf1 mx -all"
_dmarc.example.com.      TXT    "v=DMARC1; p=none; rua=mailto:postmaster@example.com"

SPF-запись указывает: «только мой MX-сервер может отправлять почту от имени этого домена, остальные отклонять». Начните использование DMARC с p=none, чтобы отслеживать отчеты, не блокируя при этом собственную почту; после подтверждения корректности настроек ужесточите политику до p=quarantine, а затем до p=reject. Две записи намеренно пропущены: DKIM, которую mailcow сгенерирует для вас на шаге 6, и PTR, которую нужно настроить сейчас в панели управления вашего хостинг-провайдера.

Установите PTR-запись (обратный DNS) для 10.0.0.10 в значение mail.example.com, которое в точности соответствует MAILCOW_HOSTNAME. Это единственная запись, о которой чаще всего забывают, и крупные почтовые провайдеры отклоняют письма именно из-за её отсутствия. Если в вашей панели управления нет поля для rDNS, обратитесь в службу поддержки.

Шаг 3, установка Docker

Для работы mailcow требуется Docker Engine версии 24.0 или новее и Docker Compose версии 2.0 или новее. Использование плагина Compose (docker compose) — самый простой способ, хотя mailcow также поддерживает отдельный бинарный файл docker-compose. Используйте официальный скрипт установки Docker вместо пакета docker.io из репозиториев Ubuntu, так как он не содержит плагин Compose:

curl -fsSL https://get.docker.com | sudo sh
sudo docker compose version

Вы должны увидеть строку Docker Compose version, указывающую на версию v2.x или v5.x. Версия Compose v5, выпущенная в 2025 году, функционально идентична v2, и любая из них подходит для mailcow. Если docker compose version выводит docker: 'compose' is not a docker command, значит, Docker Engine установлен, но плагин Compose отсутствует. Установите плагин из репозитория Docker, повторно запустите указанный выше скрипт или воспользуйтесь нашим руководством по основам Docker Compose, в котором описывается установка обоих компонентов из официального apt-репозитория Docker.

Шаг 4: Клонирование mailcow и генерация конфигурации

cd /opt
sudo git clone https://github.com/mailcow/mailcow-dockerized
cd mailcow-dockerized
umask
sudo ./generate_config.sh

Проверка того, что umask выводит 0022, соответствует стандартной процедуре установки mailcow, которая требует настройки umask 0022 перед клонированием. В mailcow нет проверок этого значения, а в свежей оболочке root на Ubuntu 24.04 оно уже равно 0022. Затем скрипт запрашивает единственный критически важный параметр: полное доменное имя (FQDN). Введите mail.example.com; значение должно в точности совпадать с вашей A-записью и PTR-записью. Скрипт создает файл mailcow.conf — единственный файл окружения, который считывает весь стек. Откройте его, если нужно изменить веб-порты (HTTP_PORT, HTTPS_PORT) или отключить ClamAV на сервере с ограниченными ресурсами:

MAILCOW_HOSTNAME=mail.example.com
HTTP_PORT=80
HTTPS_PORT=443
SKIP_CLAMD=n          # set to y to drop the virus scanner on a <2.5 GiB box

SKIP_FTS=y — еще один рычаг управления для сервера с малым объемом ОЗУ: полнотекстовый поиск является вторым по потреблению памяти компонентом согласно документации mailcow, а его отключение лишит вас лишь возможности поиска по телу писем в веб-интерфейсе.

Оставьте HTTP_PORT=80 и HTTPS_PORT=443 без изменений, если они не заняты другими сервисами на хосте. Встроенный ACME-клиент mailcow по умолчанию использует проверку HTTP-01, для которой порт 80 должен быть доступен из Интернета для получения сертификата. (Начиная с версии mailcow 2026-03, можно использовать проверку DNS-01 через ACME_DNS_CHALLENGE=y, которая не требует порта 80, но требует доступа к API вашего DNS-провайдера.) Именно поэтому простая схема не предполагает отдельную настройку nginx-plus-Certbot на том же сервере; mailcow выпускает и обновляет свои TLS-сертификаты самостоятельно, а второй сервис, занимающий порты 80/443, нарушит этот процесс. В документации mailcow описан альтернативный вариант: привязать веб-слушатели к локальному адресу через HTTP_BIND=127.0.0.1 HTTP_PORT=8080 HTTPS_BIND=127.0.0.1 HTTPS_PORT=8443, установить reverse proxy на порты 80 и 443 и, если вы хотите, чтобы локальный Certbot управлял сертификатами, указать mailcow путь к ним и добавить хук для обновления. Это усложняет обслуживание почтового сервера, поэтому тот же компромисс применим к любому другому сервису, требующему публичный веб-интерфейс: сборка вроде Halcyon, стилизующая библиотеку Jellyfin под видеопрокат 90-х, которая ожидает собственный reverse proxy на 443 порту, должна размещаться на другом хосте, если только вы не перенесете mailcow за этот прокси. Исключение составляют сервисы, которые вообще не требуют публичного веб-порта: самохостный релей RustDesk слушает только свой диапазон портов с 21115 по 21119, поэтому он может сосуществовать на одном сервере, если у вас достаточно свободной пропускной способности сети.

Шаг 5, запуск стека и вход в систему

sudo docker compose pull
sudo docker compose up -d
sudo docker compose ps

Команда pull загружает около двух десятков образов; подождите несколько минут. Когда docker compose ps покажет, что все контейнеры имеют статус running (или healthy), откройте https://mail.example.com/admin в браузере. Стандартные учетные данные администратора: имя пользователя admin, пароль moohoo. Немедленно измените пароль в административном интерфейсе в разделе System → Configuration, затем Access → Administrators. Если браузер выдает предупреждение NET::ERR_CERT_AUTHORITY_INVALID, значит, ACME-сертификат еще не выпущен. Ознакомьтесь с разделом об ошибках ACME ниже, прежде чем считать, что система неисправна; самоподписанный временный сертификат — это нормальное явление в первые пару минут.

Шаг 6, добавление домена, почтового ящика и публикация DKIM

В административном интерфейсе откройте E-Mail → Configuration, на вкладке Domains нажмите Add domain и введите example.com. Затем в разделе Mailboxes нажмите Add mailbox, чтобы создать you@example.com с паролем. Это уже рабочий почтовый ящик, доступный по протоколу IMAP.

Теперь настроим DKIM-ключ. Перейдите в System → Configuration, затем Options → ARC/DKIM keys. Возможно, mailcow уже сгенерировал ключ при добавлении домена. Если нет, сгенерируйте его там: выберите домен, оставьте селектор dkim, выберите длину 2048-bit и нажмите Add. Скопируйте длинное значение TXT, которое отобразится, и опубликуйте его как:

dkim._domainkey.example.com.  TXT  "v=DKIM1;k=rsa;t=s;s=email;p=MIIBIjANBgkqh...long-key...QAB"

На странице Domains в mailcow есть кнопка DNS, которая перечисляет все ожидаемые записи и показывает зеленую галочку или красный крестик напротив фактически опубликованных. Используйте её как контрольный список: добейтесь того, чтобы все строки стали зелеными, прежде чем проверять доставляемость почты. Красная строка DKIM после публикации обычно означает, что ключ был некорректно разбит на части TXT; ключ длиной 2048 бит превышает лимит в 255 символов для одной строки TXT. Вставьте его как единое логическое значение, и ваш DNS-провайдер автоматически разобьет его на части.

Шаг 7, проверка доставляемости и получение оценки 10/10

Перейдите на сайт mail-tester.com, скопируйте предложенный случайный адрес и отправьте на него письмо с вашего нового почтового ящика. Войдите в веб-интерфейс SOGo по адресу https://mail.example.com/SOGo и отправьте письмо оттуда. Затем нажмите кнопку "Then check your score".

Ваша цель — оценка 10/10. Распространенные причины снижения баллов:

  • SPF not aligned: отсутствует запись MX/SPF или IP-адрес отправителя не включен в нее. Перепроверьте TXT-запись SPF.
  • DKIM signature does not verify: отсутствует TXT-запись dkim._domainkey, она еще не успела распространиться по DNS или содержит ошибки. Это самая частая проблема.
  • No PTR / PTR mismatch: обратная DNS-запись (PTR) не указывает на mail.example.com. Исправьте это в панели управления вашего хостинг-провайдера.
  • Listed on a blocklist: плохая репутация вашего IP-адреса. Подайте запрос на исключение из черного списка или запросите у провайдера другой IP-адрес.

Не отправляйте реальные письма на Gmail или Outlook, пока не получите оценку 10/10. Низкий рейтинг в сочетании с новым IP-адресом — прямой путь к попаданию вашего домена в спам-фильтры в первый же день.

Шаг 8, подключение почтового клиента

Настройте Thunderbird, Apple Mail или мобильное устройство для работы с сервером, используя следующие параметры. В качестве хоста сервера для всех настроек укажите mail.example.com:

  • IMAP: порт 993, SSL/TLS (или 143 с использованием STARTTLS)
  • SMTP submission: порт 465, SSL/TLS (или 587 с использованием STARTTLS)
  • Имя пользователя: полный адрес электронной почты, you@example.com
  • Пароль: пароль почтового ящика, который вы задали

Никогда не отправляйте почту через порт 25. Этот порт предназначен только для взаимодействия между серверами. mailcow не поддерживает аутентифицированную отправку на этом порту, и попытка подключения клиента будет отклонена. Если клиент сообщает об ошибке Relay access denied, значит, он пытается отправить почту через порт 25 или без аутентификации. Переключите его на порт 465 или 587 и используйте учетные данные вашего почтового ящика.

Шаг 9, резервное копирование действительно важных данных

mailcow поставляется со скриптом резервного копирования, который создает снимки всех томов с состоянием. Запускайте его на внешний диск или смонтированный удаленный ресурс:

sudo MAILCOW_BACKUP_LOCATION=/opt/mailcow-backups \
  ./helper-scripts/backup_and_restore.sh backup all

all захватывает шесть компонентов, потеря любого из которых ведет к потере данных: vmail (сами почтовые ящики), crypt (ключи для расшифровки vmail, бесполезные без самих данных), mysql (база данных MariaDB, содержащая домены, пользователей, псевдонимы и настройки), redis (очереди и состояние кэша), rspamd (обученные фильтры спама/хам-писем) и postfix (почтовая очередь). Скрипт выполняется внутри вспомогательного контейнера и создает сжатые архивы, поэтому резервные копии остаются консистентными, даже если стек запущен. Автоматизируйте процесс с помощью ночного задания cron и добавьте --delete-days 14 для удаления старых наборов данных. Задание cron, которое перестало работать, не выдает уведомлений об ошибках, поэтому отправляйте код завершения скрипта туда, где вы его гарантированно заметите; собственный сервер ntfy позволяет выполнить одну команду curl в той же записи cron, чтобы получить уведомление о сбое на телефон в ту же ночь. Восстановление выполняется тем же скриптом с флагом restore, который выводит список снимков и позволяет выбрать нужный для восстановления. Резервная копия, которую вы никогда не пробовали восстанавливать — это лишь надежда, а не копия; проведите тестовое восстановление на временном VPS.

Шаг 10, Обновление по расписанию

mailcow обновляется через собственный скрипт, который загружает новый код, выполняет миграции mailcow.conf, предварительно скачивает образы и перезапускает контейнеры в нужном порядке:

cd /opt/mailcow-dockerized
sudo ./update.sh --check   # reports whether an update exists, changes nothing
sudo ./update.sh           # applies it

Сначала выполните резервное копирование (Шаг 9), так как миграцию схемы базы данных сложно отменить. Обновления выходят часто и включают исправления безопасности для демонов, доступных из Интернета, поэтому не допускайте длительного отставания почтового сервера от актуальной версии. Если после обновления какой-либо контейнер переходит в состояние unhealthy, команда sudo docker compose logs --tail=50 <service>-mailcow покажет имя демона, который не смог запуститься.

Замечание по обеспечению безопасности

mailcow использует собственный сервис netfilter (netfilter-mailcow), который блокирует IP-адреса, осуществляющие перебор паролей к портам почтового сервера и веб-интерфейса, поэтому почтовая часть защищена «из коробки». Это не распространяется на SSH самого хоста, который остается открытым и подвергается попыткам брутфорса. Используйте данную сборку в сочетании с мониторингом логов авторизации SSH через Fail2ban и входом только по ключам. Защитите административный интерфейс mailcow надежным паролем и, по возможности, ограничьте к нему доступ из публичной сети или используйте VPN.

Режимы сбоев и точные строки ошибок

Почта находится в очереди и не доставляется. Выполните sudo docker compose exec postfix-mailcow postqueue -p или просмотрите очередь почты в административном интерфейсе; записи остаются в состоянии deferred до пяти дней, прежде чем Postfix вернет их отправителю с сообщением:

status=deferred (connect to gmail-smtp-in.l.google.com[142.250.x.x]:25: Connection timed out)

Это почти всегда означает, что исходящий порт 25 заблокирован вашим провайдером (шаг 1). Исходящее правило в локальном файрволе хоста вызывает такой же таймаут, поэтому сначала исключите эту причину; если на хосте всё чисто, никакие правки конфигурации не помогут — открывайте тикет в поддержку. Это не проблема DNS и не проблема TLS; ключевым признаком является слово timed out при попытке соединения с удаленным MX на порту 25.

Gmail помечает всё как спам или отклоняет письма. Откройте сообщение в Gmail, выберите «Показать оригинал» и прочитайте результаты проверки аутентификации. dkim=fail или dkim=none означают, что ваша запись dkim._domainkey TXT отсутствует, повреждена или еще не распространилась; опубликуйте в точности то, что указано на странице ARC/DKIM, и дождитесь истечения TTL. spf=fail означает, что записи SPF/MX не включают ваш IP-адрес. Соответствие (alignment) критически важно; одной непройденной проверки достаточно, чтобы письмо попало в спам.

Отклонение крупными провайдерами при подключении. В сообщениях о возврате или логах Postfix содержится ошибка PTR от Gmail:

550-5.7.25 [10.0.0.10] The IP address sending this message does not have a PTR
550-5.7.25 record setup, or the corresponding forward DNS entry does not match
550 5.7.25 the sending IP. As a policy, Gmail does not accept messages from IPs
550 5.7.25 with missing PTR records.

Код 550 5.7.25 означает отсутствие или несоответствие обратной DNS-записи. Установите PTR для вашего IP-адреса в значение mail.example.com в панели управления провайдера (шаг 2). Прямая (A) и обратная (PTR) записи должны совпадать, и обе должны указывать на то же имя хоста, под которым mailcow представляется другим серверам.

Браузер показывает предупреждение о сертификате, которое не исчезает. Контейнер acme-mailcow не смог получить реальный сертификат. Проверьте его лог:

sudo docker compose logs acme-mailcow | tail -n 40

Строка вида Cannot validate any hostnames, skipping Let's Encrypt for 1 hour. или ошибка проверки (challenge failure) означают, что порт 80 недоступен из Интернета или A-запись не указывает на этот сервер. Если вы опубликовали AAAA-запись, проверьте и её: mailcow выполняет проверку по AAAA-записи в первую очередь и пропускает проверку A-записи, если AAAA существует. Поэтому неверная AAAA-запись или путь IPv6, не имеющий доступа к порту 80, приведут к сбою валидации, даже если A-запись корректна. Убедитесь, что mail.example.com разрешается в IP вашего сервера, откройте порты 80 и 443 в файрволе хоста и убедитесь, что другие процессы не занимают эти порты. После устранения причины перезапустите клиент командой sudo docker compose restart acme-mailcow, вместо того чтобы ждать часового интервала повторной попытки.

FAQ

Стоит ли вообще заниматься self-hosting для почты?

Если вам важен контроль над данными, неограниченное количество алиасов и полная независимость, то да, mailcow предоставляет профессиональный стек по цене VPS. Однако доставляемость писем — это постоянная работа: репутация IP-адреса, настройка DNS и мониторинг черных списков не заканчиваются никогда. Для критически важного бизнес-адреса, где один день в папке «Спам» у получателя стоит денег, лучше выбрать управляемого провайдера. Занимайтесь self-hosting, если вы цените контроль выше удобства и готовы обслуживать систему. Если же ваша цель — просто хранить данные на своем сервере, а не обязательно почту, начните с сервиса, который не зависит от внешних факторов: у фотогалереи нет проблем с доставляемостью, а наше сравнение PhotoPrism и Immich содержит информацию о требованиях к оперативной памяти и командах резервного копирования для таких решений на аналогичных VPS.

Как узнать, заблокирован ли исходящий порт 25?

Выполните nc -vz -w 5 gmail-smtp-in.l.google.com 25 с сервера. Сообщение «succeeded!» означает, что порт открыт; timed out после паузы означает, что порт заблокирован. Если на сервере нет ваших собственных правил межсетевого экрана, значит, блокировку установил провайдер. Это самая частая причина, по которой self-hosted сервер может принимать почту, но не отправлять её. Единственный способ исправить это — попросить провайдера открыть порт; локальные настройки здесь не помогут.

Почему моя почта всё равно попадает в папку «Спам» в Gmail?

Почти всегда дело в нарушенной цепочке аутентификации. Используйте функцию «Показать оригинал» (Show original) в Gmail и проверьте значения spf=pass, dkim=pass и dmarc=pass. Статус dkim=fail указывает на отсутствие или ошибку в TXT-записи dkim._domainkey; также на репутацию влияют несоответствие PTR-записи или новый IP-адрес без истории отправки писем. Сначала добейтесь оценки 10/10 на mail-tester.com, а затем постепенно прогревайте IP-адрес, увеличивая количество отправляемых писем день за днем, вместо массовой рассылки в первый же день.

Что именно нужно копировать при резервном копировании?

Выполните backup_and_restore.sh backup all и храните полученный архив вне сервера. Он содержит vmail (почтовые ящики), crypt (ключи для их расшифровки), базу данных MariaDB (домены, пользователи, алиасы, настройки), Redis, данные обучения Rspamd и очередь Postfix. Том crypt — это то, что часто забывают; без него резервная копия vmail представляет собой нечитаемый зашифрованный текст. Хотя бы раз протестируйте восстановление на тестовой машине.

Можно ли запустить mailcow на VPS с 2 ГБ оперативной памяти?

Не рекомендуется. generate_config.sh предлагает отключить ClamAV, если памяти меньше 2.5 ГБ, но даже с выключенным ClamAV, Rspamd, Dovecot, MariaDB и остальные компоненты стека будут конкурировать за ресурсы. При любой реальной нагрузке вы столкнетесь с использованием swap и принудительным завершением процессов (OOM kill). Считайте 6 ГБ оперативной памяти и 1 ГБ swap минимальным порогом для стабильной установки на одного пользователя, а при подключении еще нескольких человек сразу переходите на 8 ГБ.