EmpireRP UCP — cPanel დეპლოის გზამკვლევი
ეს გზამკვლევი დეტალურად აღწერს, როგორ ავტვირთოთ ხელახლა აშენებული Laravel + Inertia/React UCP
(ucp-laravel/) სტანდარტულ cPanel ჰოსტინგზე — კოდის ატვირთვიდან, ბაზების შექმნიდან,
frontend-ის აწყობიდან, Discord OAuth-ის კონფიგურაციიდან, თქვენს ცოცხალ FiveM/QBCore სერვერთან
დაკავშირებამდე.
1მიმოხილვა და არქიტექტურა
აპლიკაცია იყენებს ორ ცალკე მონაცემთა ბაზის კავშირს:
| კავშირი | დანიშნულება | Env პრეფიქსი |
|---|---|---|
mysql | UCP-ის საკუთარი მონაცემები: მომხმარებლები, როლები, სიახლეები, რულეტკა, აუდიტ-ლოგები, პარამეტრები, სერვერის ტოკენები | DB_* |
fivem | თქვენი ცოცხალი FiveM სერვერის ბაზა (QBCore/Qbox/ESX სქემა) — მოთამაშეები, მანქანები, სახლები, ბანები | FIVEM_DB_* |
ეს ორივე შეიძლება იყოს იმავე MySQL სერვერზე (მაშინაც კი, ერთსა და იმავე ფიზიკურ ბაზაში), თუ მოწოდებულ დაშვებებს (credentials) აქვთ წვდომა ორივე ცხრილთა ნაკრებზე — ისინი არ საჭიროებენ ფიზიკურად ცალკე ბაზებს, მხოლოდ ლოგიკურად ცალკე Eloquent კავშირებს.
2cPanel-ის მოთხოვნები
დაწყებამდე შეამოწმეთ ეს პუნქტები cPanel-ში:
- PHP 8.3+ — cPanel → MultiPHP Manager → აირჩიეთ თქვენი დომენი → აირჩიეთ 8.3 (ან უფრო ახალი).
- PHP გაფართოებები:
pdo_mysql,mbstring,openssl,tokenizer,xml,ctype,json,bcmath,fileinfo,gd— ჩართეთ ნაკლული გაფართოებები MultiPHP INI Editor-ში ან მიმართეთ ჰოსტინგ-პროვაიდერს. - Composer — cPanel → Software → Composer (თუ ჰოსტინგზე უკვე დაყენებულია), ან SSH/Terminal წვდომა ხელით დასაყენებლად.
- Terminal / SSH წვდომა — cPanel → Advanced → Terminal. საჭიროა
artisanბრძანებების გასაშვებად. თუ ეს არ არის ხელმისაწვდომი, მიმართეთ ჰოსტინგის მხარდაჭერას SSH-ის ჩასართავად. - Node.js — cPanel → Software → Setup Node.js App (CloudLinux NodeJS Selector). გამოიყენება ერთხელ,
npm run build-ის გასაშვებად. თუ არ არის ხელმისაწვდომი, frontend ააწყვეთ თქვენს კომპიუტერზე და ატვირთეთ მხოლოდ მიღებულიpublic/buildსაქაღალდე (იხილეთ ნაბიჯი 9). - MySQL ბაზები — cPanel → MySQL Database Wizard.
3აპლიკაციის ატვირთვა
ატვირთეთ მთელი ucp-laravel/ საქაღალდე public_html-ის გარეთ —
მაგ. ~/empirerp-ucp-ში — და არა პირდაპირ public_html-ში. მხოლოდ აპლიკაციის
საკუთარმა public/ ქვესაქაღალდემ უნდა იყოს ვებ-წვდომადი (იხილეთ ნაბიჯი 7).
# თქვენს კომპიუტერზე დაარქივეთ აპლიკაცია (vendor/node_modules ჯერ არც არსებობს, ასე რომ არ სჭირდება გამორიცხვა)
cd ucp-laravel
zip -r ../ucp-laravel.zip . -x ".git/*"
# cPanel File Manager-ში: ატვირთეთ ucp-laravel.zip ~/empirerp-ucp-ში, შემდეგ Extract
ალტერნატივად გამოიყენეთ cPanel-ის Git Version Control, თუ კოდი Git რეპოზიტორიაშია, ან SFTP კლიენტი (FileZilla, WinSCP).
4მონაცემთა ბაზების შექმნა
cPanel → MySQL Database Wizard:
- შექმენით ბაზა თავად UCP-სთვის, მაგ.
cpaneluser_ucp. - შექმენით ბაზის მომხმარებელი, მაგ.
cpaneluser_ucpapp, ძლიერი, გენერირებული პაროლით. - დაამატეთ მომხმარებელი ბაზას All Privileges-ით.
- თუ თქვენი FiveM სერვერის ბაზა იმავე MySQL სერვერზეა, ჩაინიშნეთ მისი არსებული ბაზის სახელი —
სწორედ მასზე მიუთითებთ
FIVEM_DB_*-ს. თუ ის სხვა ჰოსტზეა, გაარკვიეთ FiveM ჰოსტინგ-პროვაიდერთან, შესაძლებელია თუ არა დისტანციური (remote) MySQL წვდომა, და დაუშვით (whitelist) ამ cPanel სერვერის IP მისამართი იქ.
მინიმალური პრივილეგიები: შექმენით ცალკე MySQL მომხმარებელი fivem
კავშირისთვის (მაგ. cpaneluser_fivem), წვდომით მხოლოდ თამაშის სერვერის ბაზაზე, განსხვავებული
UCP-ის საკუთარი ბაზის მომხმარებლისგან. ასე ერთი კავშირის ბაგი ან კომპრომეტაცია ვერ შეეხება მეორე
ბაზის მონაცემებს.
5PHP დამოკიდებულებების დაყენება
გახსენით cPanel Terminal (ან SSH-ით შედით):
cd ~/empirerp-ucp
composer install --no-dev --optimize-autoloader
თუ composer თქვენს PATH-ში არ არის, cPanel-ის ჩაშენებული ვერსია ჩვეულებრივ გამოიძახება
როგორც php ~/composer.phar install --no-dev --optimize-autoloader — ზუსტი ბრძანებისთვის
შეამოწმეთ Software → Composer.
6.env-ის კონფიგურაცია
cp .env.example .env
php artisan key:generate
დაარედაქტირეთ .env (File Manager-ის კოდის რედაქტორით, ან nano .env
Terminal-ში) და შეავსეთ:
| ცვლადი | მნიშვნელობა |
|---|---|
APP_URL | თქვენი რეალური დომენი, მაგ. https://ucp.ticcix.com |
APP_ENV | production |
APP_DEBUG | false — არასდროს true production-ში, რადგან ეს ავლენს stack trace-ებს |
DB_DATABASE / DB_USERNAME / DB_PASSWORD | UCP ბაზის დაშვებები მე-4 ნაბიჯიდან |
FIVEM_DB_DATABASE / FIVEM_DB_USERNAME / FIVEM_DB_PASSWORD | FiveM სერვერის ბაზის დაშვებები მე-4 ნაბიჯიდან |
FIVEM_FRAMEWORK | qbcore, qbox ან esx |
DISCORD_CLIENT_ID / DISCORD_CLIENT_SECRET | Discord Developer Portal-იდან — იხილეთ ნაბიჯი 10 |
DISCORD_BOT_TOKEN / DISCORD_GUILD_ID | როლების სინქისთვის — იხილეთ ნაბიჯი 10 |
7დომენის მიმართვა /public-ზე
Laravel-მა არასდროს არ უნდა უპასუხოს მოთხოვნებს პროექტის root-იდან — მხოლოდ
ucp-laravel/public-იდან. აირჩიეთ ერთ-ერთი მიდგომა:
ვარიანტი A — ცალკე სუბდომეინი (რეკომენდებული)
- cPanel → Domains → შექმენით სუბდომეინი, მაგ.
ucp.ticcix.com. - როცა გკითხავენ document root-ს, დააყენეთ პირდაპირ
~/empirerp-ucp/public-ზე.
ვარიანტი B — მთავარი დომენი / ქვესაქაღალდე
თუ თქვენი ჰოსტინგი არ იძლევა სუბდომეინისთვის თვითნებური document root-ის დაყენების საშუალებას,
შექმენით სიმლინკი public_html-იდან (ან მისი ქვესაქაღალდედან) აპლიკაციის public
საქაღალდეზე:
cd ~/public_html
rm -rf ucp # მხოლოდ იმ შემთხვევაში, თუ ეს ბილიკი ცარიელია/გამოუყენებელია
ln -s ~/empirerp-ucp/public ucp
თქვენი საიტი მაშინ ხელმისაწვდომი იქნება https://yourdomain.com/ucp-ზე. დააყენეთ
APP_URL .env-ში, რომ ზუსტად ემთხვეოდეს.
არასდროს ატვირთოთ ucp-laravel საქაღალდის შიგთავსი პირდაპირ
public_html-ში — ეს გამოააშკარავებდა .env-ს (თქვენი ბაზის პაროლები),
app/-ს და ყველა სხვა სერვერის მხარის ფაილს პირდაპირ HTTP-ზე.
8მიგრაციები და სიდერები
php artisan migrate --force
php artisan db:seed --force
ეს ქმნის ყველა UCP-საკუთარ ცხრილს (მომხმარებლები, როლები, სიახლეები, რულეტკა, აუდიტ-ლოგები, ბანები,
გაფრთხილებები, სერვერის სტატუსის ცხრილები და ა.შ.) და ავსებს ნაგულისხმევ როლებს/უფლებებს
(superadmin, admin, moderator, player) და საიტის
ნაგულისხმევ პარამეტრებს. ის არ ეხება თქვენი FiveM სერვერის საკუთარ ცხრილებს
(players, player_vehicles, …) — ისინი იკითხება/იწერება ადგილზე, არასდროს
მიგრირდება.
9Frontend-ის აწყობა
თუ ჰოსტინგს აქვს Node.js App ფუნქცია
# cPanel → Setup Node.js App → შექმენით აპლიკაცია, მიმართული ~/empirerp-ucp-ზე
# შემდეგ, იმ აპლიკაციის "Run NPM Install" / ტერმინალში:
npm install
npm run build
თუ ჰოსტინგს არ აქვს Node.js მხარდაჭერა
ააწყვეთ ლოკალურად და ატვირთეთ მხოლოდ კომპილირებული შედეგი:
# თქვენს კომპიუტერზე, ucp-laravel/-ის ასლში
npm install
npm run build
# ეს აწარმოებს ucp-laravel/public/build/-ს — ატვირთეთ ეს ერთი საქაღალდე
# იმავე ბილიკზე სერვერზე (public/build/).
npm run build საჭიროა ხელახლა გაშვება მხოლოდ მაშინ, როცა იცვლება frontend კოდი
(resources/js, resources/css) — არა ყოველი დეპლოის დროს.
10Discord OAuth და ბოტის კონფიგურაცია
- გადადით Discord Developer Portal-ზე და შექმენით აპლიკაცია.
- OAuth2 → General: დააკოპირეთ Client ID და Client Secret
DISCORD_CLIENT_ID/DISCORD_CLIENT_SECRET-ში. - OAuth2 → Redirects: დაამატეთ
https://ucp.ticcix.com/auth/discord/callback(უნდა ემთხვეოდეს.env-ისDISCORD_REDIRECT_URI-ს ზუსტად, სქემის ჩათვლით). - Bot ტაბი: შექმენით ბოტი, დააკოპირეთ მისი ტოკენი
DISCORD_BOT_TOKEN-ში. - დაპატიჟეთ ბოტი თქვენს Discord სერვერზე, სულ მცირე View Server Members უფლებით (საჭიროა როლების სინქისთვის, წევრის როლების წასაკითხად).
- დააკოპირეთ თქვენი Discord სერვერის ID (მარჯვენა კლიკი სერვერის აიქონზე → Copy Server ID,
Developer Mode-ის ჩართვით Discord-ში)
DISCORD_GUILD_ID-ში. - ადმინ პანელში, მისი გაშვების შემდეგ, მომავალი "Discord როლების მიბმის" ეკრანიდან (ან პირდაპირ
discord_role_mapsცხრილში ჩანაწერების დამატებით) დააკავშირეთ კონკრეტული Discord როლის ID-ებიadmin/moderatorდა ა.შ.-სთან.
11პირველი სუპერადმინის შექმნა
შედით ერთხელ Discord-ით (რომ თქვენი ანგარიშის ჩანაწერი შეიქმნას), შემდეგ დაიწინაურეთ თავად Terminal-ით:
php artisan tinker
>>> $user = App\Models\User::where('email', 'you@example.com')->first();
>>> $user->assignRole('superadmin');
>>> exit
2FA ავტომატურად ხდება სავალდებულო შემდეგივე შესვლისას superadmin/admin/moderator
ანგარიშისთვის — გადამისამართდებით მის დასაყენებლად, ნებისმიერ გვერდზე მისვლამდე.
12Cron: სქედულერი და queue
cPanel → Cron Jobs → დაამატეთ ახალი დავალება, ყოველ წუთს გასაშვები:
* * * * * cd ~/empirerp-ucp && php artisan schedule:run >> /dev/null 2>&1
ეს ატარებს საათობრივ Discord როლების ხელახალ სინქრონიზაციას (routes/console.php).
Queue worker
უმეტესი გაზიარებული (shared) cPanel ჰოსტინგი არ იძლევა ხანგრძლივად მომუშავე ფონური პროცესების
საშუალებას, ასე რომ მუდმივი php artisan queue:work დემონი ჩვეულებრივ შეუძლებელია. ორი
ვარიანტია:
| მიდგომა | როდის გამოვიყენოთ |
|---|---|
QUEUE_CONNECTION=sync .env-ში |
ყველაზე მარტივი — დავალებები (Discord როლის სინქი შესვლისას) სრულდება დაუყოვნებლივ, request-ის ფარგლებში. კარგია დაბალი/საშუალო ტრაფიკისთვის. |
| Cron-ით მართული queue დამუშავება | დაამატეთ მეორე cron ჩანაწერი: * * * * * cd ~/empirerp-ucp && php artisan queue:work --stop-when-empty >> /dev/null 2>&1.
ამუშავებს queue-ში დავალებებს ყოველ წუთს, მუდმივი პროცესის გარეშე. საჭიროებს
QUEUE_CONNECTION=database-ს (რაც უკვე ნაგულისხმევია). |
თუ თქვენი ჰოსტინგი VPS/საკუთარი cPanel ინსტალაციაა, სადაც გაქვთ root და პროცესის მენეჯერი (systemd,
Supervisor), ნამდვილი მუდმივი queue:work worker უფრო კარგი გრძელვადიანი გამოსავალია — უბრალოდ
აქ ნაგულისხმევი არ არის, რადგან უმეტესი cPanel გაზიარებული ჰოსტინგი ამას არ უჭერს მხარს.
13FiveM სერვერის და API ტოკენის რეგისტრაცია
REST API (routes/api.php) აუთენტიფიცირებს FiveM Lua რესურსებს ცალკე Sanctum ტოკენით
თითოეული სერვერისთვის — განცალკევებული ნებისმიერი მოთამაშის/ადმინის დაშბორდის შესვლისგან. შექმენით
ერთი ჯერჯერობით Tinker-ით:
php artisan tinker
>>> $server = App\Models\FiveMServer::create(['name' => 'EmpireRP Main']);
>>> $token = $server->createToken('main-server')->plainTextToken;
>>> echo $token;
>>> exit
დააკოპირეთ ეს ტოკენი ახლავე — ის მხოლოდ ერთხელ ჩანს. შეინახეთ ის, როგორც convar ან კონფიგურაციის მნიშვნელობა FiveM სერვერზე, არასდროს დააკომიტოთ საჯარო რესურსის რეპოზიტორიაში.
14FiveM/Lua ინტეგრაციის მაგალითები
მაგალითი server-side Lua კოდისა API-სთან დასაკავშირებლად (მოარგეთ URL/ტოკენის მიღება თქვენს კონვენციას):
local UCP_URL = 'https://ucp.ticcix.com/api/v1'
local UCP_TOKEN = GetConvar('ucp_api_token', '')
local function UcpRequest(method, path, body, cb)
PerformHttpRequest(UCP_URL .. path, function(status, responseText, headers)
cb(status, json.decode(responseText or '{}'))
end, method, body and json.encode(body) or '', {
['Content-Type'] = 'application/json',
['Authorization'] = 'Bearer ' .. UCP_TOKEN,
})
end
-- ბანის შემოწმება დაკავშირებისას
AddEventHandler('playerConnecting', function(name, setKickReason, deferrals)
local src = source
deferrals.defer()
local license = GetPlayerIdentifierByType(src, 'license')
UcpRequest('GET', '/players/' .. license .. '/ban-check', nil, function(status, data)
if data and data.banned then
deferrals.done(('You are banned: %s'):format(data.reason or 'No reason given'))
else
deferrals.done()
end
end)
end)
-- სერვერის heartbeat ყოველ 60 წამში
CreateThread(function()
while true do
Wait(60000)
local players = {}
for _, id in ipairs(GetPlayers()) do
table.insert(players, { source_id = tonumber(id), name = GetPlayerName(id) })
end
UcpRequest('POST', '/server/heartbeat', {
player_count = #GetPlayers(),
max_players = GetConvarInt('sv_maxclients', 48),
players = players,
}, function() end)
end
end)
15HTTPS / SSL
cPanel → SSL/TLS Status → გაუშვით AutoSSL თქვენი სუბდომეინისთვის (Let's Encrypt,
უფასო, ავტომატურად განახლებადი). გაცემის შემდეგ დარწმუნდით, რომ APP_URL იყენებს
https://-ს და SESSION_SECURE_COOKIE=true რჩება ჩართული .env-ში —
სესიის cookie-ები არ გაიგზავნება უბრალო HTTP-ზე ამის ჩართვისას, რაც განზრახულია.
16უსაფრთხოების საბოლოო ჩეკლისტი
| პუნქტი | სტატუსი |
|---|---|
APP_DEBUG=false | სავალდებულო |
.env ვებ-root-ის გარეთაა (მხოლოდ public/ შიგნითაა) | დაცულია საქაღალდის სტრუქტურით |
ცალკე MySQL მომხმარებლები mysql და fivem კავშირებისთვის | თქვენი პასუხისმგებლობა — იხილეთ ნაბიჯი 4 |
| 2FA სავალდებულოა admin/moderator/superadmin როლებისთვის | ჩაშენებულია — EnsureTwoFactorIsConfirmed middleware |
| CSRF დაცვა | Laravel-ის ნაგულისხმევი, ჩართული ყველა web როუტისთვის |
| Rate limiting login/2FA/API-ზე | ჩაშენებულია |
| პაროლები დაჰეშილია bcrypt/argon2-ით | Laravel-ის ნაგულისხმევი hasher — არასდროს MD5/plaintext |
| FiveM API ტოკენების როტაცია/გაუქმება სერვერის გათიშვისას | თქვენი პასუხისმგებლობა |
რეგულარული composer update / npm update უსაფრთხოების პაჩებისთვის | თქვენი პასუხისმგებლობა |
17ძველი PHP საიტის გამორთვა
ორიგინალი engine/, view/, public/admin/app-assets,
base.sql და root-ის index.php/.htaccess ფაილები დარჩა
ადგილზე დისკზე და არ შეცვლილა და არ წაშლილა ამ გადაწერის დროს — ისინი შეიცავდნენ
არაავტორიზებული ადმინ-ჩაწერის bypass-ს და SQL injection-ის პრობლემებს, დოკუმენტირებულს
docs/database-analysis.md-ში, ასე რომ არ დატოვოთ ისინი საჯაროდ განლაგებული ახალი
UCP-ის ამუშავების შემდეგ.
მას შემდეგ, რაც დაადასტურებთ ახალი UCP-ის მუშაობას production-ში დასაწყისიდან ბოლომდე (შესვლა, სიახლეები, რულეტკა, ადმინ პანელები, API გამოძახებები თქვენი FiveM სერვერიდან — ყველაფერი მუშაობს):
- მიმართეთ თქვენი დომენი/სუბდომეინი მთლიანად ახალ
ucp-laravel/publicსაქაღალდეზე (ნაბიჯი 7). - გააკეთეთ საბოლოო სარეზერვო ასლი ძველი საიტის ფაილებისა და მისი
base.sqlბაზის დამპისა, იმ შემთხვევისთვის, თუ დაგჭირდებათ ძველი სიახლეების/რულეტკის შემცველობის ნახვა. - წაშალეთ ძველი
engine/,view/,public/(ძველი, არა-Laravel-ის ვერსია),index.phpდა.htaccessპროექტის root-იდან. - წაშალეთ ძველი
ucp_admin,ucp_news,ucp_settings,ucp_category_roulette,ucp_item_roulette,ucp_drop_rouletteცხრილები ძველი ბაზიდან, მას შემდეგ, რაც დაადასტურებთ, რომ მათ აღარაფერი კითხულობს.
18ხშირი პრობლემები
| სიმპტომი | სავარაუდო მიზეზი |
|---|---|
| 500 შეცდომა, ცარიელი გვერდი | დროებით დააყენეთ APP_DEBUG=true და შეამოწმეთ storage/logs/laravel.log; შემდეგ დააბრუნეთ false-ზე. |
| "vendor/autoload.php not found" | composer install არ გაშვებულა, ან გაშვებულია არასწორ საქაღალდეში. |
| Assets 404 / დაუსტილებელი გვერდი | npm run build არ გაშვებულა, ან public/build არ აიტვირთა. |
| Discord შესვლა გადამისამართდება შეცდომაზე | Redirect URI არ ემთხვევა — უნდა ემთხვეოდეს Developer Portal-ის ჩანაწერს ზუსტად, https://-ის ჩათვლით. |
| "SQLSTATE[HY000] [1045] Access denied" | არასწორი ბაზის დაშვებები .env-ში, ან MySQL მომხმარებელი არ არის დამატებული იმ ბაზაზე cPanel-ში. |
| FiveM API გამოძახებები აბრუნებს 401-ს | ტოკენი არასწორად გაიცა, ან Authorization: Bearer … header არ იგზავნება Lua რესურსიდან. |