Разворачиваем Zammad 7.1 на своём VPS: Docker, Elasticsearch и грабли, которые мы собрали за десяток внедрений

Развёртывание Zammad 7.1 на VPS: docker-контейнеры приложения, PostgreSQL, Redis и Elasticsearch под интерфейсом тикет-системы

Сайзинг: почему 4 ГБ — минимум, а 8 ГБ — комфорт

Меня зовут Евгений Семёнов, я технический директор ITfresh. Мы занимаемся IT-аутсорсингом для компаний до 50 рабочих мест в Москве, держим собственные серверы в дата-центре МТС и за последние годы развернули Zammad не одному десятку клиентов — юрфирмам, медклиникам, сервисным и торговым компаниям. Это вторая статья серии: в обзорной части я разбирал, что умеет Zammad, кому он подходит и чем отличается от Zendesk и платных аналогов. Здесь — чистая практика: как мы разворачиваем ветку 7.1 на VPS через docker compose, с реальными командами, конфигами и граблями, на которые наступали сами.

Начну с вопроса, который задаёт каждый клиент до старта: «какой сервер брать?». У Zammad аппетиты честно описаны в системных требованиях, и они совпадают с тем, что я вижу на практике: 4 ГБ оперативной памяти — это минимум, ниже которого система в проде жить не будет. Официальная рекомендация для команд до 40 агентов — 4 CPU и 6 ГБ RAM, плюс ещё 6 ГБ, если Elasticsearch крутится на том же хосте. То есть полноценная инсталляция «всё в одном» с поиском — это машина класса 4 vCPU / 8–12 ГБ.

Откуда берутся такие цифры. Zammad написан на Ruby on Rails, и в docker-стеке приложение живёт несколькими процессами: railsserver обслуживает веб-интерфейс и API, scheduler гоняет фоновые задачи (почта, триггеры, эскалации SLA), websocket держит живые обновления в интерфейсе агентов. Каждый Rails-процесс — это сотни мегабайт резидентной памяти, и со временем они подрастают. Рядом PostgreSQL с базой тикетов, лёгкий Redis и главный едок — Elasticsearch: JVM с heap-областью, которая по умолчанию норовит откусить половину доступной памяти хоста.

Наша типовая конфигурация

Для типовой фирмы на 30 рабочих мест и 5 агентов поддержки мы заказываем VPS 4 vCPU / 8 ГБ RAM / 60 ГБ SSD. На такой машине помещается весь стек вместе с Elasticsearch, остаётся запас под пики индексации и обновления, а стоит она у российских провайдеров вменяемых денег. Ниже — таблица, от которой я отталкиваюсь при заказе.

СценарийvCPURAMSSDКомментарий
Тест / демо без ES24 ГБ30 ГБАбсолютный минимум, поиск деградирует до БД
2–5 агентов, ES включён48 ГБ60 ГБНаш стандарт для фирм до 50 РМ
До 40 агентов, ES на том же хосте412 ГБ80–100 ГБПо официальной рекомендации: 6 ГБ системе + 6 ГБ под ES

На 2 ГБ система формально запустится — контейнеры поднимутся, мастер настройки пройдёт. Но первым ляжет поиск: Elasticsearch либо не стартует вовсе, либо будет убит OOM-киллером в первый же час работы, прихватив за компанию что-нибудь ещё. Мы такие «экономные» инсталляции потом переезжали на нормальное железо в аварийном режиме — выходит дороже, чем сразу взять 8 ГБ.

Диск считайте от вложений. Сама система с образами и базой занимает немного, но тикеты копят вложения: сканы актов, скриншоты ошибок, фотографии «вот так выглядит наш принтер». Служба поддержки на 5 агентов за год спокойно набирает 10–20 ГБ вложений, и Elasticsearch с плагином ingest-attachment ещё и индексирует их содержимое. Плюс локальные бэкапы за несколько дней. 60 ГБ SSD — комфортный старт, расширить диск потом можно, но лучше не впритык.

Пакетная установка vs docker compose: что выбираем и почему

У Zammad два официальных способа установки: DEB/RPM-пакеты из репозитория проекта и docker compose из репозитория zammad-docker-compose. Оба поддерживаются разработчиками, оба доводят до одинакового результата — вопрос в том, как вам потом с этим жить.

