osTicket в Docker Compose: готовый файл
Когда заявки клиентов идут вперемешку по почте, в чатах и в личных сообщениях менеджеров, часть из них теряется, а история переписки по одному вопросу расползается по трём каналам сразу. osTicket закрывает эту проблему без подписки за агента и без привязки к чужому облаку: письма превращаются в тикеты с номером, статусом и историей, а команда работает в одном интерфейсе. Ниже — рабочий docker-compose.yml, разбор install-мастера и типичных грабель, которые на голом конфиге не видны.
Содержание
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →Что понадобится перед стартом
osTicket — классическое PHP-приложение с MySQL-совместимой базой, оно не требует мощного сервера, но и не работает «в один клик» из коробки — нужна отдельная база данных и, если планируется приём заявок по почте, работающий SMTP/IMAP.
Минимальные требования для команды поддержки до 10-15 агентов:
| Параметр | Значение |
|---|---|
| vCPU | 1-2 |
| RAM | 2 ГБ |
| Диск | 20 ГБ (плюс место под вложения к тикетам) |
| ОС хоста | любая с Docker Engine 24+ и Docker Compose v2 |
Заранее подготовьте:
- домен или поддомен под тикет-систему (
support.your-domain.example), направленный A-записью на IP сервера; - почтовый ящик, с которого будут приходить заявки — либо через IMAP-опрос (проще всего), либо через прямую доставку почты на сервер (сложнее, требует своего почтового стека);
- пароли для базы данных — генерируйте их заранее, не подставляйте примеры из статьи.
Если Docker на сервере ещё не стоит, порядок установки описан в статье про Docker Compose для продакшена на Ubuntu 24.04 — там же разобраны базовые практики безопасности демона, которые для системы с клиентскими данными не будут лишними.
Готовый docker-compose.yml
Структура каталогов на сервере:
/opt/osticket/
├── db-data/ # данные MariaDB
├── osticket-data/ # конфиг, вложения, кастомные темы — переживает пересоздание контейнера
├── .env
└── docker-compose.yml
Создаём каталоги и файл переменных окружения:
mkdir -p /opt/osticket/{db-data,osticket-data}
cd /opt/osticket
nano .env
Содержимое .env:
DB_ROOT_PASSWORD=замените_на_свой_root_пароль
DB_PASSWORD=замените_на_свой_пароль_приложения
TZ=Europe/Moscow
Сам docker-compose.yml:
services:
db:
image: mariadb:10.11
container_name: osticket-db
restart: unless-stopped
environment:
MYSQL_ROOT_PASSWORD: ${DB_ROOT_PASSWORD}
MYSQL_DATABASE: osticket
MYSQL_USER: osticket
MYSQL_PASSWORD: ${DB_PASSWORD}
volumes:
- ./db-data:/var/lib/mysql
networks:
- osticket-net
healthcheck:
test: ["CMD", "healthcheck.sh", "--connect", "--innodb_initialized"]
interval: 10s
timeout: 5s
retries: 6
osticket:
image: osticket/osticket:latest
container_name: osticket
restart: unless-stopped
depends_on:
db:
condition: service_healthy
environment:
TZ: ${TZ}
volumes:
- ./osticket-data:/var/www/html/upload
ports:
- "127.0.0.1:8080:80"
networks:
- osticket-net
networks:
osticket-net:
driver: bridge
Порт снова смотрит только на 127.0.0.1 — наружу отдаём через реверс-прокси с HTTPS, об этом ниже. Каталог upload внутри контейнера — это корень веб-приложения osTicket (/var/www/html/upload), в нём же после установки появится файл конфигурации include/ost-config.php, поэтому монтировать его наружу обязательно: без этого конфиг и вложения к тикетам исчезнут при пересоздании контейнера.
Поднимаем стек:
docker compose up -d
docker compose logs -f osticket
Первый старт занимает 20-40 секунд, пока контейнер ждёт готовности базы (за это отвечает healthcheck у сервиса db).
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверУстановка через веб-мастер и ловушка с ost-config.php
Открываем http://<IP-сервера>:8080/setup/install.php (или домен, если реверс-прокси уже настроен). Мастер установки задаёт вопросы по порядку:
- Информация о компании и часовой пояс — название, сайт, e-mail по умолчанию.
- Учётная запись администратора — логин, пароль, e-mail. Пароль администратора задаётся здесь, а не берётся из переменных окружения — образ не поддерживает автоматизацию установки через env-переменные, только через веб-форму.
- Настройки базы данных:
- MySQL Hostname:
db - Database Name:
osticket - User:
osticket - Password: значение из
.env - Table Prefix: можно оставить
ost_по умолчанию.
После успешной установки мастер выводит важное предупреждение: файл include/ost-config.php нужно защитить от повторной записи. Штатно это делается так:
docker exec -it osticket chmod 0644 /var/www/html/upload/include/ost-config.php
Главная ловушка в контейнерном варианте: если каталог osticket-data не примонтирован (или примонтирован не туда), при следующем docker compose up -d --force-recreate конфиг с данными о подключении к базе теряется, а установщик открывается заново — на продакшн-системе с уже заведёнными тикетами это выглядит как «сайт умер». Проверить, что монтирование сработало, можно с хоста:
ls /opt/osticket/osticket-data/include/ost-config.php
Если файл виден с хоста — конфиг переживёт пересоздание контейнера при обновлении образа.
Реверс-прокси и HTTPS
Отдавать форму логина агента и клиентские заявки по HTTP нельзя — куда сессии и пароли будут ходить открытым текстом. Проще всего закрыть это Caddy с автоматическим Let's Encrypt:
# /etc/caddy/Caddyfile
support.your-domain.example {
reverse_proxy 127.0.0.1:8080
request_body {
max_size 25MB
}
}
Лимит max_size стоит поднять сразу — по умолчанию у большинства реверс-прокси заявка с несколькими вложениями крупнее пары мегабайт будет обрезана раньше, чем дойдёт до PHP. Если Caddy на сервере ещё не настроен, разбор есть в статье про установку Caddy с авто-SSL на VPS; вариант с Traefik, если стек уже собран вокруг него, описан в статье про Traefik как реверс-прокси для Docker.
После того как домен заработал по HTTPS, зайдите в Admin Panel → Settings → System и укажите правильный Helpdesk URL — osTicket использует его для ссылок в письмах-уведомлениях клиентам, и если оставить старый адрес или http://, ссылки в письмах будут вести не туда.
Приём заявок и уведомления по почте
Без почты osTicket превращается просто в веб-форму без автоматизации — а именно приём писем как тикетов и есть основная причина ставить такую систему. Есть два независимых канала настройки:
- Email Settings → Emails — здесь заводится ящик поддержки (например,
support@your-domain.example) с указанием IMAP/POP3-сервера для входящих. osTicket сам периодически опрашивает ящик черезcron.php(см. ниже) и превращает новые письма в тикеты или ответы к существующим — по теме письма с номером тикета. - исходящая почта — либо через тот же SMTP-аккаунт, что указан для ящика поддержки, либо через отдельный SMTP-relay сервера. Если своего почтового сервера ещё нет и заводить его ради одной тикет-системы избыточно, проще подключить внешний SMTP (Yandex 360, Mailgun, SES) прямо в настройках ящика.
Если вместо внешнего SMTP на сервере уже стоит или планируется свой почтовый стек, порядок настройки описан в статье про почтовый сервер Postfix на VPS; там же разобрана частая причина, по которой письма не уходят наружу — SPF/PTR-записи и открытый 25-й порт у провайдера.
Опрос почты по расписанию критичен для работы связки — без него письма будут копиться в ящике, но не превращаться в тикеты. Добавляем задачу на хосте, которая раз в минуту дёргает cron.php внутри контейнера:
crontab -e
* * * * * docker exec osticket php /var/www/html/upload/api/cron.php >/dev/null 2>&1
Этот же cron.php отвечает и за отложенные действия: автозакрытие неактивных тикетов, эскалацию по SLA, отправку накопленных digest-уведомлений — если задача не настроена, все эти механизмы просто не срабатывают, при этом ошибок в интерфейсе не видно, и найти причину без явной проверки crontab непросто.
Кастомизация: темы, поля тикетов, отделы
osTicket из коробки закрывает базовый сценарий, но почти всегда требует пары настроек под конкретную команду:
- Отделы (Departments) —
Admin Panel → Manage → Departments. Логично завести отдельные отделы под линии поддержки (например, «Техническая», «Биллинг»), у каждого свой список агентов и своя очередь SLA. - Плана SLA (SLA Plans) — задаёт, за какое время тикет должен получить первый ответ и быть закрыт; при превышении срока тикет подсвечивается как просроченный в списке агента.
- Пользовательские поля формы —
Admin Panel → Manage → Forms, можно добавить к стандартной форме заявки поля вроде «Номер заказа» или «Версия продукта», обязательные или нет. - Темы оформления клиентского портала — по умолчанию используется default-тема; кастомную тему заливают в
/var/www/html/upload/scp/cssиclient.cssчерезdocker cpили прямо в примонтированныйosticket-data, чтобы правки не потерялись при обновлении образа.
Для небольшой команды правильно настроенные отделы и SLA дают больше практической пользы, чем визуальный редизайн: клиент видит понятный статус заявки, а агент — приоритеты без ручной сортировки.
Резервное копирование и обновление
Данные osTicket живут в двух местах: MySQL (тикеты, переписка, настройки) и каталог osticket-data (конфиг, вложения, кастомные темы). Бэкапить нужно оба.
Дамп базы вручную:
docker exec osticket-db sh -c 'exec mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" osticket' > /opt/osticket/backups/osticket-$(date +%F).sql
Восстановление:
docker exec -i osticket-db sh -c 'exec mysql -u root -p"$MYSQL_ROOT_PASSWORD" osticket' < /opt/osticket/backups/osticket-2026-08-20.sql
Каталог с вложениями и конфигом — обычным tar:
tar czf /opt/osticket/backups/osticket-data-$(date +%F).tar.gz -C /opt/osticket osticket-data
Если на сервере уже настроен регулярный бэкап других сервисов, разумнее включить оба каталога osTicket в общий пайплайн, а не поддерживать отдельный cron-скрипт под один сервис — например, через BorgBackup в Docker Compose, где бэкап дедуплицирует и шифрует данные сразу нескольких приложений.
Обновление — стандартный pull + up, но с обязательным дампом базы перед мажорной версией:
docker exec osticket-db sh -c 'exec mysqldump -u root -p"$MYSQL_ROOT_PASSWORD" osticket' > /opt/osticket/backups/pre-update-$(date +%F).sql
docker compose pull osticket
docker compose up -d osticket
После обновления зайдите в Admin Panel — если схема базы изменилась, osTicket сам предложит накатить миграцию через веб-интерфейс (Manage → Upgrade или уведомление в шапке панели); руками менять таблицы не нужно.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Можно ли использовать PostgreSQL вместо MySQL/MariaDB?
Нет, osTicket жёстко завязан на MySQL-совместимую базу (MariaDB подходит, тестировалась именно она) — переписывания слоя доступа к данным под другую СУБД проект не поддерживает.
Заявки можно принимать без почты, только через веб-форму?
Да, клиентский портал (/) содержит форму создания тикета без e-mail — почта нужна только если хотите принимать заявки, присланные напрямую письмом, минуя портал.
Как перенести osTicket с обычной установки на хостинге в Docker?
Экспортируйте дамп MySQL и скопируйте содержимое каталога upload/include (без ost-config.php, его отредактируете под новые данные подключения) и upload/attachments в примонтированный osticket-data, затем импортируйте дамп в контейнер MariaDB — сама структура базы между обычной и контейнерной установкой не отличается.
Что делать, если письма приходят, но тикеты не создаются?
В 9 случаях из 10 причина — не настроен или не срабатывает cron-опрос cron.php; проверьте crontab -l на хосте и вручную выполните команду опроса, чтобы увидеть ошибку в выводе (неверный IMAP-пароль, просроченный OAuth-токен для Gmail/Yandex и т.д.).
Нужен ли отдельный сервер под базу данных при росте команды поддержки?
Для большинства команд до сотни агентов MariaDB в соседнем контейнере на том же сервере справляется без проблем; вынос базы имеет смысл, когда тикетов накопились миллионы и диск/IO самого сервера стали узким местом.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →