SSD Nodes Learn Hosting plans →
Посібники Matt ConnorВід Matt Connor · Оновлено 2026-08-28

Mailcow на VPS: як зробити пошту прийнятною для Gmail

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

Що ви створюєте

Повноцінний mail server на власному сервері: SMTP для надсилання й отримання пошти, IMAP для синхронізації телефона та ноутбука, webmail-клієнт і spam filter, який оцінює кожне повідомлення в обох напрямках. mailcow-dockerized об’єднує Postfix, Dovecot, Rspamd, SOGo webmail, MariaDB, Redis і ACME-клієнт в один Docker Compose stack, тому програмне забезпечення не є складною частиною. Система працюватиме приблизно за пів години.

Складною є вся інфраструктура навколо неї. Email — єдиний сервіс, якому решта інтернету активно не довіряє одразу після запуску нового сервера. Різниця між «усе працює» і «Gmail мовчки відкидає кожне повідомлення» зводиться до чотирьох DNS-записів і одного параметра репутації IP-адреси, на який ви можете не мати повного впливу. Прочитайте наведені нижче передумови, перш ніж щось орендувати. Якщо після цього ви вирішите, що формування репутації не варте зусиль, це цілком обґрунтоване рішення: у нашому огляді того, що справді варто розміщувати самостійно у 2026 році email віднесено до категорії «лише якщо ви справді цього хочете» саме з цих причин.

Передумови — це і є проєкт

Пропустіть будь-яку з цих умов — і ви надсилатимете пошту, яка ніколи не надійде. Приблизний порядок за частотою, з якою ці умови стають причиною проблем:

Вихідний порт 25 має бути відкритий. Ваш сервер доставляє пошту до Gmail і Microsoft через TCP-порт 25. Значна частина VPS- і cloud-провайдерів типово блокує вихідний порт 25 для боротьби зі спамом. Блокування відбувається без повідомлень: під час запуску помилки не виникають, усе виглядає справним, а пошта просто назавжди залишається в черзі. Перевірте це до встановлення будь-яких компонентів. Якщо порт заблокований, єдиний спосіб вирішити проблему — надіслати запит до служби підтримки провайдера з проханням відкрити його. Деякі провайдери роблять це для облікових записів із достатнім строком існування, а деякі не відкривають його ніколи.

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

Контроль над DNS і правильний запис PTR. Вам потрібно додавати записи до DNS-зони домену, а також налаштувати reverse 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, щоб kernel не почав завершувати роботу контейнерів. На початковому етапі виділіть 20 GB SSD.

DNS-ім’я, а не сама IP-адреса. Виберіть hostname на кшталт 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!

Заблокований порт очікує всі п’ять секунд, а потім завершується помилкою:

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

Таке очікування означає блокування. Це мережевий фільтр на стороні провайдера, а не ваш firewall, тому локальні зміни не допоможуть. Створіть запит у підтримку: «Будь ласка, увімкніть вихідний TCP-порт 25 для мого VPS за адресою <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, створіть ticket.

Крок 3. Встановлення Docker

mailcow потребує Docker Engine із плагіном Compose v2. Використовуйте офіційний convenience script від Docker, а не пакет Ubuntu docker.io, у якому взагалі немає плагіна Compose:

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

Має з’явитися рядок Docker Compose version v2.x. Якщо 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 не виконує збірку з непарною маскою файлів, а свіжа root-сесія в Ubuntu 24.04 вже має 0022. Потім скрипт запитає єдине важливе значення: повне доменне ім’я хоста. Введіть 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 — ще один параметр, важливий для сервера з малим обсягом RAM: повнотекстовий пошук є другим найбільшим споживачем пам’яті за документацією mailcow. Його вимкнення позбавляє лише пошуку за текстом листів у вебпошті.

Залиште HTTP_PORT=80 і HTTPS_PORT=443 без змін, якщо тільки інший сервіс на хості вже не використовує ці порти. Вбудованому ACME-клієнту mailcow потрібен доступний з інтернету порт 80, щоб отримати сертифікат. Саме тому не слід запускати на цьому сервері окрему конфігурацію nginx із Certbot: mailcow самостійно видає та поновлює TLS-сертифікат, а другий сервіс, який займає порт 80/443, порушить цю роботу. Те саме стосується будь-якого іншого сервісу, якому потрібен публічний вебінтерфейс. Тому схема на кшталт Halcyon, що перетворює бібліотеку Jellyfin на відеомагазин у стилі 90-х, яка очікує власний reverse proxy на 443, має працювати на іншому хості. Виняток — сервіс, якому взагалі не потрібен публічний вебпорт: self-hosted relay 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, пароль moohoo. Негайно змініть цей пароль в адміністративному інтерфейсі в розділі Access → Administrators. Якщо браузер показує попередження NET::ERR_CERT_AUTHORITY_INVALID, сертифікат ACME ще не видано. Перш ніж вважати, що система несправна, перегляньте опис помилки ACME нижче. Самопідписаний тимчасовий сертифікат протягом першої-двох хвилин є нормальною ситуацією.

