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

Нужна была нормальная система заявок: клиент пишет, видит статус, история не теряется в мессенджерах. Развернул TicketGo Support Ticket System (Laravel) на поддомене support.krivoshein.site за Nginx + PHP-FPM + MariaDB. Ниже – шаги, конфиг и грабли, на которые реально напоролся.

1. Зачем тикет-система

  • Прозрачность – клиент видит статус обращения, не нужно писать «ну как там?» каждые два часа.
  • История – переписка и вложения в одном месте, контекст не размазан по чатам.
  • Фиксация – заявка не «теряется», пока кто-то был в отпуске.
  • Лояльность – предсказуемая поддержка обычно ценится выше, чем «ответьте в мессенджере когда получится».

TicketGo на CodeCanyon – готовое Laravel-приложение с интерфейсом под заявки, роли, вложения. Свой велосипед писать не хотелось.


2. Поддомен и SSL

Поддомен support.krivoshein.site
  • Поддомен: support.krivoshein.site.
  • Сертификат Let’s Encrypt через Certbot, редирект HTTP → HTTPS.
  • Проверка: заход на http://... сразу уводит на https://....

Выпуск сертификата:

certbot --nginx -d support.krivoshein.site

Certbot сам дописывает HTTPS-редирект в конфиг Nginx. После правок:

nginx -t
systemctl reload nginx

3. Laravel-проект и Nginx

  • Код лежит в /var/www/support.krivoshein.site.
  • root веб-сервера смотрит в public – стандарт Laravel: app, config, vendor не торчат наружу.
  • PHP-FPM обрабатывает .php, статику Nginx отдаёт сам.

Рабочий vhost (схематично, пути под ваш сервер):

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;
}

Зависимости и ключ приложения:

cd /var/www/support.krivoshein.site
composer install
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=

Создание БД:

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 и поддомен

Нужно было аккуратно сцепить сертификаты Let’s Encrypt и редирект. После nginx -t и reload HTTPS стабильно открывался:

nginx -t
systemctl reload nginx

Access denied к БД

Laravel ругался на доступ: в пароле был символ #, в .env такие значения лучше брать в кавычки. Плюс DB_HOST=localhost иногда уезжает в unix-socket с неожиданным путём – для предсказуемости поставил 127.0.0.1:

DB_HOST=127.0.0.1

502 Bad Gateway

На сервере несколько пулов PHP-FPM. Nginx смотрел не на тот сокет. Указал явный путь /run/php/php8.2-fpm.sock и проверил, что сервис жив:

systemctl status php8.2-fpm
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:

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

Параллельно ловились 404: в URL одно имя файла, на диске другое. Для быстрого фикса скопировал каталог в public:

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

Аккуратнее по-laravel’овски – storage + symlink (когда будет время довести):

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 и reload Nginx:

php artisan config:clear
php artisan cache:clear
php artisan route:clear
php artisan view:clear
systemctl reload nginx

Логи на старте полезно подержать открытыми:

tail -f /var/log/nginx/support.krivoshein.site-error.log
tail -f /var/www/support.krivoshein.site/storage/logs/laravel.log

Критерий «готово»: клиент создаёт заявку, вешает файл, стили и скрипты грузятся, админка видит тикеты.


7. Итог

Рабочая тикет-система support.krivoshein.site

Сейчас тикет-система живёт на support.krivoshein.site:

  • клиенты ведут обращения в одном интерфейсе и видят прогресс;
  • все заявки собраны в админке, проще расставлять приоритеты.

В планах: довести storage для вложений «по учебнику Laravel», автодеплой и более гибкие уведомления. На текущем уровне задача закрыта – быстрая и прозрачная поддержка без хаоса в мессенджерах.

Источники и ссылки


Комментарии загружаются…