Пакетная установка: «один сервер навсегда»

Пакет ставит Zammad как системный сервис: юниты systemd, конфиги в привычных местах, логи в journalctl. PostgreSQL, Redis, Elasticsearch и nginx вы поднимаете рядом сами — из пакетов дистрибутива или сторонних репозиториев. Такой вариант прозрачен для классического линукс-админа: всё видно, всё руками, никакой контейнерной магии.

Обратная сторона — сцепленность с операционной системой. Мажорное обновление дистрибутива, конфликт версий Ruby-зависимостей, Elasticsearch из стороннего репозитория, который обновился несинхронно, — и вы разбираетесь с окружением вместо работы. Перенос на другой сервер превращается в аккуратное воспроизведение всей связки с нуля.

Docker compose: управляемые обновления и переносимость

Официальный zammad-docker-compose описывает весь стек одним файлом: приложение, PostgreSQL, Redis, Elasticsearch, внутренний nginx и сервис бэкапа. Версии всех компонентов зафиксированы и протестированы разработчиками Zammad в связке — вам не нужно самому угадывать, какой Elasticsearch совместим с текущим релизом.

Обновление — это git pull, docker compose pull и перезапуск: миграции базы контейнер инициализации прогонит сам. Откат при проблеме — возврат тега образа. Бэкап — тома с данными плюс дамп базы. Перенос на другой VPS — копирование томов и каталога с конфигами. Именно за эту предсказуемость мы ставим клиентам docker-вариант: за десяток внедрений ни одно обновление не превратилось в спецоперацию.

Когда пакет всё же лучше. Два честных случая. Первый — слабый VPS на 4 ГБ без Elasticsearch, где каждые полгигабайта на счету: пакетная установка без контейнерной прослойки чуть экономнее. Второй — у клиента уже есть админ, который Docker не знает и знать не хочет, а systemd и журналы читает свободно. Навязывать инструмент, который некому сопровождать, — плохая услуга. Во всех остальных случаях наш выбор — docker compose, и дальше статья идёт по этому пути.

Подготовка VPS: базовая гигиена до установки

Основа у нас всегда одна — Ubuntu 24.04 LTS: пять лет поддержки, свежие ядро и Docker, минимум сюрпризов. Прежде чем клонировать репозиторий Zammad, я привожу свежий VPS в порядок — это полчаса, которые потом экономят часы.

DNS — заранее, а не потом

Первым делом создайте A-запись вида helpdesk.company.ru, указывающую на IP вашего VPS. Именно заранее: Let's Encrypt проверяет владение доменом по HTTP-запросу к этому имени, и пока запись не разъехалась по DNS, сертификат вы не получите. Пока настраиваете сервер, запись как раз доедет до резолверов.

Пользователь, firewall, fail2ban, время

# обновляем систему, заводим рабочего пользователя
apt update && apt -y upgrade
adduser deploy
usermod -aG sudo deploy

# firewall: наружу только SSH, HTTP и HTTPS
ufw allow OpenSSH
ufw allow 80/tcp
ufw allow 443/tcp
ufw --force enable

# защита SSH от перебора и автообновления безопасности
apt -y install fail2ban unattended-upgrades
systemctl enable --now fail2ban

# время: тикеты и SLA живут по часам
timedatectl set-timezone Europe/Moscow
timedatectl set-ntp true

По пунктам. SSH я дополнительно ограничиваю по IP офиса и нашего сервера мониторинга (ufw allow from x.x.x.x to any port 22 вместо общего правила) — на VPS с открытым 22-м портом брутфорс начинается в первые же минуты. Порты самого Zammad наружу не открываем вообще: docker-стек будет слушать только localhost, а с миром общается nginx на 80/443.

Отдельно про NTP — пункт, который выглядит формальностью, но таковой не является. Zammad считает SLA, эскалации и рабочие календари по времени сервера. Уехавшие на несколько минут часы — это неправильно посчитанные сроки реакции и триггеры, сработавшие не тогда. Убедитесь, что timedatectl показывает System clock synchronized: yes, и живите спокойно.

