Платформа для айдолов и их фанатов. Laravel 12 + Inertia.js v2 + Vue 3.
- Backend: Laravel 12, PostgreSQL
- Frontend: Inertia.js v2, Vue 3 (Composition API), Vite
- Auth: два гарда —
web(пользователи) иadmin(администраторы)
- PHP 8.4+ с расширениями:
bcmath,pgsql,gd,exif - PostgreSQL
- Node.js + npm
- Composer
Установка расширений на Fedora/RHEL:
sudo dnf install php-bcmath php-pgsql php-gd php-exif sudo systemctl restart php-fpm
cp .env.example .env
composer install
npm install
php artisan key:generate
php artisan migrate
php artisan db:seed --class=AdminSeeder
php artisan storage:link
# Создать симлинк для публичного хранилища (картинки категорий, аватары и т.д.)
php artisan storage:linkВ .env значения REVERB_APP_ID, REVERB_APP_KEY, REVERB_APP_SECRET — произвольные строки, главное чтобы они были заполнены:
REVERB_APP_ID=no-alone
REVERB_APP_KEY=no-alone-key
REVERB_APP_SECRET=no-alone-secret
REVERB_HOST="localhost"
REVERB_PORT=8080
REVERB_SCHEME=httpПроект использует barryvdh/laravel-ide-helper для улучшения автодополнения в IDE (PhpStorm, VS Code, Zed и др.).
Генерация хелперов:
# Хелпер для фасадов Laravel (создаёт _ide_helper.php)
php artisan ide-helper:generate
# Хелпер для моделей — добавляет PHPDoc с полями и связями (создаёт _ide_helper_models.php)
php artisan ide-helper:models -N
# Мета-файл для PhpStorm (создаёт .phpstorm.meta.php)
php artisan ide-helper:metaФайлы
_ide_helper.php,_ide_helper_models.phpи.phpstorm.meta.phpдобавлены в.gitignore— каждый разработчик генерирует их локально.
Когда перегенерировать:
ide-helper:models— после изменения миграций или добавления связей в моделяхide-helper:generate— после обновления Laravel или добавления новых фасадов
Для работы реалтайм-уведомлений нужно запускать три процесса одновременно (в разных терминалах):
# 1. Laravel dev-сервер
php artisan serve
# 2. Vite (фронтенд + HMR)
npm run dev
# 3. Reverb WebSocket-сервер (реалтайм-уведомления)
php artisan reverb:startБез
reverb:startколокольчик уведомлений работать не будет (страница не получит push от сервера).
Примечание: WebSocket-события (
NewNotification) используютShouldBroadcastNowи отправляются в Reverb напрямую, минуя очередь. Если в будущем переключить наShouldBroadcast— нужно будет также запускатьphp artisan queue:work.
Сидер создаёт одного администратора:
php artisan db:seed --class=AdminSeeder| Поле | Значение |
|---|---|
| admin@noalone.test | |
| Пароль | password |
Панель доступна по адресу /admin.
php artisan user:makeКоманда спросит тип и создаст пользователя с рандомными данными:
Кого создать?:
[0] Обычный пользователь
[1] Айдол
[2] Админ
Что создаётся:
- Русскоязычные имя + фамилия (Faker
ru_RU) - Пароль
123123 - Email сразу подтверждён (
email_verified_atзаполнен) - Случайный пол и дата рождения (18–40 лет)
- Для айдола:
is_idol = true, рейтинг 50, запись вidol_applications(статусapproved) - Для админа: запись в таблице
admins, вход через/admin/login
php artisan users:generate {count}Пример — создать 100 пользователей:
php artisan users:generate 100Что создаётся:
- Русскоязычные имена (Faker
ru_RU) - Пароль
123123для всех - Случайный пол (
male/female/ без пола) - Случайная дата рождения, возраст 18–50 лет
- ~40% пользователей становятся айдолами (
is_idol = true+ запись вidol_applicationsсо статусомapproved)
Создаёт тестовые услуги во всех активных категориях для указанного пользователя. Перед созданием показывает имя и email пользователя и запрашивает подтверждение.
php artisan services:seed 1app/
Http/Controllers/
Admin/ — контроллеры админ-панели
Idol/ — контроллеры idol flow
Models/
Console/Commands/
MakeUser.php — интерактивное создание одного пользователя/айдола/админа
GenerateUsers.php — массовая генерация тестовых пользователей
SeedUserServices.php — наполнение профиля айдола тестовыми услугами
resources/js/
Pages/
Admin/ — страницы админ-панели
Idol/ — страницы idol flow
Profile/ — профиль пользователя
Layouts/
AppLayout.vue — шапка для авторизованных страниц
AdminLayout.vue — шапка для админ-панели
routes/
web.php
admin.php
- Деплой: Kamal 2 (Docker-образ → VPS по SSH)
- Веб-сервер: nginx + php-fpm в одном контейнере (supervisord)
- Прокси / SSL: kamal-proxy (встроен в Kamal, Let's Encrypt)
- БД: PostgreSQL 17 как Kamal accessory (контейнер на том же VPS)
- Очередь / сессии / кеш: database-драйвер (Redis не нужен на старте)
- WebSocket: Reverb в отдельном контейнере
- Docker Registry: GitHub Container Registry (
ghcr.io/yar101/no-alone)
Для корректной работы загрузки и сжатия изображений (аватары до 5МБ, посты до 10МБ), на сервере должны быть установлены следующие лимиты:
post_max_size = 100M
upload_max_filesize = 100M
max_file_uploads = 100После изменения настроек необходимо перезапустить PHP-FPM или Apache.
Фото контент-паков хранятся на приватном диске (storage/app/private), прямой URL недоступен.
Схема: Laravel выдаёт подписанный URL (TTL 30 мин) → MediaController проверяет подпись + покупку → отдаёт заголовок X-Accel-Redirect → nginx стримит файл напрямую с диска.
Nginx location: location /private-media/ { internal; alias /var/www/html/storage/app/private/; }
Один Dockerfile, роли разделены через CONTAINER_ROLE:
| Роль | Что запускает |
|---|---|
web |
migrate + config:cache + supervisord (nginx + php-fpm) |
worker |
php artisan queue:work |
scheduler |
php artisan schedule:work |
reverb |
php artisan reverb:start |
Конфиги: docker/nginx-prod.conf, docker/php-fpm-prod.conf, docker/supervisord.conf, docker/entrypoint.sh
Требования:
- VPS Ubuntu 24.04, SSH-ключ добавлен при создании
- Домен направлен A-записью на IP VPS
- GitHub Personal Access Token с
write:packages→KAMAL_REGISTRY_PASSWORD - Установлен Kamal:
gem install kamal
Заполнить в .env.production (файл локальный, не в git):
APP_URL=https://домен
DB_PASSWORD=... # совпадает с POSTGRES_PASSWORD
POSTGRES_PASSWORD=...
KAMAL_REGISTRY_PASSWORD=ghp_...
MAIL_HOST=...
MAIL_USERNAME=...
MAIL_PASSWORD=...
Команды:
DEPLOY_HOST=1.2.3.4 APP_DOMAIN=домен kamal setup # установить Docker на VPS, поднять postgres
kamal env push # залить секреты на VPS
DEPLOY_HOST=1.2.3.4 APP_DOMAIN=домен kamal deploy # собрать образ, задеплоитьПоследующие деплои:
DEPLOY_HOST=1.2.3.4 APP_DOMAIN=домен kamal deployПриватные файлы живут на VPS в /var/www/no-alone/storage (смонтировано в контейнер). При деплое не пересоздаются — данные сохраняются между деплоями.
БД живёт в /var/www/no-alone/postgres.
Бэкапы этих двух директорий = полный бэкап данных.
kamal rollback # откат на предыдущий образ
kamal app logs # логи web-контейнера
kamal app logs -r worker # логи worker