Оглавление

1. Почему тикет-система важна для клиентов

Современным компаниям необходимо быстро и прозрачно обрабатывать запросы пользователей. Тикет-система (или система заявок) даёт несколько ключевых преимуществ:

  • Прозрачность – Клиенты видят статус своих обращений и могут отслеживать прогресс решения.
  • Удобная история – Все переписки и детали заявки сохраняются, что позволяет обоим сторонам быстро вспомнить контекст.
  • Гарантия ответа – Ни один вопрос не остаётся без внимания: каждая заявка фиксируется в системе.
  • Повышение лояльности – Оперативная и понятная поддержка влияет на удовлетворённость клиентов и их желание сотрудничать в дальнейшем.

С учётом этих преимуществ я решил внедрить систему тикетов и развернуть её на своём сервере. Для этого я выбрал готовое решение — TicketGo Support Ticket System, доступное на CodeCanyon. Это Laravel-приложение с удобным интерфейсом и всеми необходимыми функциями для управления заявками — решил внедрить систему тикетов и развернуть её на своём сервере.


2. Подготовка домена и SSL

Настройка системы тикетов на Laravel и Nginx
  • Зарегистрировал или перенастроил поддомен: support.krivoshein.site.
  • Установил SSL-сертификат (Let’s Encrypt) и настроил редирект с HTTP на HTTPS, чтобы соединение было безопасным и вызывало у пользователей доверие.
  • Проверил конфигурацию, чтобы при обращении к http://support.krivoshein.site пользователь сразу попадал на https://support.krivoshein.site.

Для установки SSL-сертификата я использовал Certbot:

certbot --nginx -d support.krivoshein.site

Certbot автоматически добавил редирект с HTTP на HTTPS в конфигурацию Nginx. После этого я проверил конфигурацию:

nginx -t
systemctl reload nginx

3. Разворачивание Laravel-проекта

  • Склонировал/разместил систему тикетов (Laravel-проект) в /var/www/support.krivoshein.site.
  • Указал корень веб-сервера (root) на папку public, что является рекомендуемым подходом для Laravel. Так файлы приложения (app, config, vendor и т.д.) остаются вне зоны прямого доступа.
  • Настроил PHP-FPM и Nginx, чтобы запросы к .php-файлам шли через нужный сокет PHP, а статика (CSS, JS) отдавалась напрямую.

Я настроил Nginx следующим образом:

server {
    if ($host = support.krivoshein.site) {
        return 301 https://$host$request_uri;
    }

    listen 80;
    listen [::]:80;
    server_name support.krivoshein.site;
    return 301 https://support.krivoshein.site$request_uri;
}

server {
    listen 443 ssl;
    listen [::]:443 ssl;

    server_name support.krivoshein.site;

    root /var/www/support.krivoshein.site/public;

    ssl_certificate /etc/letsencrypt/live/support.krivoshein.site/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/support.krivoshein.site/privkey.pem;
    ssl_trusted_certificate /etc/ssl/krivoshein.site/ca-bundle.crt;

    index index.php index.html index.htm;
    charset utf-8;

    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        include snippets/fastcgi-php.conf;
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
    }

    location ~ /\.ht {
        deny all;
    }

    location ~* \.(css|js|png|jpg|jpeg|gif|ico|woff|woff2|ttf|svg)$ {
        expires max;
        log_not_found off;
        access_log off;
    }

    location ~* ^/public/(css|assets|market_assets|images|landing|uploads|storage|installer|js|vendor)/(.*)$ {
        rewrite ^/public/(.*)$ /public/$1 break;
    }

    location ~ /\.(?!well-known).* {
        deny all;
    }

    error_log /var/log/nginx/support.krivoshein.site-error.log;
    access_log /var/log/nginx/support.krivoshein.site-access.log;
}

После настройки я установил зависимости Laravel:

cd /var/www/support.krivoshein.site
composer install

И скопировал файл .env:

cp .env.example .env
php artisan key:generate

4. Настройка базы данных

  • Создал базу данных и пользователя в MariaDB (учётные данные прописаны в .env без публичных символов и паролей).
  • Запустил миграции командой php artisan migrate, проверил, что все таблицы для тикетов создались корректно.

Пример настройки .env (без паролей):

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel_db
DB_USERNAME=laravel_user
DB_PASSWORD=