Docker Engine из официального репозитория

apt -y install ca-certificates curl
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc
echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu $(. /etc/os-release && echo $VERSION_CODENAME) stable" \
  > /etc/apt/sources.list.d/docker.list
apt update
apt -y install docker-ce docker-ce-cli containerd.io docker-compose-plugin
usermod -aG docker deploy

Ставим именно из репозитория Docker, а не docker.io из Ubuntu: нужен свежий compose-плагин v2 (команда docker compose без дефиса). После добавления пользователя в группу docker перелогиньтесь и проверьте: docker compose version должен ответить без sudo.

Установка через docker compose пошагово

Теперь основное блюдо. Весь боевой стек Zammad разворачивается из официального репозитория zammad/zammad-docker-compose — клонируем, правим переменные, поднимаем.

Шаг 1. Клонируем репозиторий и правим .env

cd /opt
git clone https://github.com/zammad/zammad-docker-compose.git
cd zammad-docker-compose

В корне репозитория лежит файл .env — единственное место, которое нужно трогать перед первым запуском. Внутри зафиксированы версии всех образов (их не выдумываем и не «улучшаем» — разработчики протестировали именно эту связку) и несколько параметров, которые стоит осознанно проверить:

  • POSTGRES_PASS — пароль пользователя базы. По умолчанию там стоит заглушка — обязательно меняем на длинную случайную строку до первого запуска: после инициализации базы менять его сложнее.
  • NGINX_EXPOSE_PORT — порт, на котором внутренний nginx стека отдаёт Zammad наружу (по умолчанию 8080). Мы оставляем 8080, а в связке с системным reverse proxy привязываем его только к localhost.
  • ELASTICSEARCH_ENABLED — включён ли поисковый движок. Оставляем true; вариант false для маленьких команд разберём в разделе про Elasticsearch.

Шаг 2. vm.max_map_count — до первого запуска, а не после

Elasticsearch требует от ядра хоста увеличенного лимита memory-mapped областей. Значение задаётся на хосте (не в контейнере!) и обязано пережить перезагрузку:

# применяем сразу
sysctl -w vm.max_map_count=262144

# и закрепляем навсегда
echo "vm.max_map_count=262144" > /etc/sysctl.d/99-zammad-elasticsearch.conf
sysctl --system

Если этот шаг пропустить, контейнер Elasticsearch будет падать при старте и уходить в цикл перезапуска, а Zammad — бесконечно ждать готовности поиска. Это грабля номер один по частоте: подробнее — в разделе про типовые ошибки.

Шаг 3. Поднимаем стек

docker compose up -d
docker compose ps

Первый запуск скачает образы и займёт несколько минут. Что должно подняться и зачем каждый контейнер:

  • zammad-init — одноразовый контейнер инициализации: готовит базу, прогоняет миграции и завершается. Его статус Exited (0) — это норма, а не проблема.
  • zammad-railsserver — само приложение: веб-интерфейс и REST API.
  • zammad-scheduler — фоновые задачи: опрос почтовых ящиков, триггеры, эскалации SLA, отложенные задания.
  • zammad-websocket — живые обновления интерфейса агентов: новые тикеты и ответы появляются без перезагрузки страницы.
  • zammad-nginx — внутренний веб-сервер стека, склеивает railsserver и websocket в один HTTP-эндпоинт на порту 8080.
  • zammad-postgresql — база данных: тикеты, пользователи, настройки.
  • zammad-redis — кэш и обмен сообщениями между процессами.
  • zammad-elasticsearch — полнотекстовый поиск по тикетам и вложениям.
  • zammad-backup — регулярные дампы базы и файлов по расписанию.
Вывод docker compose ps: контейнеры Zammad со статусами running и завершившийся init-контейнер
Вывод docker compose ps: боевые контейнеры в состоянии running, init-контейнер завершился с Exited (0)

Данные живут в именованных томах Docker (посмотреть: docker volume ls) — том PostgreSQL, том с файлами Zammad, том Elasticsearch и каталог бэкапов. Именно тома вы бэкапите и переносите; контейнеры — расходный материал, их можно пересоздавать без потери данных.