Крок 6. Додайте домен, поштову скриньку та опублікуйте DKIM

В адміністративному інтерфейсі відкрийте сторінку Mail Setup (Configuration → Mail Setup). На вкладці Domains натисніть Add domain і введіть example.com. Потім у розділі Mailboxes натисніть Add mailbox, щоб створити you@example.com із паролем. Поштова скринька одразу буде доступна через IMAP.

Тепер налаштуйте DKIM-ключ. Перейдіть до Configuration → 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. Вона показує всі записи, які очікує mailcow, і позначає зеленим прапорцем або червоним хрестиком, що фактично опубліковано. Використовуйте цей список як контрольний. Перед перевіркою доставляння пошти всі рядки мають бути позначені зеленим.

Червоний рядок DKIM після публікації зазвичай означає, що ключ неправильно розділили на частини TXT-запису. Ключ 2048-bit довший за обмеження 255 символів для одного рядка TXT. Вставте його як одне логічне значення, а DNS-провайдер розділить його на частини автоматично.

Крок 7. Перевірте доставляння та отримайте 10/10

Перейдіть на mail-tester.com, скопіюйте випадкову адресу, яку він покаже, і надішліть на неї повідомлення з нової поштової скриньки. Увійдіть у вебпошту SOGo за адресою https://mail.example.com/SOGo і надішліть повідомлення звідти. Потім натисніть "Then check your score".

Прагніть отримати 10/10. Найчастіші причини зниження оцінки:

  • SPF не узгоджений — запис MX/SPF відсутній або IP-адреса відправника не охоплена ним. Повторно перевірте SPF TXT-запис.
  • Підпис DKIM не проходить перевірку — TXT-запис dkim._domainkey відсутній, ще поширюється або пошкоджений. Це найпоширеніша проблема.
  • Немає PTR або PTR не збігається — зворотний DNS не повертає mail.example.com. Виправте це в панелі провайдера.
  • IP-адресу внесено до 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 (поштова черга). Скрипт працює всередині допоміжного контейнера та записує стиснені архіви, тому резервні копії залишаються узгодженими навіть під час роботи всього стека. Автоматизуйте його за допомогою nightly cron job і додайте --delete-days 14, щоб видаляти старі набори. cron job, який перестав працювати, завершується без повідомлення, тому передавайте код завершення скрипту туди, де ви його точно помітите; self-hosted ntfy server приймає однорядковий curl із того самого cron entry і надсилає повідомлення про збій на ваш телефон у ніч, коли він стався. Відновлення виконується тим самим скриптом із 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), оскільки міграцію схеми складно скасувати. Оновлення виходять часто та містять виправлення безпеки для daemon, доступних з Інтернету, тому не залишайте поштовий сервер без оновлень на місяці. Якщо після оновлення контейнер перейде в несправний стан, sudo docker compose logs --tail=50 <service>-mailcow назве daemon, який не зміг запуститися знову.

Нотатка про hardening

mailcow запускає власний сервіс netfilter (netfilter-mailcow), який блокує IP-адреси, що надсилають велику кількість запитів до портів пошти та webmail. Тому поштову частину системи захищено з коробки. Це не захищає SSH на самому хості: він і далі доступний ззовні та зазнає brute-force-атак. Для цього налаштування додатково використовуйте Fail2ban для моніторингу журналу автентифікації SSH і вхід лише за ключами. Захистіть адміністративний інтерфейс mailcow надійним паролем і, за можливості, закрийте до нього доступ із публічного інтернету або розмістіть його за VPN.

Типові збої з точними рядками