Создание базы данных в MariaDB:

CREATE DATABASE laravel_db;
CREATE USER 'laravel_user'@'localhost' IDENTIFIED BY 'your_secure_password';
GRANT ALL PRIVILEGES ON laravel_db.* TO 'laravel_user'@'localhost';
FLUSH PRIVILEGES;

Запуск миграций:

php artisan migrate

5. Основные проблемы, с которыми столкнулся

Сложности с SSL и поддоменом

Пришлось разобраться, как корректно подключить сертификаты и выполнить редирект на HTTPS. После проверки nginx -t и перезагрузки всё заработало:

nginx -t
systemctl reload nginx

Проблемы с доступом к базе

Laravel сначала выдавал «Access denied»: мешали спецсимволы # в пароле, которые нужно было заключить в кавычки в .env. Также сменил DB_HOST=localhost на 127.0.0.1, чтобы исключить непредвиденные ошибки с сокетами.

Обновлённый .env:

DB_HOST=127.0.0.1

502 Bad Gateway

Оказалось, что у меня несколько пулов PHP-FPM; Nginx не находил верный сокет. После того как я точно указал путь (например, /run/php/php8.2-fpm.sock) и проверил, что PHP-FPM действительно слушает этот сокет, всё заработало:

systemctl status php8.2-fpm

Обновил конфигурацию Nginx:

location ~ \.php$ {
    include snippets/fastcgi-php.conf;
    fastcgi_pass unix:/run/php/php8.2-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    include fastcgi_params;
}

Проблемы с папкой uploads

Система тикетов позволяет клиентам прикреплять файлы к заявкам. Изначально я поместил папку uploads вне public, что потребовало дополнительного alias в Nginx:

location /uploads/ {
    alias /var/www/support.krivoshein.site/uploads/;
    expires max;
    log_not_found off;
    access_log off;
}

Некоторое время имена файлов не совпадали: сайт пытался запросить, скажем, logo_1234.png, а фактически загружался logo_5678.png. В итоге временно скопировал папку uploads в public, чтобы гарантированно избавиться от 404:

cp -r /var/www/support.krivoshein.site/uploads /var/www/support.krivoshein.site/public/

Когда появится время, планирую перенести файлы в storage/app/public и настроить php artisan storage:link:

mv /var/www/support.krivoshein.site/public/uploads /var/www/support.krivoshein.site/storage/app/public/
php artisan storage:link

Несоответствие имён файлов

Основная причина 404 — в неверном окончании названий. Нужно было внимательно сверять, как система (или админка) генерирует пути к загружаемым файлам и как они называются на диске. Я проверил содержимое директории:

ls -l /var/www/support.krivoshein.site/uploads/logo

И обновил пути в базе данных:

UPDATE settings SET value = 'uploads/logo/logo-dark.png' WHERE name = 'dark_logo';
UPDATE settings SET value = 'uploads/logo/logo-light.png' WHERE name = 'light_logo';
UPDATE settings SET value = 'uploads/logo/favicon.png' WHERE name = 'favicon';

6. Финальная проверка и запуск

Настройка системы тикетов на Laravel и Nginx
  • Очистил кэши Laravel (config, cache, route, view) и перезапустил Nginx:
php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
systemctl reload nginx
  • Проверил логи в /var/log/nginx/error.log и в storage/logs/laravel.log, чтобы убедиться в отсутствии новых ошибок:
tail -f /var/log/nginx/support.krivoshein.site-error.log
tail -f /var/www/support.krivoshein.site/storage/logs/laravel.log
  • Убедился, что система тикетов доступна: клиенты могут создавать заявки, прикреплять файлы, и все стили/скрипты подгружаются корректно.

7. Итог

Настройка системы тикетов на Laravel и Nginx

Теперь у меня работает полноценная тикет-система на поддомене support.krivoshein.site. Благодаря такой организации:

  • Клиенты оперативно получают ответы и могут отслеживать статус своих заявок, что повышает их доверие и лояльность.
  • Я вижу все заявки в едином интерфейсе, облегчающем контроль и приоритетность задач.

В перспективе хочу усовершенствовать хранение файлов (перенести в storage/app/public), а также настроить автодеплой и более гибкую систему уведомлений. Но уже сейчас тикеты отлично выполняют свою задачу: быстрая и прозрачная коммуникация с клиентами.