Шаг 4. Первая проверка

# все сервисы, кроме init, должны быть в состоянии running/healthy
docker compose ps

# логи инициализации: миграции должны завершиться без ошибок
docker compose logs zammad-init

# приложение отвечает на localhost?
curl -sI http://127.0.0.1:8080 | head -1

Если curl вернул HTTP-ответ — стек жив. В браузер пока не торопимся: наружу Zammad мы откроем правильно, через reverse proxy с HTTPS.

Reverse proxy nginx + Let's Encrypt

Выставлять порт 8080 в интернет нельзя: без TLS пароли агентов и содержимое тикетов ходят открытым текстом. Перед стеком ставим системный nginx, который терминирует HTTPS и проксирует запросы внутрь.

Архитектура развёртывания Zammad: браузер через HTTPS попадает на nginx, дальше Rails-приложение и websocket, за ними PostgreSQL, Redis и Elasticsearch
Схема стека: браузер по HTTPS → системный nginx → внутренний nginx стека → Rails и websocket, за ними PostgreSQL, Redis и Elasticsearch
apt -y install nginx

Конфиг /etc/nginx/sites-available/zammad.conf:

server {
    listen 80;
    server_name helpdesk.company.ru;

    location / {
        proxy_pass http://127.0.0.1:8080;
        proxy_http_version 1.1;

        # websocket: без этих трёх строк интерфейс агентов "зависает"
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_read_timeout 86400;

        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 50m;
    }
}
ln -s /etc/nginx/sites-available/zammad.conf /etc/nginx/sites-enabled/
nginx -t && systemctl reload nginx
Websocket — самая частая жалоба после установки. Заголовки Upgrade и Connection "upgrade" плюс длинный proxy_read_timeout обязательны: через websocket-соединение агенты получают живые обновления. Забудете — интерфейс внешне работает, но новые тикеты и ответы коллег не появляются, пока пользователь не обновит страницу вручную. Симптом коварный: «у нас всё тормозит и глючит», хотя на самом деле просто рвётся websocket. Проверяется во вкладке Network браузера — соединение должно висеть в статусе 101 Switching Protocols.

HTTPS через certbot с плагином nginx

apt -y install certbot python3-certbot-nginx
certbot --nginx -d helpdesk.company.ru

# проверяем, что автопродление отработает через 60 дней
certbot renew --dry-run

Обратите внимание: именно --nginx, а не certonly --standalone. Standalone-режим поднимает собственный временный веб-сервер на 80-м порту — а он уже занят вашим nginx. Мы на эту граблю наступили на сервере с хостинг-панелью: сертификат выпустили, остановив nginx руками, а через два месяца автопродление молча упало, потому что порт снова был занят. Плагин --nginx проходит проверку через работающий веб-сервер, сам дописывает ssl-блок в конфиг и корректно продлевается. Команда certbot renew --dry-run — обязательный финальный аккорд: она репетирует продление и ловит проблему сейчас, а не через 60 дней в пятницу вечером.

Мастер первичной настройки

Открываем https://helpdesk.company.ru — Zammad встречает мастером первичной настройки. Пройти его — пять минут, но несколько решений здесь стоит принять осознанно.

Администратор и организация

Первый экран — создание учётной записи администратора: имя, email, пароль. Этот аккаунт получает полные права, поэтому email указывайте реальный рабочий (на него пойдут системные уведомления), а пароль — из менеджера паролей, не «временный, потом поменяю». Дальше — название организации, логотип и системный URL: проверьте, что там указан ваш домен с https, — от этого поля зависят все ссылки в исходящих письмах.

Почтовый канал: support@ на входе и выходе

Мастер предложит настроить email-канал — это главный источник тикетов в любом нашем внедрении. Понадобится выделенный ящик вида support@company.ru: Zammad забирает из него письма по IMAP (каждое письмо становится тикетом или ответом в существующем тикете) и отправляет ответы через SMTP. Вводим сервер, логин, пароль — мастер сам проверит соединение в обе стороны.

Сразу после мастера сделайте контрольный круг: отправьте письмо на support@ с личной почты, убедитесь, что тикет создался, ответьте на него из Zammad и проверьте, что ответ дошёл и не упал в спам. Если упал — вам в раздел про SPF и DKIM ниже, это чинится на стороне DNS, а не Zammad.

