Как установить и настроить Listmonk на VPS
Mailchimp и его аналоги упираются в лимиты подписчиков и растущий ценник уже на паре тысяч контактов, а с российских карт их и вовсе не оплатить напрямую. Listmonk — open-source платформа для email-рассылок, которая работает на собственном сервере, не требует подписки и справляется с сотнями тысяч писем при разумном железе. Ниже — рабочая установка на VPS через Docker Compose: от чистого сервера до первой отправленной кампании.
Содержание
- Что такое Listmonk и когда он оправдан
- Требования к серверу
- Установка Docker и подготовка окружения
- Docker Compose для Listmonk и PostgreSQL
- Конфигурация config.toml и первый запуск
- Nginx, HTTPS и обратный прокси
- Настройка SMTP и репутации отправителя
- Первая кампания: импорт базы, шаблон, отправка
- Бэкапы, обновления и обслуживание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что такое Listmonk и когда он оправдан
Listmonk — написанный на Go self-hosted сервис email-маркетинга с открытым исходным кодом. Под капотом PostgreSQL как хранилище подписчиков и кампаний, встроенный веб-интерфейс для редактирования писем и полноценный REST API. Проект активно развивается, легко разворачивается в контейнерах и не требует PHP-зоопарка, характерного для более старых аналогов.
Имеет смысл ставить Listmonk, если у вас:
- база от 1000 подписчиков и облачные тарифы за MAU/контакты становятся ощутимой статьей расходов;
- нужен полный контроль над данными подписчиков (GDPR, внутренние политики, просто нежелание отдавать базу третьей стороне);
- есть свой SMTP или транзакционный провайдер (Amazon SES, Mailgun, Postmark, свой Postfix) и не хочется платить второй раз за отправку через встроенный сервис рассылок;
- достаточно квалификации поддерживать сервер самостоятельно — обновления, бэкапы, репутацию домена.
Если рассылки эпизодические и объём подписчиков небольшой, разница в деньгах может не окупить время на администрирование. Но при регулярных рассылках на несколько тысяч адресов self-hosted решение обычно окупается за 2-3 месяца по сравнению с платными тарифами.
Требования к серверу
Listmonk не прожорлив, но PostgreSQL и очередь отправки писем любят память при росте базы.
| Размер базы подписчиков | RAM | vCPU | Диск |
|---|---|---|---|
| до 10 000 | 2 ГБ | 1-2 | 20 ГБ SSD |
| 10 000 - 100 000 | 4 ГБ | 2 | 40 ГБ SSD |
| 100 000+ | 8 ГБ+ | 4 | 80 ГБ+ SSD |
Для старта достаточно VPS с 2 ГБ RAM и 2 vCPU — этого хватит на базу в несколько десятков тысяч контактов при аккуратной настройке PostgreSQL. Понадобится Ubuntu 24.04 или Debian 12, доменное имя для веб-интерфейса и — отдельно — домен или поддомен для отправки писем с настроенными SPF/DKIM/DMARC (об этом ниже).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверУстановка Docker и подготовка окружения
Если Docker на сервере ещё не стоит, разверните его с нуля — есть подробный разбор для Ubuntu 24.04. Кратко:
apt update && apt upgrade -y
curl -fsSL https://get.docker.com | sh
systemctl enable --now docker
docker --version
docker compose version
Создайте рабочую директорию и пользователя без root-прав для операций с файлами конфигурации:
mkdir -p /opt/listmonk
cd /opt/listmonk
Docker Compose для Listmonk и PostgreSQL
Официальный образ Listmonk публикуется на Docker Hub и GHCR. Разворачиваем связку из двух контейнеров: PostgreSQL 17 как база данных и сам Listmonk.
Создайте docker-compose.yml:
services:
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_USER: listmonk
POSTGRES_PASSWORD: ${DB_PASSWORD}
POSTGRES_DB: listmonk
volumes:
- ./data/postgres:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U listmonk"]
interval: 10s
timeout: 5s
retries: 6
app:
image: listmonk/listmonk:latest
restart: unless-stopped
ports:
- "127.0.0.1:9000:9000"
environment:
LISTMONK_APP_ADDRESS: 0.0.0.0:9000
depends_on:
db:
condition: service_healthy
volumes:
- ./config.toml:/listmonk/config.toml
- ./uploads:/listmonk/uploads
Порт 9000 сознательно привязан к 127.0.0.1 — наружу приложение отдаст nginx по HTTPS, напрямую по IP:9000 доступа быть не должно.
Файл .env рядом с compose-файлом:
DB_PASSWORD=сгенерируйте_длинный_случайный_пароль
Пароль удобно сгенерировать сразу: openssl rand -base64 24.
Конфигурация config.toml и первый запуск
Listmonk требует файл config.toml с параметрами подключения к базе. Создайте его в /opt/listmonk/config.toml:
[app]
address = "0.0.0.0:9000"
[db]
host = "db"
port = 5432
user = "listmonk"
password = "тот_же_пароль_что_и_в_env"
database = "listmonk"
ssl_mode = "disable"
max_open = 25
max_idle = 25
max_lifetime = "300s"
ssl_mode = "disable" здесь нормален — соединение между контейнерами app и db идёт внутри изолированной docker-сети, не наружу.
Инициализируйте схему базы данных перед первым запуском:
docker compose run --rm app ./listmonk --install --yes
Команда создаст таблицы и служебные записи. После этого поднимите сервисы:
docker compose up -d
docker compose ps
Проверьте логи, если что-то пошло не так:
docker compose logs -f app
При успешном старте Listmonk слушает на 127.0.0.1:9000 и ждёт входящие запросы через reverse proxy.
Nginx, HTTPS и обратный прокси
Веб-интерфейс и API должны отдаваться по HTTPS с валидным доменом — иначе браузер будет ругаться, а некоторые интеграции (webhooks, вебформы подписки) откажутся работать по HTTP. Настройте nginx как reverse proxy — общий подход разобран в статье про nginx как reverse proxy, здесь — конфиг под Listmonk конкретно.
Пример /etc/nginx/sites-available/listmonk:
server {
listen 80;
server_name lists.example.com;
location / {
proxy_pass http://127.0.0.1:9000;
proxy_set_header Host $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 25M;
}
}
client_max_body_size увеличен, потому что через интерфейс загружаются CSV-файлы с подписчиками и вложения.
Активируйте конфиг и получите сертификат через certbot:
ln -s /etc/nginx/sites-available/listmonk /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
certbot --nginx -d lists.example.com
Домен предварительно должен указывать A-записью на IP сервера — если домен и DNS настраиваются с нуля, весь процесс описан в статье про настройку домена и DNS.
После получения сертификата откройте https://lists.example.com — Listmonk встретит мастером создания администратора: email, пароль, имя. Это единственный раз, когда учётка создаётся через UI, дальше пользователей можно добавлять из админки.
Настройка SMTP и репутации отправителя
Это самая критичная часть — без неё письма будут падать в спам или блокироваться получающими серверами. У Listmonk нет встроенного MTA, он работает через внешний SMTP-сервер. Варианты:
- Транзакционный провайдер (Amazon SES, Mailgun, Postmark, SendGrid) — проще всего, провайдер уже прогрел IP-репутацию, но платите за объём писем.
- Свой Postfix/Mailcow на отдельном сервере — полный контроль, но репутацию IP и домена придётся выстраивать самостоятельно, и это не быстрый процесс.
Настройка SMTP — в разделе Settings → SMTP админки Listmonk:
Host: smtp.eu.mailgun.org (пример)
Port: 587
Auth protocol: LOGIN / PLAIN
Username: postmaster@mg.example.com
Password: ваш_ключ
TLS type: STARTTLS
Max conns: 10
Idle timeout: 15s
Max msg retries: 2
Для собственного почтового домена обязательны три записи в DNS:
- SPF —
TXTна домене:v=spf1 include:mailgun.org ~all(замените на своего провайдера/сервер); - DKIM — публичный ключ, который выдаёт провайдер или генерируется Postfix'ом, публикуется как
TXTнаselector._domainkey.example.com; - DMARC —
TXTна_dmarc.example.com:v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com.
Без этих трёх записей крупные почтовые провайдеры (Gmail, Mail.ru, Yandex) массово отправляют письма в спам или отклоняют их вовсе — это не блажь Listmonk, а общее требование к email-инфраструктуре в 2026 году. Если разворачиваете полноценный почтовый сервер с нуля, а не используете внешний SMTP, изучите отдельную статью про установку Mailcow на VPS — там разобраны DKIM и репутация домена подробнее, эти же принципы применимы и к Listmonk как отправителю.
Первая кампания: импорт базы, шаблон, отправка
Структура Listmonk строится вокруг трёх сущностей: подписчики (subscribers), списки (lists) и кампании (campaigns).
Создайте список в Lists → New, укажите тип — публичный (с формой подписки) или приватный (только импорт вручную). Импорт существующей базы — Subscribers → Import, формат CSV с колонками email,name,attributes:
email,name
ivan@example.com,Иван Петров
maria@example.com,Мария Сидорова
Важно: при импорте старой базы, собранной не через двойное согласие (double opt-in), риск жалоб на спам выше — это напрямую бьёт по репутации домена отправителя. Listmonk поддерживает опциональный double opt-in при подписке через форму — включите его для новых списков, если планируете растить базу органически.
Кампания создаётся в Campaigns → New campaign: тема письма, список получателей, редактор — либо визуальный (rich text), либо raw HTML с поддержкой шаблонизации Go templates ({{ .Subscriber.Name }} для персонализации). Перед массовой отправкой обязательно отправьте тестовое письмо себе через кнопку Send test — так ловится большинство ошибок вёрстки и битых переменных.
Скорость отправки регулируется в SMTP-настройках (Max conns, задержки между батчами) — не стоит слать резко тысячи писем за минуту с нового домена, это триггерит спам-фильтры. Для прогрева нового отправляющего домена разумно наращивать объём постепенно в течение 2-3 недель, начиная с сотен писем в день — точных цифр темпа прогрева никто не даст, ориентируйтесь на статистику доставляемости в Postmaster Tools Gmail и аналогах.
Бэкапы, обновления и обслуживание
База подписчиков — самый ценный актив в этой связке, бэкапить нужно регулярно и раздельно от остального сервера.
Дамп PostgreSQL из контейнера:
docker compose exec db pg_dump -U listmonk listmonk > /opt/backups/listmonk_$(date +%F).sql
Добавьте в cron ежедневный запуск и ротацию старых файлов:
0 3 * * * cd /opt/listmonk && docker compose exec -T db pg_dump -U listmonk listmonk | gzip > /opt/backups/listmonk_$(date +\%F).sql.gz
find /opt/backups -name "listmonk_*.sql.gz" -mtime +14 -delete
Обновление до новой версии — стандартный для Docker Compose путь:
docker compose pull
docker compose up -d
Перед крупным обновлением (смена мажорной версии) сверьтесь с changelog проекта на GitHub — иногда меняется схема базы, и апгрейд просит явного флага миграции.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Чем Listmonk отличается от Mailtrain или другого open-source аналога?
Listmonk написан на Go (не Node.js/PHP), потребляет меньше памяти на сравнимых объёмах и активнее развивается на момент 2026 года — но сравнение стоит делать под свою задачу, единого "лучшего" решения нет.
Можно ли использовать Listmonk без своего почтового сервера?
Да, и это самый практичный вариант для старта — подключите SMTP от Amazon SES, Mailgun или Postmark, а Listmonk останется только "мозгом" рассылок: базой подписчиков, редактором и планировщиком кампаний.
Что делать, если письма уходят в спам сразу после запуска?
Проверьте SPF/DKIM/DMARC записи через любой онлайн-чекер (mail-tester.com), убедитесь, что домен для отправки "прогрет" — новый домен без истории отправок почтовые провайдеры оценивают настороженно первые недели.
Нужен ли отдельный сервер под Listmonk, если уже есть VPS под сайт?
Для небольших объёмов можно разместить Listmonk на том же сервере в отдельных контейнерах — главное, чтобы хватало RAM и порты не конфликтовали с существующими сервисами.
Как перенести базу подписчиков из Mailchimp?
Экспортируйте контакты в CSV из Mailchimp (Audience → Export), приведите заголовки колонок к формату Listmonk (email, name) и импортируйте через Subscribers → Import — сегменты и теги Mailchimp придётся пересоздать вручную, автоматической миграции атрибутов нет.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →