Пошаговая инструкция · Самостоятельная установка
Как установить listmonk на сервер и отправить первую рассылку
Пошаговая инструкция для самостоятельной установки. Установим listmonk на Ubuntu 26.04 небольшими шагами: включим HTTPS, настроим SMTP и проверим рассылку, картинки, отписку и копирование данных.
Что понадобится и где выполнять команды #
Установим listmonk 6.2.0 — систему списков подписчиков и рассылок. PostgreSQL хранит адреса, шаблоны и кампании; само приложение передаёт письма внешнему SMTP-сервису. Заранее получите SMTP-доступ, настройте домен отправителя по требованиям провайдера и узнайте лимиты отправки. Для первого теста понадобятся два ваших почтовых адреса.
Подготовьте отдельный сервер Ubuntu 26.04 LTS по общей инструкции: доступ по SSH, Docker Engine, Docker Compose и Nginx. Docker запускает приложение в контейнерах — отдельных окружениях с нужными зависимостями. Compose читает файл, в котором описаны все контейнеры и их связи. Nginx будет принимать HTTPS-запросы из браузера и передавать их приложению.
Все команды выполняйте в SSH-терминале сервера. Домен mailings.example.com в примерах заменяйте своим. В DNS-панели создайте A-запись с публичным IPv4 сервера; проверьте её командой getent ahostsv4 mailings.example.com. Без правильного адреса сертификат не будет выпущен. Нужны входящие порты 80/443 и SSH; базы данных снаружи не открывайте. Выбор сервера для listmonk поможет рассчитать ресурсы.
Перед работой выполните docker compose version: команда должна показать Compose v2. Если доступ к Docker запрещён, завершите настройку доступа из общей инструкции и заново войдите по SSH. В nano файл сохраняется клавишами Ctrl+O и Enter, редактор закрывается Ctrl+X. Примеры конфигурации записывают в файл, а не запускают как команды.
Настройка внешнего доступа использует обратный прокси Nginx и Certbot для Nginx. Приложение остаётся доступным на локальном порту; снаружи открыт его HTTPS-домен.
Шаг 1. Создайте папку установки #
Каталог uploads будет хранить картинки, которые используются в письмах. Остальные файлы установки положим рядом, но резервные копии сюда складывать не будем.
mkdir -p "$HOME/apps/listmonk/uploads"
cd "$HOME/apps/listmonk"Дальнейшие команды выполняйте из этой папки. В новом SSH-сеансе сначала выполните cd "$HOME/apps/listmonk".
Шаг 2. Сохраните пароли в .env #
Создадим разные случайные пароли базы и первого администратора owner. Блок целиком записывает файл .env. Не повторяйте его поверх работающей установки: это изменит сохранённые секреты, но не пароль уже созданной базы.
.envumask 077
cat > .env <<EOF
POSTGRES_PASSWORD=$(openssl rand -hex 32)
LISTMONK_ADMIN_USER=owner
LISTMONK_ADMIN_PASSWORD=$(openssl rand -hex 32)
EOF
chmod 600 .envОткройте nano .env, сохраните пароль LISTMONK_ADMIN_PASSWORD в менеджере паролей и закройте Ctrl+X. Значения не нужно отправлять кому-либо вместе с журналами.
Шаг 3. Создайте Compose-файл #
Откройте nano compose.yaml и вставьте весь YAML ниже, сохранив пробелы и отступы. Сохраните Ctrl+O, Enter, Ctrl+X. Файл использует listmonk 6.2.0 и PostgreSQL 17. Внутри app официальный порядок сначала создаёт пустую базу, затем применяет миграции и запускает сервер. Это действия самого контейнера, отдельно вводить их в терминал не нужно.
services:
db:
image: postgres:17-alpine
restart: unless-stopped
environment:
POSTGRES_DB: listmonk
POSTGRES_USER: listmonk
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set password}
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: [CMD-SHELL, "pg_isready -U listmonk -d listmonk"]
interval: 10s
timeout: 5s
retries: 10
app:
image: listmonk/listmonk:v6.2.0
restart: unless-stopped
ports:
- "127.0.0.1:9001:9000"
depends_on:
db:
condition: service_healthy
command: [sh, -c, "./listmonk --install --idempotent --yes --config '' && ./listmonk --upgrade --yes --config '' && ./listmonk --config ''"]
environment:
LISTMONK_app__address: 0.0.0.0:9000
LISTMONK_db__host: db
LISTMONK_db__port: 5432
LISTMONK_db__user: listmonk
LISTMONK_db__password: ${POSTGRES_PASSWORD:?set password}
LISTMONK_db__database: listmonk
LISTMONK_db__ssl_mode: disable
LISTMONK_ADMIN_USER: ${LISTMONK_ADMIN_USER:-}
LISTMONK_ADMIN_PASSWORD: ${LISTMONK_ADMIN_PASSWORD:-}
TZ: Etc/UTC
volumes:
- ./uploads:/listmonk/uploads
volumes:
pgdata:Порт приложения опубликован только на 127.0.0.1:9001, а порт базы наружу не опубликован. Каталог uploads подключён к /listmonk/uploads.
Шаг 4. Проверьте конфигурацию #
Compose проверит YAML и прочитает секреты из .env. --quiet не выводит итоговую конфигурацию с паролями.
docker compose config --quietПри успехе вывода нет. При ошибке исправьте имя переменной или отступы до запуска.
Шаг 5. Скачайте образы #
Скачаем выбранные версии приложения и базы. На этом шаге сервисы ещё не запускаются.
docker compose pullЗагрузка должна завершиться без denied или not found. При сбое подключения повторите только загрузку после устранения причины.
Шаг 6. Запустите базу и listmonk #
Compose дождётся готовности PostgreSQL и запустит приложение. Оно само создаст таблицы и первого администратора с данными из .env.
docker compose up -dДайте первому запуску немного времени. Не создавайте второй Compose-проект, если интерфейс пока не открылся; сначала проверьте журнал.
Шаг 7. Проверьте локальную работу #
Сначала посмотрим сервисы, затем HTTP-ответ listmonk на самом сервере. Это проверка приложения до подключения HTTPS.
docker compose ps
curl -I http://127.0.0.1:9001База должна быть healthy, app — работать. 200 или перенаправление допустимы. При Connection refused или 500 смотрите docker compose logs --tail=100 app db.
Шаг 8. Сохраните сайт Nginx #
Установите Nginx и Certbot по подготовке Ubuntu, если ещё не установили. Откройте sudo nano /etc/nginx/sites-available/listmonk и вставьте файл ниже. Замените все домены своими. Nginx передаёт приложению домен, адрес клиента и протокол; Upgrade и Connection сохраняют WebSocket. До получения сертификата условие $scheme блокирует обычные HTTP-запросы кодом 403, чтобы вход не происходил без шифрования.
/etc/nginx/sites-available/listmonkmap $http_upgrade $listmonk_connection_upgrade {
default upgrade;
"" close;
}
server {
listen 80;
server_name mailings.example.com;
client_max_body_size 100m;
location / {
if ($scheme = http) { return 403; }
proxy_pass http://127.0.0.1:9001;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $listmonk_connection_upgrade;
proxy_read_timeout 3600s;
proxy_send_timeout 3600s;
proxy_buffering off;
}
}
Сохраните Ctrl+O, Enter, Ctrl+X. В файле пока нет путей к сертификатам: Nginx сможет проверить его до выпуска HTTPS.
Шаг 9. Подключите сайт и проверьте HTTP #
Ссылка подключает сохранённый сайт. nginx -t проверяет все настройки сервера; && разрешает перечитать их только при успешной проверке. curl проверяет ответ для вашего домена. При ошибке остановитесь, исправьте указанную строку и повторите проверку.
sudo ln -sfn /etc/nginx/sites-available/listmonk /etc/nginx/sites-enabled/listmonk
sudo nginx -t && sudo systemctl reload nginx
curl -I http://mailings.example.com/Ожидается successful от nginx -t и HTTP 403 для обычного запроса: до HTTPS это намеренная блокировка. DNS должен указывать на сервер, TCP 80/443 — быть доступен у провайдера. Ничего не вводите в форму входа по HTTP.
Шаг 10. Получите сертификат и включите HTTPS #
Каждое имя из команды должно указывать на этот сервер. Certbot проверит домены, сам добавит сертификат в сайт Nginx и включит перенаправление HTTP → HTTPS. Укажите свою почту при запросе и подтвердите условия Let’s Encrypt. Это отдельное действие после успешной проверки HTTP.
sudo /snap/bin/certbot --nginx -d mailings.example.com --redirectCertbot сообщил об успешной установке. Откройте HTTPS-адрес со своего компьютера: браузер не должен предупреждать о сертификате. Для закрытой панели используйте разрешённый IP. При ошибке исправьте DNS, в том числе AAAA, либо доступ к TCP 80; не повторяйте запросы выпуска подряд.
Шаг 11. Проверьте продление сертификата #
Certbot из snap создаёт службу автоматического продления. Dry-run выполняет пробное продление: настоящие сертификаты не заменяются. Затем проверьте, что таймер планирует следующий запуск. Сохраняйте доступ к TCP 80 для следующих проверок домена.
sudo /snap/bin/certbot renew --dry-run
systemctl list-timers --all 'snap.certbot.renew*'Пробное продление успешно, у таймера есть следующий запуск. Если тест не прошёл, проверьте /var/log/letsencrypt/letsencrypt.log; сначала исправьте причину. После этого можно создавать учётную запись и приглашать пользователей.
Шаг 12. Войдите первым администратором #
Используйте owner и сохранённый пароль LISTMONK_ADMIN_PASSWORD. После первого успешного входа откройте в терминале nano .env и удалите только две строки LISTMONK_ADMIN_USER и LISTMONK_ADMIN_PASSWORD. Пользователь уже записан в базе; его стартовый пароль больше не требуется в окружении.
docker compose up -d --force-recreate appСнова войдите как owner: учётная запись должна сохраниться. POSTGRES_PASSWORD не удаляйте, он продолжает использоваться для базы.
Шаг 13. Задайте публичный адрес рассылки #
В настройках приложения установите Root URL равным https://mailings.example.com с вашим доменом. Укажите имя сервиса, email отправителя и адрес для ответов. Root URL используется в ссылках просмотра письма, подтверждения и отписки.
Адрес должен открываться из обычного браузера вне сервера. Если стоит localhost или IP, исправьте до отправки писем подписчикам.
Шаг 14. Настройте хранение картинок #
В Settings → Media выберите файловое хранилище и путь /listmonk/uploads. Загрузите небольшую тестовую картинку через интерфейс, затем откройте её выданную ссылку в приватном окне браузера.
Картинка должна открываться без входа администратора: её должны видеть получатели письма. При ошибке проверьте путь и права uploads, не открывая дополнительный порт.
Шаг 15. Настройте SMTP и проверьте письмо #
В настройках SMTP укажите host, порт, логин, пароль и режим шифрования своего сервиса. Порт 465 с TLS и порт 587 с STARTTLS — разные способы подключения; используйте именно тот, что указал провайдер. Начните с небольшой скорости в пределах его лимита. Отправьте тестовое письмо себе.
Письмо должно прийти с правильным отправителем и адресом ответа. Проверьте папку «Спам». Если listmonk получил SMTP-ошибку, исправьте её до запуска кампании.
Шаг 16. Выдайте доступ коллегам #
Создайте отдельные пользовательские учётные записи с правами под их задачи. Коллегам для редактирования кампаний не всегда требуется Super Admin. Публичная подписка на рассылку создаёт подписчика и не выдаёт административный доступ.
Проверьте вход под одним сотрудником и доступ к нужным разделам. Доступ к настройкам и базе подписчиков должен соответствовать его роли.
Шаг 17. Создайте маленький тестовый список #
Добавьте список «Проверка сервера» и только два контролируемых адреса. Для форм на сайте включите подтверждение подписки, если используете его в рабочем сценарии. Не импортируйте всю клиентскую базу ради проверки установки.
Оба адреса должны находиться в выбранном списке с подходящим статусом подписки. Наличие адреса в общей базе не всегда означает подписку на конкретный список.
Шаг 18. Соберите первое тестовое письмо #
Создайте шаблон с текстом, тестовой картинкой и штатной ссылкой отписки. Создайте кампанию только на тестовый список. Отправьте предпросмотр себе и откройте его на компьютере и телефоне.
Проверьте тему, текст, картинку, ссылку просмотра и отписку. Ссылки должны вести на ваш HTTPS-домен, а не localhost.
Шаг 19. Запустите тестовую кампанию #
Отправьте кампанию на два тестовых адреса. Посмотрите изменение счётчика отправок, затем проверьте фактическую доставку в оба ящика. SMTP-ответ «принято» ещё не означает доставку во входящие.
Письма должны прийти на оба адреса. При задержке проверьте журнал app, лимиты провайдера и ошибки конкретных получателей; не запускайте ту же кампанию повторно наугад.
Шаг 20. Проверьте отписку #
На одном тестовом адресе нажмите «Отписаться». Затем создайте новую небольшую кампанию на тот же список. Если используете форму подтверждения подписки, отдельно пройдите её из приватного окна.
Отписанный адрес не должен получать следующую кампанию. Оставшийся подписчик должен получить её. Если это не так, проверьте список и статусы до рабочего импорта.
Шаг 21. Сохраните базу рассылки #
Приостановите кампании и запланируйте короткий перерыв. Создадим закрытую папку, остановим app и выгрузим SQL. Следующий шаг выполняйте в том же SSH-сеансе. При ошибке верните приложение через docker compose start app.
umask 077
LISTMONK_BACKUP="$HOME/backups/listmonk/$(date -u +%Y%m%dT%H%M%SZ)"
mkdir -p "$LISTMONK_BACKUP"
docker compose stop app
docker compose exec -T db pg_dump -U listmonk listmonk > "$LISTMONK_BACKUP/database.sql"pg_dump должен завершиться без ошибки. База содержит адреса, настройки SMTP и статусы кампаний: храните копию с ограниченным доступом.
Шаг 22. Сохраните картинки и возобновите работу #
Добавим uploads и файлы настройки, затем вернём приложение. Перенесите весь набор через SFTP в закрытое хранилище за пределами сервера.
tar -czf "$LISTMONK_BACKUP/files.tar.gz" uploads .env compose.yaml
docker compose start app
ls -lh "$LISTMONK_BACKUP"SQL и архив должны быть ненулевыми. После старта проверьте вход и картинку. Регулярные копии должны контролировать ошибки, а не просто создавать файл по расписанию.
Если возникла ошибка или пора обновляться #
Команды Compose работают из каталога $HOME/apps/listmonk. Посмотрите состояние через docker compose ps --all и последние сообщения через docker compose logs --tail=100 app db. Не запускайте всю установку заново при первой ошибке: сначала найдите конкретный сервис и сообщение. 502 в браузере обычно означает, что Nginx не может получить ответ приложения; сначала проверьте локальный адрес из инструкции.
Проверьте восстановление на отдельном сервере с listmonk 6.2.0 и PostgreSQL 17: верните SQL и uploads, а отправку через рабочий SMTP отключите до проверки. После возврата базы пересмотрите активные кампании, чтобы случайно не отправить их повторно. Письма в спаме требуют проверки домена отправителя и его SPF/DKIM/DMARC по указаниям почтового провайдера.
Перед обновлением сохраните свежую полную копию, выберите конкретный релиз и прочитайте его примечания. Проверяйте обновление на отдельной машине с восстановленной копией. Если меняется схема базы, возврат одного старого образа не заменяет возврат совместимого дампа. Менять основную версию базы отдельным тегом без процедуры переноса данных нельзя.
Настройки внешнего доступа храните вместе с копией приложения: /etc/nginx/sites-available/listmonk и /etc/letsencrypt содержат сайт и сертификаты с закрытыми ключами. Архивируйте их с sudo в закрытое хранилище. После восстановления подключите сайт через sites-enabled, выполните sudo nginx -t, затем перечитайте Nginx. Для ошибки 502 сначала проверьте локальное приложение и /var/log/nginx/error.log; для сертификата — /var/log/letsencrypt/letsencrypt.log и таймер продления.