Ящик должен быть выделенным. Не подключайте к Zammad общий ящик, которым параллельно пользуются люди: система забирает письма и превращает их в тикеты, почтовый клиент бухгалтера видит «пропавшую» почту, начинается паника. Отдельный ящик — только для service desk.

Часовой пояс, календарь, русский язык

Три настройки, которые нужно сделать до того, как показывать систему заказчику. Первая — часовой пояс системы (Настройки → Система) — Europe/Moscow или ваш регион. Вторая — бизнес-календарь (Настройки → Объекты → Календари): рабочие часы 9:00–18:00, выходные, праздники — по нему Zammad будет считать SLA; если календарь не настроить, сроки реакции будут тикать и ночью. Третья — язык по умолчанию для новых пользователей: русский перевод у Zammad из коробки, ставим его системным, а каждый пользователь при желании выберет свой язык в профиле.

И последний штрих перед демонстрацией: заведите пару тестовых агентов и группу («Техподдержка»), прогоните тикет по полному циклу — создание из письма, назначение, ответ, закрытие. Показывать заказчику живую систему с примером тикета всегда убедительнее, чем пустой интерфейс.

Elasticsearch и полнотекстовый поиск

Elasticsearch — самый тяжёлый и самый капризный компонент стека, поэтому у него отдельный раздел. Зачем он вообще: без него Zammad ищет средствами базы данных, с ним — полнотекстово по всему: темам и телам тикетов, комментариям, карточкам клиентов и организаций и, главное, по содержимому вложений — плагин ingest-attachment вытаскивает текст из PDF и офисных документов. «Найди тикет, где клиент присылал акт сверки за март» — это запрос, который без ES не работает, а с ES решается за секунду.

Первичная индексация

После установки и после каждого восстановления из бэкапа поисковый индекс нужно построить заново:

docker compose exec zammad-railsserver bundle exec rake zammad:searchindex:rebuild

На свежей системе это минуты. На системе с историей (например, после миграции из OTRS или Zendesk) — до нескольких часов: индексируется каждый тикет с вложениями. Прогресс видно в выводе команды; систему в это время использовать можно, просто поиск будет неполным, пока индексация не добежит.

Ограничиваем heap, чтобы ES не съел весь VPS

JVM Elasticsearch по умолчанию берёт heap пропорционально памяти хоста — на VPS с 8 ГБ он с удовольствием заберёт половину. Для нашей типовой инсталляции на 5 агентов хватает 1–2 ГБ heap. Ограничение задаём через docker-compose.override.yml рядом с основным файлом:

services:
  zammad-elasticsearch:
    environment:
      - ES_JAVA_OPTS=-Xms1g -Xmx1g

После docker compose up -d контейнер пересоздастся с лимитом. Правило простое: heap ES + Rails-процессы + PostgreSQL + запас системе должны помещаться в RAM без пересечения, иначе рано или поздно придёт OOM-киллер и убьёт самого жирного — обычно как раз Elasticsearch, а иногда и PostgreSQL.

Симптомы «поиск отвалился» и порядок реанимации

Как это выглядит: поиск возвращает пустоту или старые результаты, новые тикеты не находятся, в мониторинге Zammad жалобы на search index. Порядок действий:

  1. docker compose ps — жив ли контейнер ES. Если рестартится циклически — смотрим docker compose logs zammad-elasticsearch: чаще всего там либо max_map_count, либо нехватка памяти.
  2. sysctl vm.max_map_count — должно быть 262144. После переустановки или смены VPS этот параметр теряют регулярно.
  3. Свободное место на диске: при заполнении диска выше ватермарок ES переводит индексы в read-only и перестаёт принимать новые документы. Чистим место, снимаем блокировку, индексируем заново.
  4. Если контейнер здоров, а поиск всё равно кривой — пересобираем индекс командой rebuild выше. Это безопасно и решает большинство «странностей» поиска.

Вариант без ES: ELASTICSEARCH_ENABLED=false