Поштові повідомлення залишаються в черзі й ніколи не доставляються. Виконайте sudo docker compose exec postfix-mailcow postqueue -p або перегляньте поштову чергу в адміністративному інтерфейсі; записи залишаються зі статусом deferred і містять:

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, виберіть «Show original» і перегляньте результати автентифікації. dkim=fail або dkim=none означає, що ваш запис dkim._domainkey TXT відсутній, пошкоджений або ще не розповсюдився. Опублікуйте його точно в тому вигляді, як показано на сторінці ARC/DKIM, і дочекайтеся завершення TTL. spf=fail означає, що записи SPF/MX не охоплюють вашу IP-адресу. Відповідність імені та домену має вирішальне значення: однієї невдалої перевірки достатньо, щоб повідомлення потрапило до спаму.

Великі провайдери відхиляють з’єднання. У повідомленнях про недоставлення або журналах Postfix міститься відхилення Gmail через PTR:

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 відсутній або не відповідає очікуваному значенню. Установіть для своєї IP-адреси PTR зі значенням 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 означає, що порт 80 недоступний з Інтернету або запис A не вказує на цей сервер. Переконайтеся, що mail.example.com розв’язується в IP-адресу цього сервера, відкрийте порти 80 і 443 у всіх host firewall та перевірте, що їх не зайняв інший процес. Після усунення причини перезапустіть клієнт командою sudo docker compose restart acme-mailcow, а не чекайте завершення годинної затримки повторної спроби.

FAQ

Чи справді варто самостійно хостити електронну пошту?

Якщо вам потрібні контроль над даними, необмежена кількість псевдонімів і повний контроль, так: mailcow надає професійний стек за ціною VPS. Але доставлення листів потребує постійної уваги: репутація IP-адреси, узгодженість DNS і моніторинг списків блокування ніколи повністю не завершуються. Для критично важливої робочої адреси, коли один день у папці спаму може завдати значних збитків, керований провайдер є практичним вибором. Обирайте self-hosting, якщо цінуєте контроль більше за зручність і справді готові підтримувати систему. Якщо насправді вам потрібно лише зберігати дані не на чужих серверах, а не обов’язково самостійно хостити пошту, почніть із сервісу, де ніхто інший не має права голосу: у фотобібліотеки взагалі немає проблем із доставленням, а в нашому порівнянні PhotoPrism та Immich описано мінімальні вимоги до RAM і команди резервного копіювання для такого розгортання на VPS подібного типу.

Як дізнатися, чи заблоковано вихідний порт 25?

Виконайте nc -vz -w 5 gmail-smtp-in.l.google.com 25 на сервері. Повідомлення "succeeded!" означає, що порт відкритий; timed out після паузи означає, що провайдер його блокує. Це найпоширеніша причина, через яку self-hosted сервер може отримувати пошту, але не може її надсилати. Єдиний спосіб виправити це — попросити провайдера відкрити порт. Локальні зміни налаштувань не допоможуть.

Чому мої листи досі потрапляють у папку спаму Gmail?

Майже завжди причина полягає в неправильному ланцюжку автентифікації. У Gmail виберіть "Show original" і знайдіть spf=pass, dkim=pass та dmarc=pass. dkim=fail вказує на відсутній або пошкоджений TXT-запис dkim._domainkey. Невідповідність PTR або нова IP-адреса без історії надсилання також погіршують доставлення. Спочатку доведіть результат mail-tester.com до 10/10, а потім поступово прогрівайте IP-адресу: надсилайте по кілька повідомлень на день і поступово збільшуйте обсяг, а не надсилайте великий обсяг у перший день.

Що саме потрібно резервно копіювати?

Виконайте backup_and_restore.sh backup all і зберігайте весь набір за межами сервера. Він охоплює vmail (поштові скриньки), crypt (ключі для їх розшифрування), базу даних MariaDB (домени, користувачі, псевдоніми, налаштування), Redis, накопичені дані Rspamd і чергу Postfix. Том crypt часто залишають без уваги. Без нього резервна копія vmail є непридатним для читання шифротекстом. Принаймні один раз перевірте відновлення на тестовому сервері.

Чи можна запустити mailcow на VPS із 2 GB RAM?

Не з належним комфортом. generate_config.sh пропонує вимкнути ClamAV, якщо обсяг пам’яті менший приблизно за 2.5 GiB. Навіть після цього Rspamd, ClamAV, Dovecot і MariaDB конкуруватимуть за пам’ять, тому за реального навантаження виникатимуть використання swap і завершення процесів через OOM. Вважайте 6 GiB RAM плюс 1 GiB swap мінімальним обсягом для стабільного встановлення одним користувачем. Щойно системою почнуть користуватися більше ніж кілька людей, збільшіть обсяг до 8 GiB.