Для совсем маленьких команд — два-три агента, VPS на 4 ГБ — официальный стек позволяет выключить Elasticsearch: в .env ставите ELASTICSEARCH_ENABLED=false, и контейнер поиска не поднимается вовсе. Выигрыш — минус самый прожорливый компонент, стек уверенно живёт в 4 ГБ.

Чем платите: поиск деградирует до запросов в PostgreSQL. Он продолжает работать, но ищет медленнее и грубее, ранжирование примитивнее, а содержимое вложений не индексируется совсем — «найди тикет с тем PDF» превращается в ручное листание. Для пары агентов с сотней тикетов в месяц это приемлемый компромисс; для команды, где поиск по истории — рабочий инструмент, — нет. Хорошая новость: решение обратимо, ES можно включить позже, добавив памяти и прогнав rebuild.

Типовые грабли наших внедрений

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

Грабля 1. Забытый vm.max_map_count

Классика жанра: стек подняли, всё работало, через месяц VPS перезагрузился — и Zammad не стартует. Причина: sysctl -w применили руками, а файл в /etc/sysctl.d/ не создали. После ребута лимит вернулся к дефолту, Elasticsearch падает на старте, init-контейнер ждёт поиск, стек стоит. Диагноз — одна команда sysctl vm.max_map_count; лечение — закрепить значение в конфиге, как в разделе установки. Мы теперь проверяем это тестовой перезагрузкой на каждой сдаче.

Грабля 2. Elasticsearch съедает память и роняет соседей

Симптом: раз в несколько дней Zammad «сам собой» падает или дико тормозит, в dmesg — следы OOM-киллера. Без явного лимита heap ES растёт до половины RAM, Rails-процессы тоже подрастают, и в какой-то момент ядро начинает отстреливать процессы. Лечение — явный ES_JAVA_OPTS из предыдущего раздела и честный сайзинг: если на машине 6 ГБ и меньше, а ES нужен — добавляйте память, а не надейтесь на авось.

Грабля 3. Почтовый канал: спам-папка и петли автоответов

Две беды одного канала. Первая: ответы агентов уходят, но падают клиентам в спам. Zammad тут ни при чём — у домена не настроены SPF и DKIM для сервера, через который шлёт service desk. Перед боевым запуском добавьте SMTP-источник в SPF-запись домена и включите DKIM-подпись; проверить проще всего, отправив тестовый ответ на ящик Gmail и посмотрев «показать оригинал» — обе проверки должны быть pass. Без этого сервис-деск бесполезен: клиенты не видят ответов.

Вторая беда — почтовая петля: клиентский автоответчик («я в отпуске») отвечает на автоответ Zammad, тот создаёт обновление и шлёт уведомление, автоответчик снова отвечает... За вечер такая петля способна намотать сотни писем в одном тикете. У Zammad есть встроенная защита от mail loop, но правило гигиены с нашей стороны: в триггере автоответа всегда стоит условие не отвечать на письма с признаками автогенерации, а сам автоответ шлём только на первое обращение, а не на каждое обновление тикета.

Грабля 4. Реестры образов и российские блокировки

Реальность 2026 года: docker compose pull с российского VPS может упереться в недоступность зарубежных реестров — Docker Hub периодически ограничивает доступ, провайдеры фильтруют. Решения по нарастающей: зеркала реестров у российских облаков (прописываются в registry-mirrors в /etc/docker/daemon.json), корпоративный прокси для docker daemon, в крайнем случае — docker save/docker load образов через машину с нормальной связностью. Проверьте доступность реестра до внедрения, а не в момент срочного обновления безопасности.

Грабля 5. Обновления «на удачу»

Обновление docker-стека — три команды: git pull в каталоге репозитория (обновляет compose-файлы и закреплённые версии), docker compose pull (скачивает образы), docker compose up -d (пересоздаёт контейнеры, init прогоняет миграции). Грабля не в командах, а в порядке: обновлять без свежего бэкапа и без чтения changelog — азартная игра. Наш регламент: бэкап → changelog релиза → обновление вечером, когда агенты разошлись → проверка версии и поиска. Мажорные апгрейды (смена ветки) сначала репетируем на копии.

Чек-лист сдачи в прод

Внедрение мы считаем законченным не когда «открылось в браузере», а когда инсталляция проходит наш чек-лист сдачи. Он короткий, и каждый пункт оплачен чьим-то печальным опытом.

  1. HTTPS с автопродлением. Сертификат валиден, certbot renew --dry-run проходит без ошибок. Проверено именно dry-run'ом, а не «ну сертификат же есть».
  2. Бэкап настроен и проверен восстановлением. Контейнер zammad-backup складывает дампы по расписанию, копия уходит с сервера (на соседний VPS или в S3-совместимое хранилище), и — ключевое — мы хотя бы раз развернули бэкап на тестовой машине и вошли в систему. Непроверенный бэкап — это файл, о котором вы думаете, что он вас спасёт.
  3. Мониторинг health-endpoint. В Zammad есть встроенный мониторинг (Настройки → Мониторинг) с URL вида /api/v1/monitoring/health_check?token=... — он отдаёт состояние системы, включая проблемы с почтовыми каналами и поиском. Мы цепляем его в Zabbix; подойдёт любой внешний чекер, лишь бы кто-то узнал о проблеме раньше клиента.
  4. Перезагрузочный тест. reboot сервера — и через пять минут все контейнеры снова в строю без ручных действий, включая Elasticsearch (тот самый max_map_count из sysctl.d).
  5. Отдельный админ-аккаунт с 2FA. Ежедневная работа — под учёткой агента; администраторский доступ — отдельная запись с включённой двухфакторной аутентификацией. Утечка пароля агента не должна отдавать злоумышленнику всю систему.
  6. Документашка на одну страницу. Передаём клиенту: адрес системы, где лежат бэкапы, как перезапустить стек, три команды обновления, контакты поддержки. Одна страница, которую реально прочитают, работает лучше пятидесяти, которые не откроют.

Сколько это занимает и что повторить самостоятельно

Честный хронометраж типового внедрения у нас: 3–4 часа чистого времени на стандартном VPS. Из них подготовка сервера — минут сорок, docker-стек — полчаса вместе со скачиванием образов, nginx и сертификат — двадцать минут, мастер и базовая настройка каналов — час, остальное — чек-лист и прогон тикета по кругу. Календарно с DNS, доступами от почты и согласованиями выходит день-два.

Что из этого реально повторить самостоятельно по этой статье: всё до раздела с граблями включительно, если у вас есть админ, спокойно работающий с Linux и Docker. Где чаще всего нужна помощь: почтовая обвязка (SPF/DKIM, петли), сайзинг под нестандартную нагрузку и миграция истории из старой системы — про подключение Telegram, веб-чата и Active Directory будет третья статья серии, «Zammad в бою». А если тикет-система нужна работающей к понедельнику и без экспериментов — это ровно наша работа: развернём по этому же чек-листу, сдадим с документацией и возьмём на сопровождение: Telegram @ITfresh_Boss, телефон +7 903 729-62-41.

Развернём Zammad 7.1 на вашем VPS под ключ

Поставим тикет-систему на ваш сервер и возьмём на сопровождение: docker compose, nginx с HTTPS, Elasticsearch, почтовый канал с SPF/DKIM, бэкапы и мониторинг. Прогоним по чек-листу сдачи. Свои серверы в дата-центре МТС, 15+ лет практики.

✈️ Telegram @ITfresh_Boss 📞 +7 903 729-62-41
#установка Zammad #Zammad Docker #docker compose #Elasticsearch #nginx #Let's Encrypt #service desk #регламент ITfresh
Комментарии 0

Оставить комментарий

загрузка...

Подпишитесь на рассылку ITfresh

Раз в неделю — практические гайды для руководителя IT и сисадмина: безопасность, 1С, миграции, резервные копии, лайфхаки из реальных проектов.

Реквизиты оператора персональных данных

ООО «АЙТИ-ФРЕШ», ИНН 7719418495, КПП 771901001. Юридический адрес: 105523, г. Москва, Щёлковское шоссе, д. 92, корп. 7. Контакт: info@itfresh.ru, +7 903 729-62-41. Оператор обрабатывает e-mail подписчика в целях рассылки информационных и рекламных материалов до момента отзыва согласия.